CODE
* attribute won't be visited. This can be used, for example, to retrieve
@@ -133,6 +108,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 not 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. The content of this array must not be
* modified. This field is intended for {@link Attribute} sub classes, and
@@ -195,8 +185,8 @@ 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_9) {
- throw new IllegalArgumentException();
+ if (readShort(off + 6) > Opcodes.V10) {
+ //throw new IllegalArgumentException();
}
// parses the constant pool
items = new int[readUnsignedShort(off + 8)];
@@ -234,6 +224,8 @@ public class ClassReader {
// case ClassWriter.CLASS:
// case ClassWriter.STR:
// case ClassWriter.MTYPE
+ // case ClassWriter.PACKAGE:
+ // case ClassWriter.MODULE:
default:
size = 3;
break;
@@ -377,7 +369,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;
@@ -584,11 +578,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();
@@ -607,13 +604,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;
@@ -623,12 +618,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++) {
@@ -657,6 +656,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,
@@ -664,19 +669,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,
@@ -684,7 +689,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,
@@ -726,6 +731,120 @@ public class ClassReader {
classVisitor.visitEnd();
}
+ /**
+ * 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.
*
@@ -762,24 +881,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,
@@ -801,19 +916,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,
@@ -821,7 +936,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,
@@ -895,32 +1010,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;
@@ -953,7 +1062,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;
@@ -990,26 +1099,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,
@@ -1017,7 +1126,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,
@@ -1025,10 +1134,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);
}
@@ -1075,7 +1184,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;
@@ -1085,11 +1194,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:
@@ -1104,9 +1218,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;
@@ -1115,9 +1229,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;
@@ -1147,9 +1261,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;
@@ -1180,13 +1294,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;
}
}
@@ -1196,9 +1306,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) {
@@ -1210,17 +1318,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);
@@ -1244,7 +1350,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;
@@ -1273,7 +1379,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
@@ -1306,14 +1412,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;
@@ -1334,7 +1457,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.
@@ -1346,6 +1469,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);
@@ -1354,6 +1480,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;
@@ -1378,9 +1511,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
+ //
- * This method must be called after all the method that is being built
- * has been visited. In particular, the {@link Label Label} objects used
- * to construct the method are no longer valid after this method has been
- * called.
- */
- private void resizeInstructions() {
- byte[] b = code.data; // bytecode of the method
- int u, v, label; // indexes in b
- int i, j; // loop indexes
- /*
- * 1st step: As explained above, resizing an instruction may require to
- * resize another one, which may require to resize yet another one, and
- * so on. The first step of the algorithm consists in finding all the
- * instructions that need to be resized, without modifying the code.
- * This is done by the following "fix point" algorithm:
- *
- * Parse the code to find the jump instructions whose offset will need
- * more than 2 bytes to be stored (the future offset is computed from
- * the current offset and from the number of bytes that will be inserted
- * or removed between the source and target instructions). For each such
- * instruction, adds an entry in (a copy of) the indexes and sizes
- * arrays (if this has not already been done in a previous iteration!).
- *
- * If at least one entry has been added during the previous step, go
- * back to the beginning, otherwise stop.
- *
- * In fact the real algorithm is complicated by the fact that the size
- * of TABLESWITCH and LOOKUPSWITCH instructions depends on their
- * position in the bytecode (because of padding). In order to ensure the
- * convergence of the algorithm, the number of bytes to be added or
- * removed from these instructions is over estimated during the previous
- * loop, and computed exactly only after the loop is finished (this
- * requires another pass to parse the bytecode of the method).
- */
- int[] allIndexes = new int[0]; // copy of indexes
- int[] allSizes = new int[0]; // copy of sizes
- boolean[] resize; // instructions to be resized
- int newOffset; // future offset of a jump instruction
-
- resize = new boolean[code.length];
-
- // 3 = loop again, 2 = loop ended, 1 = last pass, 0 = done
- int state = 3;
- do {
- if (state == 3) {
- state = 2;
- }
- u = 0;
- while (u < b.length) {
- int opcode = b[u] & 0xFF; // opcode of current instruction
- int insert = 0; // bytes to be added after this instruction
-
- switch (ClassWriter.TYPE[opcode]) {
- case ClassWriter.NOARG_INSN:
- case ClassWriter.IMPLVAR_INSN:
- u += 1;
- break;
- case ClassWriter.LABEL_INSN:
- if (opcode > 201) {
- // converts temporary opcodes 202 to 217, 218 and
- // 219 to IFEQ ... JSR (inclusive), IFNULL and
- // IFNONNULL
- opcode = opcode < 218 ? opcode - 49 : opcode - 20;
- label = u + readUnsignedShort(b, u + 1);
- } else {
- label = u + readShort(b, u + 1);
- }
- newOffset = getNewOffset(allIndexes, allSizes, u, label);
- if (newOffset < Short.MIN_VALUE
- || newOffset > Short.MAX_VALUE) {
- if (!resize[u]) {
- if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
- // two additional bytes will be required to
- // replace this GOTO or JSR instruction with
- // a GOTO_W or a JSR_W
- insert = 2;
- } else {
- // five additional bytes will be required to
- // replace this IFxxx
- * Note: it is possible to have several entries for the same instruction in
- * the indexes and sizes: two entries (index=a,size=b) and
- * (index=a,size=b') are equivalent to a single entry (index=a,size=b+b').
- *
- * @param indexes
- * current positions of the instructions to be resized. Each
- * instruction must be designated by the index of its last
- * byte, plus one (or, in other words, by the index of the
- * first byte of the next instruction).
- * @param sizes
- * the number of bytes to be added to the above
- * instructions. More precisely, for each i < len,
- * sizes[i] bytes will be added at the end of the
- * instruction designated by indexes[i] or, if
- * sizes[i] is negative, the last |
- * sizes[i]| bytes of the instruction will be removed
- * (the instruction size must not become negative or
- * null).
- * @param begin
- * index of the first byte of the source instruction.
- * @param end
- * index of the first byte of the target instruction.
- * @return the future value of the given bytecode offset.
- */
- static int getNewOffset(final int[] indexes, final int[] sizes,
- final int begin, final int end) {
- int offset = end - begin;
- for (int i = 0; i < indexes.length; ++i) {
- if (begin < indexes[i] && indexes[i] <= end) {
- // forward jump
- offset += sizes[i];
- } else if (end < indexes[i] && indexes[i] <= begin) {
- // backward jump
- offset -= sizes[i];
- }
- }
- return offset;
- }
-
- /**
- * Updates the offset of the given label.
- *
- * @param indexes
- * current positions of the instructions to be resized. Each
- * instruction must be designated by the index of its last
- * byte, plus one (or, in other words, by the index of the
- * first byte of the next instruction).
- * @param sizes
- * the number of bytes to be added to the above
- * instructions. More precisely, for each i < len,
- * sizes[i] bytes will be added at the end of the
- * instruction designated by indexes[i] or, if
- * sizes[i] is negative, the last |
- * sizes[i]| bytes of the instruction will be removed
- * (the instruction size must not become negative or
- * null).
- * @param label
- * the label whose offset must be updated.
- */
- static void getNewOffset(final int[] indexes, final int[] sizes,
- final Label label) {
- if ((label.status & Label.RESIZED) == 0) {
- label.position = getNewOffset(indexes, sizes, 0, label.position);
- label.status |= Label.RESIZED;
- }
- }
}
diff --git a/src/org/redkale/asm/ModuleVisitor.java b/src/org/redkale/asm/ModuleVisitor.java
new file mode 100644
index 000000000..cef97f2aa
--- /dev/null
+++ b/src/org/redkale/asm/ModuleVisitor.java
@@ -0,0 +1,219 @@
+/*
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+/*
+ *
+ *
+ *
+ *
+ *
+ * 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.redkale.asm;
+
+/**
+ * A visitor to visit a Java module. The methods of this class must be called in
+ * the following order: visitMainClass | ( visitPackage |
+ * visitRequire | visitExport | visitOpen |
+ * visitUse | visitProvide )* visitEnd.
+ *
+ * The methods {@link #visitRequire(String, int, String)}, {@link #visitExport(String, int, String...)},
+ * {@link #visitOpen(String, int, String...)} and {@link #visitPackage(String)}
+ * take as parameter a package name or a module name. Unlike the other names which are internal names
+ * (names separated by slash), module and package names are qualified names (names separated by dot).
+ *
+ * @author Remi Forax
+ */
+public abstract class ModuleVisitor {
+ /**
+ * The ASM API version implemented by this visitor. The value of this field
+ * must be {@link Opcodes#ASM6}.
+ */
+ protected final int api;
+
+ /**
+ * The module visitor to which this visitor must delegate method calls. May
+ * be null.
+ */
+ protected ModuleVisitor mv;
+
+ /**
+ * Constructs a new {@link ModuleVisitor}.
+ *
+ * @param api
+ * the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
+ */
+ public ModuleVisitor(final int api) {
+ this(api, null);
+ }
+
+ /**
+ * Constructs a new {@link ModuleVisitor}.
+ *
+ * @param api
+ * the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
+ * @param mv
+ * the module visitor to which this visitor must delegate method
+ * calls. May be null.
+ */
+ public ModuleVisitor(final int api, final ModuleVisitor mv) {
+ if (api != Opcodes.ASM6) {
+ throw new IllegalArgumentException();
+ }
+ this.api = api;
+ this.mv = mv;
+ }
+
+ /**
+ * Visit the main class of the current module.
+ *
+ * @param mainClass the internal name of the main class of the current module.
+ */
+ public void visitMainClass(String mainClass) {
+ if (mv != null) {
+ mv.visitMainClass(mainClass);
+ }
+ }
+
+ /**
+ * Visit a package of the current module.
+ *
+ * @param packaze the qualified name of a package.
+ */
+ public void visitPackage(String packaze) {
+ if (mv != null) {
+ mv.visitPackage(packaze);
+ }
+ }
+
+ /**
+ * Visits a dependence of the current module.
+ *
+ * @param module the qualified name of the dependence.
+ * @param access the access flag of the dependence among
+ * ACC_TRANSITIVE, ACC_STATIC_PHASE, ACC_SYNTHETIC
+ * and ACC_MANDATED.
+ * @param version the module version at compile time or null.
+ */
+ public void visitRequire(String module, int access, String version) {
+ if (mv != null) {
+ mv.visitRequire(module, access, version);
+ }
+ }
+
+ /**
+ * Visit an exported package of the current module.
+ *
+ * @param packaze the qualified name of the exported package.
+ * @param access the access flag of the exported package,
+ * valid values are among {@code ACC_SYNTHETIC} and
+ * {@code ACC_MANDATED}.
+ * @param modules the qualified names of the modules that can access to
+ * the public classes of the exported package or
+ * null.
+ */
+ public void visitExport(String packaze, int access, String... modules) {
+ if (mv != null) {
+ mv.visitExport(packaze, access, modules);
+ }
+ }
+
+ /**
+ * Visit an open package of the current module.
+ *
+ * @param packaze the qualified name of the opened package.
+ * @param access the access flag of the opened package,
+ * valid values are among {@code ACC_SYNTHETIC} and
+ * {@code ACC_MANDATED}.
+ * @param modules the qualified names of the modules that can use deep
+ * reflection to the classes of the open package or
+ * null.
+ */
+ public void visitOpen(String packaze, int access, String... modules) {
+ if (mv != null) {
+ mv.visitOpen(packaze, access, modules);
+ }
+ }
+
+ /**
+ * Visit a service used by the current module.
+ * The name must be the internal name of an interface or a class.
+ *
+ * @param service the internal name of the service.
+ */
+ public void visitUse(String service) {
+ if (mv != null) {
+ mv.visitUse(service);
+ }
+ }
+
+ /**
+ * Visit an implementation of a service.
+ *
+ * @param service the internal name of the service
+ * @param providers the internal names of the implementations
+ * of the service (there is at least one provider).
+ */
+ public void visitProvide(String service, String... providers) {
+ if (mv != null) {
+ mv.visitProvide(service, providers);
+ }
+ }
+
+ /**
+ * Visits the end of the module. This method, which is the last one to be
+ * called, is used to inform the visitor that everything have been visited.
+ */
+ public void visitEnd() {
+ if (mv != null) {
+ mv.visitEnd();
+ }
+ }
+}
diff --git a/src/org/redkale/asm/ModuleWriter.java b/src/org/redkale/asm/ModuleWriter.java
new file mode 100644
index 000000000..57277cd94
--- /dev/null
+++ b/src/org/redkale/asm/ModuleWriter.java
@@ -0,0 +1,322 @@
+/*
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+/*
+ *
+ *
+ *
+ *
+ *
+ * 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.redkale.asm;
+
+/**
+ * @author Remi Forax
+ */
+final class ModuleWriter extends ModuleVisitor {
+ /**
+ * The class writer to which this Module attribute must be added.
+ */
+ private final ClassWriter cw;
+
+ /**
+ * size in byte of the Module attribute.
+ */
+ int size;
+
+ /**
+ * Number of attributes associated with the current module
+ * (Version, ConcealPackages, etc)
+ */
+ int attributeCount;
+
+ /**
+ * Size in bytes of the attributes associated with the current module
+ */
+ int attributesSize;
+
+ /**
+ * module name index in the constant pool
+ */
+ private final int name;
+
+ /**
+ * module access flags
+ */
+ private final int access;
+
+ /**
+ * module version index in the constant pool or 0
+ */
+ private final int version;
+
+ /**
+ * module main class index in the constant pool or 0
+ */
+ private int mainClass;
+
+ /**
+ * number of packages
+ */
+ private int packageCount;
+
+ /**
+ * The packages in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in packageCount
+ */
+ private ByteVector packages;
+
+ /**
+ * number of requires items
+ */
+ private int requireCount;
+
+ /**
+ * The requires items in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in requireCount
+ */
+ private ByteVector requires;
+
+ /**
+ * number of exports items
+ */
+ private int exportCount;
+
+ /**
+ * The exports items in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in exportCount
+ */
+ private ByteVector exports;
+
+ /**
+ * number of opens items
+ */
+ private int openCount;
+
+ /**
+ * The opens items in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in openCount
+ */
+ private ByteVector opens;
+
+ /**
+ * number of uses items
+ */
+ private int useCount;
+
+ /**
+ * The uses items in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in useCount
+ */
+ private ByteVector uses;
+
+ /**
+ * number of provides items
+ */
+ private int provideCount;
+
+ /**
+ * The uses provides in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in provideCount
+ */
+ private ByteVector provides;
+
+ ModuleWriter(final ClassWriter cw, final int name,
+ final int access, final int version) {
+ super(Opcodes.ASM6);
+ this.cw = cw;
+ this.size = 16; // name + access + version + 5 counts
+ this.name = name;
+ this.access = access;
+ this.version = version;
+ }
+
+ @Override
+ public void visitMainClass(String mainClass) {
+ if (this.mainClass == 0) { // protect against several calls to visitMainClass
+ cw.newUTF8("ModuleMainClass");
+ attributeCount++;
+ attributesSize += 8;
+ }
+ this.mainClass = cw.newClass(mainClass);
+ }
+
+ @Override
+ public void visitPackage(String packaze) {
+ if (packages == null) {
+ // protect against several calls to visitPackage
+ cw.newUTF8("ModulePackages");
+ packages = new ByteVector();
+ attributeCount++;
+ attributesSize += 8;
+ }
+ packages.putShort(cw.newPackage(packaze));
+ packageCount++;
+ attributesSize += 2;
+ }
+
+ @Override
+ public void visitRequire(String module, int access, String version) {
+ if (requires == null) {
+ requires = new ByteVector();
+ }
+ requires.putShort(cw.newModule(module))
+ .putShort(access)
+ .putShort(version == null? 0: cw.newUTF8(version));
+ requireCount++;
+ size += 6;
+ }
+
+ @Override
+ public void visitExport(String packaze, int access, String... modules) {
+ if (exports == null) {
+ exports = new ByteVector();
+ }
+ exports.putShort(cw.newPackage(packaze)).putShort(access);
+ if (modules == null) {
+ exports.putShort(0);
+ size += 6;
+ } else {
+ exports.putShort(modules.length);
+ for(String module: modules) {
+ exports.putShort(cw.newModule(module));
+ }
+ size += 6 + 2 * modules.length;
+ }
+ exportCount++;
+ }
+
+ @Override
+ public void visitOpen(String packaze, int access, String... modules) {
+ if (opens == null) {
+ opens = new ByteVector();
+ }
+ opens.putShort(cw.newPackage(packaze)).putShort(access);
+ if (modules == null) {
+ opens.putShort(0);
+ size += 6;
+ } else {
+ opens.putShort(modules.length);
+ for(String module: modules) {
+ opens.putShort(cw.newModule(module));
+ }
+ size += 6 + 2 * modules.length;
+ }
+ openCount++;
+ }
+
+ @Override
+ public void visitUse(String service) {
+ if (uses == null) {
+ uses = new ByteVector();
+ }
+ uses.putShort(cw.newClass(service));
+ useCount++;
+ size += 2;
+ }
+
+ @Override
+ public void visitProvide(String service, String... providers) {
+ if (provides == null) {
+ provides = new ByteVector();
+ }
+ provides.putShort(cw.newClass(service));
+ provides.putShort(providers.length);
+ for(String provider: providers) {
+ provides.putShort(cw.newClass(provider));
+ }
+ provideCount++;
+ size += 4 + 2 * providers.length;
+ }
+
+ @Override
+ public void visitEnd() {
+ // empty
+ }
+
+ void putAttributes(ByteVector out) {
+ if (mainClass != 0) {
+ out.putShort(cw.newUTF8("ModuleMainClass")).putInt(2).putShort(mainClass);
+ }
+ if (packages != null) {
+ out.putShort(cw.newUTF8("ModulePackages"))
+ .putInt(2 + 2 * packageCount)
+ .putShort(packageCount)
+ .putByteArray(packages.data, 0, packages.length);
+ }
+ }
+
+ void put(ByteVector out) {
+ out.putInt(size);
+ out.putShort(name).putShort(access).putShort(version);
+ out.putShort(requireCount);
+ if (requires != null) {
+ out.putByteArray(requires.data, 0, requires.length);
+ }
+ out.putShort(exportCount);
+ if (exports != null) {
+ out.putByteArray(exports.data, 0, exports.length);
+ }
+ out.putShort(openCount);
+ if (opens != null) {
+ out.putByteArray(opens.data, 0, opens.length);
+ }
+ out.putShort(useCount);
+ if (uses != null) {
+ out.putByteArray(uses.data, 0, uses.length);
+ }
+ out.putShort(provideCount);
+ if (provides != null) {
+ out.putByteArray(provides.data, 0, provides.length);
+ }
+ }
+}
diff --git a/src/org/redkale/asm/Opcodes.java b/src/org/redkale/asm/Opcodes.java
index 3ffbad8b6..ccb07f345 100644
--- a/src/org/redkale/asm/Opcodes.java
+++ b/src/org/redkale/asm/Opcodes.java
@@ -1,4 +1,33 @@
/*
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+/*
+ *
+ *
+ *
+ *
+ *
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
@@ -41,13 +70,13 @@ package org.redkale.asm;
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
-@SuppressWarnings("deprecation") // for Integer(int) constructor
public interface Opcodes {
// ASM API versions
int ASM4 = 4 << 16 | 0 << 8 | 0;
int ASM5 = 5 << 16 | 0 << 8 | 0;
+ int ASM6 = 6 << 16 | 0 << 8 | 0;
// versions
@@ -59,7 +88,8 @@ public interface Opcodes {
int V1_6 = 0 << 16 | 50;
int V1_7 = 0 << 16 | 51;
int V1_8 = 0 << 16 | 52;
- int V1_9 = 0 << 16 | 53;
+ int V9 = 0 << 16 | 53;
+ int V10 = 0 << 16 | 54;
// access flags
@@ -70,18 +100,23 @@ public interface Opcodes {
int ACC_FINAL = 0x0010; // class, field, method, parameter
int ACC_SUPER = 0x0020; // class
int ACC_SYNCHRONIZED = 0x0020; // method
+ int ACC_OPEN = 0x0020; // module
+ int ACC_TRANSITIVE = 0x0020; // module requires
int ACC_VOLATILE = 0x0040; // field
int ACC_BRIDGE = 0x0040; // method
+ int ACC_STATIC_PHASE = 0x0040; // module requires
int ACC_VARARGS = 0x0080; // method
int ACC_TRANSIENT = 0x0080; // field
int ACC_NATIVE = 0x0100; // method
int ACC_INTERFACE = 0x0200; // class
int ACC_ABSTRACT = 0x0400; // class, method
int ACC_STRICT = 0x0800; // method
- int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter
+ int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter, module *
int ACC_ANNOTATION = 0x2000; // class
int ACC_ENUM = 0x4000; // class(?) field inner
- int ACC_MANDATED = 0x8000; // parameter
+ int ACC_MANDATED = 0x8000; // parameter, module, module *
+ int ACC_MODULE = 0x8000; // class
+
// ASM specific pseudo access flags
@@ -148,15 +183,17 @@ public interface Opcodes {
*/
int F_SAME1 = 4;
- // For reference comparison purposes, construct new instances
- // instead of using valueOf() or autoboxing.
- Integer TOP = new Integer(0);
- Integer INTEGER = new Integer(1);
- Integer FLOAT = new Integer(2);
- Integer DOUBLE = new Integer(3);
- Integer LONG = new Integer(4);
- Integer NULL = new Integer(5);
- Integer UNINITIALIZED_THIS = new Integer(6);
+ // Do not try to change the following code to use auto-boxing,
+ // these values are compared by reference and not by value
+ // The constructor of Integer was deprecated in 9
+ // but we are stuck with it by backward compatibility
+ @SuppressWarnings("deprecation") Integer TOP = new Integer(0);
+ @SuppressWarnings("deprecation") Integer INTEGER = new Integer(1);
+ @SuppressWarnings("deprecation") Integer FLOAT = new Integer(2);
+ @SuppressWarnings("deprecation") Integer DOUBLE = new Integer(3);
+ @SuppressWarnings("deprecation") Integer LONG = new Integer(4);
+ @SuppressWarnings("deprecation") Integer NULL = new Integer(5);
+ @SuppressWarnings("deprecation") Integer UNINITIALIZED_THIS = new Integer(6);
// opcodes // visit method (- = idem)
diff --git a/src/org/redkale/asm/Type.java b/src/org/redkale/asm/Type.java
index 00710efc0..cc644bb5c 100644
--- a/src/org/redkale/asm/Type.java
+++ b/src/org/redkale/asm/Type.java
@@ -406,7 +406,16 @@ public class Type {
*/
public static Type getReturnType(final String methodDescriptor) {
char[] buf = methodDescriptor.toCharArray();
- return getType(buf, methodDescriptor.indexOf(')') + 1);
+ int off = 1;
+ while (true) {
+ char car = buf[off++];
+ if (car == ')') {
+ return getType(buf, off);
+ } else if (car == 'L') {
+ while (buf[off++] != ';') {
+ }
+ }
+ }
}
/**
diff --git a/src/org/redkale/asm/TypeReference.java b/src/org/redkale/asm/TypeReference.java
index 83bcfadb4..38579e7b5 100644
--- a/src/org/redkale/asm/TypeReference.java
+++ b/src/org/redkale/asm/TypeReference.java
@@ -1,427 +1,481 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.redkale.asm;
-
-/**
- * A reference to a type appearing in a class, field or method declaration, or
- * on an instruction. Such a reference designates the part of the class where
- * the referenced type is appearing (e.g. an 'extends', 'implements' or 'throws'
- * clause, a 'new' instruction, a 'catch' clause, a type cast, a local variable
- * declaration, etc).
- *
- * @author Eric Bruneton
- */
-public class TypeReference {
-
- /**
- * The sort of type references that target a type parameter of a generic
- * class. See {@link #getSort getSort}.
- */
- public final static int CLASS_TYPE_PARAMETER = 0x00;
-
- /**
- * The sort of type references that target a type parameter of a generic
- * method. See {@link #getSort getSort}.
- */
- public final static int METHOD_TYPE_PARAMETER = 0x01;
-
- /**
- * The sort of type references that target the super class of a class or one
- * of the interfaces it implements. See {@link #getSort getSort}.
- */
- public final static int CLASS_EXTENDS = 0x10;
-
- /**
- * The sort of type references that target a bound of a type parameter of a
- * generic class. See {@link #getSort getSort}.
- */
- public final static int CLASS_TYPE_PARAMETER_BOUND = 0x11;
-
- /**
- * The sort of type references that target a bound of a type parameter of a
- * generic method. See {@link #getSort getSort}.
- */
- public final static int METHOD_TYPE_PARAMETER_BOUND = 0x12;
-
- /**
- * The sort of type references that target the type of a field. See
- * {@link #getSort getSort}.
- */
- public final static int FIELD = 0x13;
-
- /**
- * The sort of type references that target the return type of a method. See
- * {@link #getSort getSort}.
- */
- public final static int METHOD_RETURN = 0x14;
-
- /**
- * The sort of type references that target the receiver type of a method.
- * See {@link #getSort getSort}.
- */
- public final static int METHOD_RECEIVER = 0x15;
-
- /**
- * The sort of type references that target the type of a formal parameter of
- * a method. See {@link #getSort getSort}.
- */
- public final static int METHOD_FORMAL_PARAMETER = 0x16;
-
- /**
- * The sort of type references that target the type of an exception declared
- * in the throws clause of a method. See {@link #getSort getSort}.
- */
- public final static int THROWS = 0x17;
-
- /**
- * The sort of type references that target the type of a local variable in a
- * method. See {@link #getSort getSort}.
- */
- public final static int LOCAL_VARIABLE = 0x40;
-
- /**
- * The sort of type references that target the type of a resource variable
- * in a method. See {@link #getSort getSort}.
- */
- public final static int RESOURCE_VARIABLE = 0x41;
-
- /**
- * The sort of type references that target the type of the exception of a
- * 'catch' clause in a method. See {@link #getSort getSort}.
- */
- public final static int EXCEPTION_PARAMETER = 0x42;
-
- /**
- * The sort of type references that target the type declared in an
- * 'instanceof' instruction. See {@link #getSort getSort}.
- */
- public final static int INSTANCEOF = 0x43;
-
- /**
- * The sort of type references that target the type of the object created by
- * a 'new' instruction. See {@link #getSort getSort}.
- */
- public final static int NEW = 0x44;
-
- /**
- * The sort of type references that target the receiver type of a
- * constructor reference. See {@link #getSort getSort}.
- */
- public final static int CONSTRUCTOR_REFERENCE = 0x45;
-
- /**
- * The sort of type references that target the receiver type of a method
- * reference. See {@link #getSort getSort}.
- */
- public final static int METHOD_REFERENCE = 0x46;
-
- /**
- * The sort of type references that target the type declared in an explicit
- * or implicit cast instruction. See {@link #getSort getSort}.
- */
- public final static int CAST = 0x47;
-
- /**
- * The sort of type references that target a type parameter of a generic
- * constructor in a constructor call. See {@link #getSort getSort}.
- */
- public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
-
- /**
- * The sort of type references that target a type parameter of a generic
- * method in a method call. See {@link #getSort getSort}.
- */
- public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
-
- /**
- * The sort of type references that target a type parameter of a generic
- * constructor in a constructor reference. See {@link #getSort getSort}.
- */
- public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
-
- /**
- * The sort of type references that target a type parameter of a generic
- * method in a method reference. See {@link #getSort getSort}.
- */
- public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
-
- /**
- * The type reference value in Java class file format.
- */
- private int value;
-
- /**
- * Creates a new TypeReference.
- *
- * @param typeRef
- * the int encoded value of the type reference, as received in a
- * visit method related to type annotations, like
- * visitTypeAnnotation.
- */
- public TypeReference(int typeRef) {
- this.value = typeRef;
- }
-
- /**
- * Returns a type reference of the given sort.
- *
- * @param sort
- * {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN},
- * {@link #METHOD_RECEIVER METHOD_RECEIVER},
- * {@link #LOCAL_VARIABLE LOCAL_VARIABLE},
- * {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE},
- * {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW},
- * {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, or
- * {@link #METHOD_REFERENCE METHOD_REFERENCE}.
- * @return a type reference of the given sort.
- */
- public static TypeReference newTypeReference(int sort) {
- return new TypeReference(sort << 24);
- }
-
- /**
- * Returns a reference to a type parameter of a generic class or method.
- *
- * @param sort
- * {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or
- * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}.
- * @param paramIndex
- * the type parameter index.
- * @return a reference to the given generic class or method type parameter.
- */
- public static TypeReference newTypeParameterReference(int sort,
- int paramIndex) {
- return new TypeReference((sort << 24) | (paramIndex << 16));
- }
-
- /**
- * Returns a reference to a type parameter bound of a generic class or
- * method.
- *
- * @param sort
- * {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or
- * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}.
- * @param paramIndex
- * the type parameter index.
- * @param boundIndex
- * the type bound index within the above type parameters.
- * @return a reference to the given generic class or method type parameter
- * bound.
- */
- public static TypeReference newTypeParameterBoundReference(int sort,
- int paramIndex, int boundIndex) {
- return new TypeReference((sort << 24) | (paramIndex << 16)
- | (boundIndex << 8));
- }
-
- /**
- * Returns a reference to the super class or to an interface of the
- * 'implements' clause of a class.
- *
- * @param itfIndex
- * the index of an interface in the 'implements' clause of a
- * class, or -1 to reference the super class of the class.
- * @return a reference to the given super type of a class.
- */
- public static TypeReference newSuperTypeReference(int itfIndex) {
- itfIndex &= 0xFFFF;
- return new TypeReference((CLASS_EXTENDS << 24) | (itfIndex << 8));
- }
-
- /**
- * Returns a reference to the type of a formal parameter of a method.
- *
- * @param paramIndex
- * the formal parameter index.
- *
- * @return a reference to the type of the given method formal parameter.
- */
- public static TypeReference newFormalParameterReference(int paramIndex) {
- return new TypeReference((METHOD_FORMAL_PARAMETER << 24)
- | (paramIndex << 16));
- }
-
- /**
- * Returns a reference to the type of an exception, in a 'throws' clause of
- * a method.
- *
- * @param exceptionIndex
- * the index of an exception in a 'throws' clause of a method.
- *
- * @return a reference to the type of the given exception.
- */
- public static TypeReference newExceptionReference(int exceptionIndex) {
- return new TypeReference((THROWS << 24) | (exceptionIndex << 8));
- }
-
- /**
- * Returns a reference to the type of the exception declared in a 'catch'
- * clause of a method.
- *
- * @param tryCatchBlockIndex
- * the index of a try catch block (using the order in which they
- * are visited with visitTryCatchBlock).
- *
- * @return a reference to the type of the given exception.
- */
- public static TypeReference newTryCatchReference(int tryCatchBlockIndex) {
- return new TypeReference((EXCEPTION_PARAMETER << 24)
- | (tryCatchBlockIndex << 8));
- }
-
- /**
- * Returns a reference to the type of a type argument in a constructor or
- * method call or reference.
- *
- * @param sort
- * {@link #CAST CAST},
- * {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
- * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
- * {@link #METHOD_INVOCATION_TYPE_ARGUMENT
- * METHOD_INVOCATION_TYPE_ARGUMENT},
- * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
- * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
- * {@link #METHOD_REFERENCE_TYPE_ARGUMENT
- * METHOD_REFERENCE_TYPE_ARGUMENT}.
- * @param argIndex
- * the type argument index.
- *
- * @return a reference to the type of the given type argument.
- */
- public static TypeReference newTypeArgumentReference(int sort, int argIndex) {
- return new TypeReference((sort << 24) | argIndex);
- }
-
- /**
- * Returns the sort of this type reference.
- *
- * @return {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER},
- * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER},
- * {@link #CLASS_EXTENDS CLASS_EXTENDS},
- * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND},
- * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND},
- * {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN},
- * {@link #METHOD_RECEIVER METHOD_RECEIVER},
- * {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER},
- * {@link #THROWS THROWS}, {@link #LOCAL_VARIABLE LOCAL_VARIABLE},
- * {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE},
- * {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER},
- * {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW},
- * {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE},
- * {@link #METHOD_REFERENCE METHOD_REFERENCE}, {@link #CAST CAST},
- * {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
- * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
- * {@link #METHOD_INVOCATION_TYPE_ARGUMENT
- * METHOD_INVOCATION_TYPE_ARGUMENT},
- * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
- * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
- * {@link #METHOD_REFERENCE_TYPE_ARGUMENT
- * METHOD_REFERENCE_TYPE_ARGUMENT}.
- */
- public int getSort() {
- return value >>> 24;
- }
-
- /**
- * Returns the index of the type parameter referenced by this type
- * reference. This method must only be used for type references whose sort
- * is {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER},
- * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER},
- * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
- * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}.
- *
- * @return a type parameter index.
- */
- public int getTypeParameterIndex() {
- return (value & 0x00FF0000) >> 16;
- }
-
- /**
- * Returns the index of the type parameter bound, within the type parameter
- * {@link #getTypeParameterIndex}, referenced by this type reference. This
- * method must only be used for type references whose sort is
- * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
- * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}.
- *
- * @return a type parameter bound index.
- */
- public int getTypeParameterBoundIndex() {
- return (value & 0x0000FF00) >> 8;
- }
-
- /**
- * Returns the index of the "super type" of a class that is referenced by
- * this type reference. This method must only be used for type references
- * whose sort is {@link #CLASS_EXTENDS CLASS_EXTENDS}.
- *
- * @return the index of an interface in the 'implements' clause of a class,
- * or -1 if this type reference references the type of the super
- * class.
- */
- public int getSuperTypeIndex() {
- return (short) ((value & 0x00FFFF00) >> 8);
- }
-
- /**
- * Returns the index of the formal parameter whose type is referenced by
- * this type reference. This method must only be used for type references
- * whose sort is {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER}.
- *
- * @return a formal parameter index.
- */
- public int getFormalParameterIndex() {
- return (value & 0x00FF0000) >> 16;
- }
-
- /**
- * Returns the index of the exception, in a 'throws' clause of a method,
- * whose type is referenced by this type reference. This method must only be
- * used for type references whose sort is {@link #THROWS THROWS}.
- *
- * @return the index of an exception in the 'throws' clause of a method.
- */
- public int getExceptionIndex() {
- return (value & 0x00FFFF00) >> 8;
- }
-
- /**
- * Returns the index of the try catch block (using the order in which they
- * are visited with visitTryCatchBlock), whose 'catch' type is referenced by
- * this type reference. This method must only be used for type references
- * whose sort is {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER} .
- *
- * @return the index of an exception in the 'throws' clause of a method.
- */
- public int getTryCatchBlockIndex() {
- return (value & 0x00FFFF00) >> 8;
- }
-
- /**
- * Returns the index of the type argument referenced by this type reference.
- * This method must only be used for type references whose sort is
- * {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
- * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
- * {@link #METHOD_INVOCATION_TYPE_ARGUMENT METHOD_INVOCATION_TYPE_ARGUMENT},
- * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
- * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
- * {@link #METHOD_REFERENCE_TYPE_ARGUMENT METHOD_REFERENCE_TYPE_ARGUMENT}.
- *
- * @return a type parameter index.
- */
- public int getTypeArgumentIndex() {
- return value & 0xFF;
- }
-
- /**
- * Returns the int encoded value of this type reference, suitable for use in
- * visit methods related to type annotations, like visitTypeAnnotation.
- *
- * @return the int encoded value of this type reference.
- */
- public int getValue() {
- return value;
- }
-}
+/*
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+/*
+ *
+ *
+ *
+ *
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2013 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.redkale.asm;
+
+/**
+ * A reference to a type appearing in a class, field or method declaration, or
+ * on an instruction. Such a reference designates the part of the class where
+ * the referenced type is appearing (e.g. an 'extends', 'implements' or 'throws'
+ * clause, a 'new' instruction, a 'catch' clause, a type cast, a local variable
+ * declaration, etc).
+ *
+ * @author Eric Bruneton
+ */
+public class TypeReference {
+
+ /**
+ * The sort of type references that target a type parameter of a generic
+ * class. See {@link #getSort getSort}.
+ */
+ public final static int CLASS_TYPE_PARAMETER = 0x00;
+
+ /**
+ * The sort of type references that target a type parameter of a generic
+ * method. See {@link #getSort getSort}.
+ */
+ public final static int METHOD_TYPE_PARAMETER = 0x01;
+
+ /**
+ * The sort of type references that target the super class of a class or one
+ * of the interfaces it implements. See {@link #getSort getSort}.
+ */
+ public final static int CLASS_EXTENDS = 0x10;
+
+ /**
+ * The sort of type references that target a bound of a type parameter of a
+ * generic class. See {@link #getSort getSort}.
+ */
+ public final static int CLASS_TYPE_PARAMETER_BOUND = 0x11;
+
+ /**
+ * The sort of type references that target a bound of a type parameter of a
+ * generic method. See {@link #getSort getSort}.
+ */
+ public final static int METHOD_TYPE_PARAMETER_BOUND = 0x12;
+
+ /**
+ * The sort of type references that target the type of a field. See
+ * {@link #getSort getSort}.
+ */
+ public final static int FIELD = 0x13;
+
+ /**
+ * The sort of type references that target the return type of a method. See
+ * {@link #getSort getSort}.
+ */
+ public final static int METHOD_RETURN = 0x14;
+
+ /**
+ * The sort of type references that target the receiver type of a method.
+ * See {@link #getSort getSort}.
+ */
+ public final static int METHOD_RECEIVER = 0x15;
+
+ /**
+ * The sort of type references that target the type of a formal parameter of
+ * a method. See {@link #getSort getSort}.
+ */
+ public final static int METHOD_FORMAL_PARAMETER = 0x16;
+
+ /**
+ * The sort of type references that target the type of an exception declared
+ * in the throws clause of a method. See {@link #getSort getSort}.
+ */
+ public final static int THROWS = 0x17;
+
+ /**
+ * The sort of type references that target the type of a local variable in a
+ * method. See {@link #getSort getSort}.
+ */
+ public final static int LOCAL_VARIABLE = 0x40;
+
+ /**
+ * The sort of type references that target the type of a resource variable
+ * in a method. See {@link #getSort getSort}.
+ */
+ public final static int RESOURCE_VARIABLE = 0x41;
+
+ /**
+ * The sort of type references that target the type of the exception of a
+ * 'catch' clause in a method. See {@link #getSort getSort}.
+ */
+ public final static int EXCEPTION_PARAMETER = 0x42;
+
+ /**
+ * The sort of type references that target the type declared in an
+ * 'instanceof' instruction. See {@link #getSort getSort}.
+ */
+ public final static int INSTANCEOF = 0x43;
+
+ /**
+ * The sort of type references that target the type of the object created by
+ * a 'new' instruction. See {@link #getSort getSort}.
+ */
+ public final static int NEW = 0x44;
+
+ /**
+ * The sort of type references that target the receiver type of a
+ * constructor reference. See {@link #getSort getSort}.
+ */
+ public final static int CONSTRUCTOR_REFERENCE = 0x45;
+
+ /**
+ * The sort of type references that target the receiver type of a method
+ * reference. See {@link #getSort getSort}.
+ */
+ public final static int METHOD_REFERENCE = 0x46;
+
+ /**
+ * The sort of type references that target the type declared in an explicit
+ * or implicit cast instruction. See {@link #getSort getSort}.
+ */
+ public final static int CAST = 0x47;
+
+ /**
+ * The sort of type references that target a type parameter of a generic
+ * constructor in a constructor call. See {@link #getSort getSort}.
+ */
+ public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
+
+ /**
+ * The sort of type references that target a type parameter of a generic
+ * method in a method call. See {@link #getSort getSort}.
+ */
+ public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
+
+ /**
+ * The sort of type references that target a type parameter of a generic
+ * constructor in a constructor reference. See {@link #getSort getSort}.
+ */
+ public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
+
+ /**
+ * The sort of type references that target a type parameter of a generic
+ * method in a method reference. See {@link #getSort getSort}.
+ */
+ public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
+
+ /**
+ * The type reference value in Java class file format.
+ */
+ private int value;
+
+ /**
+ * Creates a new TypeReference.
+ *
+ * @param typeRef
+ * the int encoded value of the type reference, as received in a
+ * visit method related to type annotations, like
+ * visitTypeAnnotation.
+ */
+ public TypeReference(int typeRef) {
+ this.value = typeRef;
+ }
+
+ /**
+ * Returns a type reference of the given sort.
+ *
+ * @param sort
+ * {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN},
+ * {@link #METHOD_RECEIVER METHOD_RECEIVER},
+ * {@link #LOCAL_VARIABLE LOCAL_VARIABLE},
+ * {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE},
+ * {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW},
+ * {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, or
+ * {@link #METHOD_REFERENCE METHOD_REFERENCE}.
+ * @return a type reference of the given sort.
+ */
+ public static TypeReference newTypeReference(int sort) {
+ return new TypeReference(sort << 24);
+ }
+
+ /**
+ * Returns a reference to a type parameter of a generic class or method.
+ *
+ * @param sort
+ * {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or
+ * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}.
+ * @param paramIndex
+ * the type parameter index.
+ * @return a reference to the given generic class or method type parameter.
+ */
+ public static TypeReference newTypeParameterReference(int sort,
+ int paramIndex) {
+ return new TypeReference((sort << 24) | (paramIndex << 16));
+ }
+
+ /**
+ * Returns a reference to a type parameter bound of a generic class or
+ * method.
+ *
+ * @param sort
+ * {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or
+ * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}.
+ * @param paramIndex
+ * the type parameter index.
+ * @param boundIndex
+ * the type bound index within the above type parameters.
+ * @return a reference to the given generic class or method type parameter
+ * bound.
+ */
+ public static TypeReference newTypeParameterBoundReference(int sort,
+ int paramIndex, int boundIndex) {
+ return new TypeReference((sort << 24) | (paramIndex << 16)
+ | (boundIndex << 8));
+ }
+
+ /**
+ * Returns a reference to the super class or to an interface of the
+ * 'implements' clause of a class.
+ *
+ * @param itfIndex
+ * the index of an interface in the 'implements' clause of a
+ * class, or -1 to reference the super class of the class.
+ * @return a reference to the given super type of a class.
+ */
+ public static TypeReference newSuperTypeReference(int itfIndex) {
+ itfIndex &= 0xFFFF;
+ return new TypeReference((CLASS_EXTENDS << 24) | (itfIndex << 8));
+ }
+
+ /**
+ * Returns a reference to the type of a formal parameter of a method.
+ *
+ * @param paramIndex
+ * the formal parameter index.
+ *
+ * @return a reference to the type of the given method formal parameter.
+ */
+ public static TypeReference newFormalParameterReference(int paramIndex) {
+ return new TypeReference((METHOD_FORMAL_PARAMETER << 24)
+ | (paramIndex << 16));
+ }
+
+ /**
+ * Returns a reference to the type of an exception, in a 'throws' clause of
+ * a method.
+ *
+ * @param exceptionIndex
+ * the index of an exception in a 'throws' clause of a method.
+ *
+ * @return a reference to the type of the given exception.
+ */
+ public static TypeReference newExceptionReference(int exceptionIndex) {
+ return new TypeReference((THROWS << 24) | (exceptionIndex << 8));
+ }
+
+ /**
+ * Returns a reference to the type of the exception declared in a 'catch'
+ * clause of a method.
+ *
+ * @param tryCatchBlockIndex
+ * the index of a try catch block (using the order in which they
+ * are visited with visitTryCatchBlock).
+ *
+ * @return a reference to the type of the given exception.
+ */
+ public static TypeReference newTryCatchReference(int tryCatchBlockIndex) {
+ return new TypeReference((EXCEPTION_PARAMETER << 24)
+ | (tryCatchBlockIndex << 8));
+ }
+
+ /**
+ * Returns a reference to the type of a type argument in a constructor or
+ * method call or reference.
+ *
+ * @param sort
+ * {@link #CAST CAST},
+ * {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+ * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
+ * {@link #METHOD_INVOCATION_TYPE_ARGUMENT
+ * METHOD_INVOCATION_TYPE_ARGUMENT},
+ * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+ * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
+ * {@link #METHOD_REFERENCE_TYPE_ARGUMENT
+ * METHOD_REFERENCE_TYPE_ARGUMENT}.
+ * @param argIndex
+ * the type argument index.
+ *
+ * @return a reference to the type of the given type argument.
+ */
+ public static TypeReference newTypeArgumentReference(int sort, int argIndex) {
+ return new TypeReference((sort << 24) | argIndex);
+ }
+
+ /**
+ * Returns the sort of this type reference.
+ *
+ * @return {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER},
+ * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER},
+ * {@link #CLASS_EXTENDS CLASS_EXTENDS},
+ * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND},
+ * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND},
+ * {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN},
+ * {@link #METHOD_RECEIVER METHOD_RECEIVER},
+ * {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER},
+ * {@link #THROWS THROWS}, {@link #LOCAL_VARIABLE LOCAL_VARIABLE},
+ * {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE},
+ * {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER},
+ * {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW},
+ * {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE},
+ * {@link #METHOD_REFERENCE METHOD_REFERENCE}, {@link #CAST CAST},
+ * {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+ * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
+ * {@link #METHOD_INVOCATION_TYPE_ARGUMENT
+ * METHOD_INVOCATION_TYPE_ARGUMENT},
+ * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+ * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
+ * {@link #METHOD_REFERENCE_TYPE_ARGUMENT
+ * METHOD_REFERENCE_TYPE_ARGUMENT}.
+ */
+ public int getSort() {
+ return value >>> 24;
+ }
+
+ /**
+ * Returns the index of the type parameter referenced by this type
+ * reference. This method must only be used for type references whose sort
+ * is {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER},
+ * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER},
+ * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
+ * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}.
+ *
+ * @return a type parameter index.
+ */
+ public int getTypeParameterIndex() {
+ return (value & 0x00FF0000) >> 16;
+ }
+
+ /**
+ * Returns the index of the type parameter bound, within the type parameter
+ * {@link #getTypeParameterIndex}, referenced by this type reference. This
+ * method must only be used for type references whose sort is
+ * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
+ * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}.
+ *
+ * @return a type parameter bound index.
+ */
+ public int getTypeParameterBoundIndex() {
+ return (value & 0x0000FF00) >> 8;
+ }
+
+ /**
+ * Returns the index of the "super type" of a class that is referenced by
+ * this type reference. This method must only be used for type references
+ * whose sort is {@link #CLASS_EXTENDS CLASS_EXTENDS}.
+ *
+ * @return the index of an interface in the 'implements' clause of a class,
+ * or -1 if this type reference references the type of the super
+ * class.
+ */
+ public int getSuperTypeIndex() {
+ return (short) ((value & 0x00FFFF00) >> 8);
+ }
+
+ /**
+ * Returns the index of the formal parameter whose type is referenced by
+ * this type reference. This method must only be used for type references
+ * whose sort is {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER}.
+ *
+ * @return a formal parameter index.
+ */
+ public int getFormalParameterIndex() {
+ return (value & 0x00FF0000) >> 16;
+ }
+
+ /**
+ * Returns the index of the exception, in a 'throws' clause of a method,
+ * whose type is referenced by this type reference. This method must only be
+ * used for type references whose sort is {@link #THROWS THROWS}.
+ *
+ * @return the index of an exception in the 'throws' clause of a method.
+ */
+ public int getExceptionIndex() {
+ return (value & 0x00FFFF00) >> 8;
+ }
+
+ /**
+ * Returns the index of the try catch block (using the order in which they
+ * are visited with visitTryCatchBlock), whose 'catch' type is referenced by
+ * this type reference. This method must only be used for type references
+ * whose sort is {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER} .
+ *
+ * @return the index of an exception in the 'throws' clause of a method.
+ */
+ public int getTryCatchBlockIndex() {
+ return (value & 0x00FFFF00) >> 8;
+ }
+
+ /**
+ * Returns the index of the type argument referenced by this type reference.
+ * This method must only be used for type references whose sort is
+ * {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+ * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
+ * {@link #METHOD_INVOCATION_TYPE_ARGUMENT METHOD_INVOCATION_TYPE_ARGUMENT},
+ * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+ * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
+ * {@link #METHOD_REFERENCE_TYPE_ARGUMENT METHOD_REFERENCE_TYPE_ARGUMENT}.
+ *
+ * @return a type parameter index.
+ */
+ public int getTypeArgumentIndex() {
+ return value & 0xFF;
+ }
+
+ /**
+ * Returns the int encoded value of this type reference, suitable for use in
+ * visit methods related to type annotations, like visitTypeAnnotation.
+ *
+ * @return the int encoded value of this type reference.
+ */
+ public int getValue() {
+ return value;
+ }
+}
diff --git a/test/org/redkale/test/asm/AsmCreator.java b/test/org/redkale/test/asm/AsmCreator.java
index 3a507c62c..c7bcad7b9 100644
--- a/test/org/redkale/test/asm/AsmCreator.java
+++ b/test/org/redkale/test/asm/AsmCreator.java
@@ -16,8 +16,8 @@ public class AsmCreator {
public static void main(String[] args) throws Throwable {
boolean realasm = false; //从http://forge.ow2.org/projects/asm/ 下载最新asm的src放在 srcasmroot 目录下
- File srcasmroot = new File("D:/JAVA/JDK源码/JDK9源码/java.base/jdk/internal/org/objectweb/asm");
- if(realasm) srcasmroot = new File("D:/JAVA/JDK源码/org/objectweb/asm");
+ File srcasmroot = new File("D:/JAVA/JDK源码/jdk/internal/org/objectweb/asm");
+ if (realasm) srcasmroot = new File("D:/JAVA/JDK源码/org/objectweb/asm");
File destasmroot = new File("D:/Java-Projects/RedkaleProject/src/org/redkale/asm");
String line = null;
LineNumberReader txtin = new LineNumberReader(new FileReader(new File(destasmroot, "asm.txt")));
@@ -32,5 +32,6 @@ public class AsmCreator {
out.write(content.replace("jdk.internal.org.objectweb", "org.redkale").replace("org.objectweb", "org.redkale").getBytes());
out.close();
}
+ //需要屏蔽ClassReader中判断checks the class version的部分
}
}