Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.zving.framework.thirdparty.asm.ClassReader Maven / Gradle / Ivy
package com.zving.framework.thirdparty.asm;
import java.io.IOException;
import java.io.InputStream;
import com.zving.preloader.Util;
// fix
public class ClassReader {
public ClassReader(byte b[]) {
this(b, 0, b.length);
}
public ClassReader(byte b[], int off, int len) {
this.b = b;
if (readShort(off + 6) > 51)
throw new IllegalArgumentException();
items = new int[readUnsignedShort(off + 8)];
int n = items.length;
strings = new String[n];
int max = 0;
int index = off + 10;
for (int i = 1; i < n; i++) {
items[i] = index + 1;
int size;
switch (b[index]) {
case 3: // '\003'
case 4: // '\004'
case 9: // '\t'
case 10: // '\n'
case 11: // '\013'
case 12: // '\f'
case 18: // '\022'
size = 5;
break;
case 5: // '\005'
case 6: // '\006'
size = 9;
i++;
break;
case 1: // '\001'
size = 3 + readUnsignedShort(index + 1);
if (size > max)
max = size;
break;
case 15: // '\017'
size = 4;
break;
case 2: // '\002'
case 7: // '\007'
case 8: // '\b'
case 13: // '\r'
case 14: // '\016'
case 16: // '\020'
case 17: // '\021'
default:
size = 3;
break;
}
index += size;
}
maxStringLength = max;
header = index;
}
public int getAccess() {
return readUnsignedShort(header);
}
public String getClassName() {
return readClass(header + 2, new char[maxStringLength]);
}
public String getSuperName() {
return readClass(header + 4, new char[maxStringLength]);
}
public String[] getInterfaces() {
int index = header + 6;
int n = readUnsignedShort(index);
String interfaces[] = new String[n];
if (n > 0) {
char buf[] = new char[maxStringLength];
for (int i = 0; i < n; i++) {
index += 2;
interfaces[i] = readClass(index, buf);
}
}
return interfaces;
}
void copyPool(ClassWriter classWriter) {
char buf[] = new char[maxStringLength];
int ll = items.length;
Item items2[] = new Item[ll];
for (int i = 1; i < ll; i++) {
int index = items[i];
int tag = b[index - 1];
Item item = new Item(i);
switch (tag) {
case 9: // '\t'
case 10: // '\n'
case 11: // '\013'
{
int nameType = items[readUnsignedShort(index + 2)];
item.set(tag, readClass(index, buf), readUTF8(nameType, buf), readUTF8(nameType + 2, buf));
break;
}
case 3: // '\003'
{
item.set(readInt(index));
break;
}
case 4: // '\004'
{
item.set(Float.intBitsToFloat(readInt(index)));
break;
}
case 12: // '\f'
{
item.set(tag, readUTF8(index, buf), readUTF8(index + 2, buf), null);
break;
}
case 5: // '\005'
{
item.set(readLong(index));
i++;
break;
}
case 6: // '\006'
{
item.set(Double.longBitsToDouble(readLong(index)));
i++;
break;
}
case 1: // '\001'
{
String s = strings[i];
if (s == null) {
index = items[i];
s = strings[i] = readUTF(index + 2, readUnsignedShort(index), buf);
}
item.set(tag, s, null, null);
break;
}
case 15: // '\017'
{
int fieldOrMethodRef = items[readUnsignedShort(index + 1)];
int nameType = items[readUnsignedShort(fieldOrMethodRef + 2)];
item.set(20 + readByte(index), readClass(fieldOrMethodRef, buf), readUTF8(nameType, buf), readUTF8(nameType + 2, buf));
break;
}
case 18: // '\022'
{
if (classWriter.bootstrapMethods == null)
copyBootstrapMethods(classWriter, items2, buf);
int nameType = items[readUnsignedShort(index + 2)];
item.set(readUTF8(nameType, buf), readUTF8(nameType + 2, buf), readUnsignedShort(index));
break;
}
case 2: // '\002'
case 7: // '\007'
case 8: // '\b'
case 13: // '\r'
case 14: // '\016'
case 16: // '\020'
case 17: // '\021'
default: {
item.set(tag, readUTF8(index, buf), null, null);
break;
}
}
int index2 = item.hashCode % items2.length;
item.next = items2[index2];
items2[index2] = item;
}
int off = items[1] - 1;
classWriter.pool.putByteArray(b, off, header - off);
classWriter.items = items2;
classWriter.threshold = (int) (0.75D * (double) ll);
classWriter.index = ll;
}
private void copyBootstrapMethods(ClassWriter classWriter, Item items[], char c[]) {
int u = getAttributes();
boolean found = false;
for (int i = readUnsignedShort(u); i > 0; i--) {
String attrName = readUTF8(u + 2, c);
if ("BootstrapMethods".equals(attrName)) {
found = true;
break;
}
u += 6 + readInt(u + 4);
}
if (!found)
return;
int boostrapMethodCount = readUnsignedShort(u + 8);
int j = 0;
int v = u + 10;
for (; j < boostrapMethodCount; j++) {
int position = v - u - 10;
int hashCode = readConst(readUnsignedShort(v), c).hashCode();
for (int k = readUnsignedShort(v + 2); k > 0; k--) {
hashCode ^= readConst(readUnsignedShort(v + 4), c).hashCode();
v += 2;
}
v += 4;
Item item = new Item(j);
item.set(position, hashCode & 0x7fffffff);
int index = item.hashCode % items.length;
item.next = items[index];
items[index] = item;
}
int attrSize = readInt(u + 4);
ByteVector bootstrapMethods = new ByteVector(attrSize + 62);
bootstrapMethods.putByteArray(b, u + 10, attrSize - 2);
classWriter.bootstrapMethodsCount = boostrapMethodCount;
classWriter.bootstrapMethods = bootstrapMethods;
}
public ClassReader(InputStream is) throws IOException {
this(readClass(is, false));
}
public ClassReader(String name) throws IOException {
this(readClass(ClassLoader.getSystemResourceAsStream((new StringBuilder(String.valueOf(name.replace('.', '/')))).append(".class").toString()), true));
}
private static byte[] readClass(InputStream is, boolean close) throws IOException {
byte[] bs = Util.readByte(is);
if (close) {
is.close();
}
return bs;
// if(is == null)
// throw new IOException("Class not found");
// byte b[];
// int len;
// b = new byte[is.available()];
// len = 0;
// _L4:
// int n = is.read(b, len, b.length - len);
// if(n != -1) {
// len += n;
// if(len != b.length) goto _L4; else goto _L3
// } else goto {
// byte abyte0[];
// if(len < b.length)
// {
// byte c[] = new byte[len];
// System.arraycopy(b, 0, c, 0, len);
// b = c;
// }
// abyte0 = b;
// if(close)
// is.close();
// return abyte0;
// }
// _L1:
//
// _L2:
//
// _L3:
// int last;
// last = is.read();
// if(last >= 0)
// break MISSING_BLOCK_LABEL_115;
// abyte0 = b;
// if(close)
// is.close();
// return abyte0;
// byte c[] = new byte[b.length + 1000];
// System.arraycopy(b, 0, c, 0, len);
// c[len++] = (byte)last;
// b = c;
// goto _L4
// Exception exception;
// exception;
// if(close)
// is.close();
// throw exception;
}
public void accept(ClassVisitor classVisitor, int flags) {
accept(classVisitor, new Attribute[0], flags);
}
public void accept(ClassVisitor classVisitor, Attribute attrs[], int flags) {
int u = header;
char c[] = new char[maxStringLength];
Context context = new Context();
context.attrs = attrs;
context.flags = flags;
context.buffer = c;
int access = readUnsignedShort(u);
String name = readClass(u + 2, c);
String superClass = readClass(u + 4, c);
String interfaces[] = new String[readUnsignedShort(u + 6)];
u += 8;
for (int i = 0; i < interfaces.length; i++) {
interfaces[i] = readClass(u, c);
u += 2;
}
String signature = null;
String sourceFile = null;
String sourceDebug = null;
String enclosingOwner = null;
String enclosingName = null;
String enclosingDesc = null;
int anns = 0;
int ianns = 0;
int innerClasses = 0;
Attribute attributes = null;
u = getAttributes();
for (int i = readUnsignedShort(u); i > 0; i--) {
String attrName = readUTF8(u + 2, c);
if ("SourceFile".equals(attrName))
sourceFile = readUTF8(u + 8, c);
else if ("InnerClasses".equals(attrName))
innerClasses = u + 8;
else if ("EnclosingMethod".equals(attrName)) {
enclosingOwner = readClass(u + 8, c);
int item = readUnsignedShort(u + 10);
if (item != 0) {
enclosingName = readUTF8(items[item], c);
enclosingDesc = readUTF8(items[item] + 2, c);
}
} else if ("Signature".equals(attrName))
signature = readUTF8(u + 8, c);
else if ("RuntimeVisibleAnnotations".equals(attrName))
anns = u + 8;
else if ("Deprecated".equals(attrName))
access |= 0x20000;
else if ("Synthetic".equals(attrName))
access |= 0x41000;
else if ("SourceDebugExtension".equals(attrName)) {
int len = readInt(u + 4);
sourceDebug = readUTF(u + 8, len, new char[len]);
} else if ("RuntimeInvisibleAnnotations".equals(attrName))
ianns = u + 8;
else if ("BootstrapMethods".equals(attrName)) {
int bootstrapMethods[] = new int[readUnsignedShort(u + 8)];
int j = 0;
int v = u + 10;
for (; j < bootstrapMethods.length; j++) {
bootstrapMethods[j] = v;
v += 2 + readUnsignedShort(v + 2) << 1;
}
context.bootstrapMethods = bootstrapMethods;
} else {
Attribute attr = readAttribute(attrs, attrName, u + 8, readInt(u + 4), c, -1, null);
if (attr != null) {
attr.next = attributes;
attributes = attr;
}
}
u += 6 + readInt(u + 4);
}
classVisitor.visit(readInt(items[1] - 7), access, name, signature, superClass, interfaces);
if ((flags & 2) == 0 && (sourceFile != null || sourceDebug != null))
classVisitor.visitSource(sourceFile, sourceDebug);
if (enclosingOwner != null)
classVisitor.visitOuterClass(enclosingOwner, enclosingName, enclosingDesc);
if (anns != 0) {
int i = readUnsignedShort(anns);
int v = anns + 2;
for (; i > 0; i--)
v = readAnnotationValues(v + 2, c, true, classVisitor.visitAnnotation(readUTF8(v, c), true));
}
if (ianns != 0) {
int i = readUnsignedShort(ianns);
int v = ianns + 2;
for (; i > 0; i--)
v = readAnnotationValues(v + 2, c, true, classVisitor.visitAnnotation(readUTF8(v, c), false));
}
Attribute attr;
for (; attributes != null; attributes = attr) {
attr = attributes.next;
attributes.next = null;
classVisitor.visitAttribute(attributes);
}
if (innerClasses != 0) {
int v = innerClasses + 2;
for (int i = readUnsignedShort(innerClasses); i > 0; i--) {
classVisitor.visitInnerClass(readClass(v, c), readClass(v + 2, c), readUTF8(v + 4, c), readUnsignedShort(v + 6));
v += 8;
}
}
u = header + 10 + 2 * interfaces.length;
for (int i = readUnsignedShort(u - 2); i > 0; i--)
u = readField(classVisitor, context, u);
u += 2;
for (int i = readUnsignedShort(u - 2); i > 0; i--)
u = readMethod(classVisitor, context, u);
classVisitor.visitEnd();
}
private int readField(ClassVisitor classVisitor, Context context, int u) {
char c[] = context.buffer;
int access = readUnsignedShort(u);
String name = readUTF8(u + 2, c);
String desc = readUTF8(u + 4, c);
u += 6;
String signature = null;
int anns = 0;
int ianns = 0;
Object value = null;
Attribute attributes = null;
for (int i = readUnsignedShort(u); i > 0; i--) {
String attrName = readUTF8(u + 2, c);
if ("ConstantValue".equals(attrName)) {
int item = readUnsignedShort(u + 8);
value = item != 0 ? readConst(item, c) : null;
} else if ("Signature".equals(attrName))
signature = readUTF8(u + 8, c);
else if ("Deprecated".equals(attrName))
access |= 0x20000;
else if ("Synthetic".equals(attrName))
access |= 0x41000;
else if ("RuntimeVisibleAnnotations".equals(attrName))
anns = u + 8;
else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
ianns = u + 8;
} else {
Attribute attr = readAttribute(context.attrs, attrName, u + 8, readInt(u + 4), c, -1, null);
if (attr != null) {
attr.next = attributes;
attributes = attr;
}
}
u += 6 + readInt(u + 4);
}
u += 2;
FieldVisitor fv = classVisitor.visitField(access, name, desc, signature, value);
if (fv == null)
return u;
if (anns != 0) {
int i = readUnsignedShort(anns);
int v = anns + 2;
for (; i > 0; i--)
v = readAnnotationValues(v + 2, c, true, fv.visitAnnotation(readUTF8(v, c), true));
}
if (ianns != 0) {
int i = readUnsignedShort(ianns);
int v = ianns + 2;
for (; i > 0; i--)
v = readAnnotationValues(v + 2, c, true, fv.visitAnnotation(readUTF8(v, c), false));
}
Attribute attr;
for (; attributes != null; attributes = attr) {
attr = attributes.next;
attributes.next = null;
fv.visitAttribute(attributes);
}
fv.visitEnd();
return u;
}
private int readMethod(ClassVisitor classVisitor, Context context, int u) {
char c[] = context.buffer;
int access = readUnsignedShort(u);
String name = readUTF8(u + 2, c);
String desc = readUTF8(u + 4, c);
u += 6;
int code = 0;
int exception = 0;
String exceptions[] = (String[]) null;
String signature = null;
int anns = 0;
int ianns = 0;
int dann = 0;
int mpanns = 0;
int impanns = 0;
int firstAttribute = u;
Attribute attributes = null;
for (int i = readUnsignedShort(u); i > 0; i--) {
String attrName = readUTF8(u + 2, c);
if ("Code".equals(attrName)) {
if ((context.flags & 1) == 0)
code = u + 8;
} else if ("Exceptions".equals(attrName)) {
exceptions = new String[readUnsignedShort(u + 8)];
exception = u + 10;
for (int j = 0; j < exceptions.length; j++) {
exceptions[j] = readClass(exception, c);
exception += 2;
}
} else if ("Signature".equals(attrName))
signature = readUTF8(u + 8, c);
else if ("Deprecated".equals(attrName))
access |= 0x20000;
else if ("RuntimeVisibleAnnotations".equals(attrName))
anns = u + 8;
else if ("AnnotationDefault".equals(attrName))
dann = u + 8;
else if ("Synthetic".equals(attrName))
access |= 0x41000;
else if ("RuntimeInvisibleAnnotations".equals(attrName))
ianns = u + 8;
else if ("RuntimeVisibleParameterAnnotations".equals(attrName))
mpanns = u + 8;
else if ("RuntimeInvisibleParameterAnnotations".equals(attrName)) {
impanns = u + 8;
} else {
Attribute attr = readAttribute(context.attrs, attrName, u + 8, readInt(u + 4), c, -1, null);
if (attr != null) {
attr.next = attributes;
attributes = attr;
}
}
u += 6 + readInt(u + 4);
}
u += 2;
MethodVisitor mv = classVisitor.visitMethod(access, name, desc, signature, exceptions);
if (mv == null)
return u;
if (mv instanceof MethodWriter) {
MethodWriter mw = (MethodWriter) mv;
if (mw.cw.cr == this && signature.equals(mw.signature)) {
boolean sameExceptions = false;
if (exceptions == null)
sameExceptions = mw.exceptionCount == 0;
else if (exceptions.length == mw.exceptionCount) {
sameExceptions = true;
for (int j = exceptions.length - 1; j >= 0; j--) {
exception -= 2;
if (mw.exceptions[j] == readUnsignedShort(exception))
continue;
sameExceptions = false;
break;
}
}
if (sameExceptions) {
mw.classReaderOffset = firstAttribute;
mw.classReaderLength = u - firstAttribute;
return u;
}
}
}
if (dann != 0) {
AnnotationVisitor dv = mv.visitAnnotationDefault();
readAnnotationValue(dann, c, null, dv);
if (dv != null)
dv.visitEnd();
}
if (anns != 0) {
int i = readUnsignedShort(anns);
int v = anns + 2;
for (; i > 0; i--)
v = readAnnotationValues(v + 2, c, true, mv.visitAnnotation(readUTF8(v, c), true));
}
if (ianns != 0) {
int i = readUnsignedShort(ianns);
int v = ianns + 2;
for (; i > 0; i--)
v = readAnnotationValues(v + 2, c, true, mv.visitAnnotation(readUTF8(v, c), false));
}
if (mpanns != 0)
readParameterAnnotations(mpanns, desc, c, true, mv);
if (impanns != 0)
readParameterAnnotations(impanns, desc, c, false, mv);
Attribute attr;
for (; attributes != null; attributes = attr) {
attr = attributes.next;
attributes.next = null;
mv.visitAttribute(attributes);
}
if (code != 0) {
context.access = access;
context.name = name;
context.desc = desc;
mv.visitCode();
readCode(mv, context, code);
}
mv.visitEnd();
return u;
}
private void readCode(MethodVisitor mv, Context context, int u) {
byte b[] = this.b;
char c[] = context.buffer;
int maxStack = readUnsignedShort(u);
int maxLocals = readUnsignedShort(u + 2);
int codeLength = readInt(u + 4);
int codeStart = u += 8;
int codeEnd = u + codeLength;
Label labels[] = new Label[codeLength + 2];
readLabel(codeLength + 1, labels);
while (u < codeEnd) {
int offset = u - codeStart;
int opcode = b[u] & 0xff;
switch (ClassWriter.TYPE[opcode]) {
case 0: // '\0'
case 4: // '\004'
u++;
break;
case 9: // '\t'
readLabel(offset + readShort(u + 1), labels);
u += 3;
break;
case 10: // '\n'
readLabel(offset + readInt(u + 1), labels);
u += 5;
break;
case 17: // '\021'
opcode = b[u + 1] & 0xff;
if (opcode == 132)
u += 6;
else
u += 4;
break;
case 14: // '\016'
u = (u + 4) - (offset & 3);
readLabel(offset + readInt(u), labels);
for (int i = (readInt(u + 8) - readInt(u + 4)) + 1; i > 0; i--) {
readLabel(offset + readInt(u + 12), labels);
u += 4;
}
u += 12;
break;
case 15: // '\017'
u = (u + 4) - (offset & 3);
readLabel(offset + readInt(u), labels);
for (int i = readInt(u + 4); i > 0; i--) {
readLabel(offset + readInt(u + 12), labels);
u += 8;
}
u += 8;
break;
case 1: // '\001'
case 3: // '\003'
case 11: // '\013'
u += 2;
break;
case 2: // '\002'
case 5: // '\005'
case 6: // '\006'
case 12: // '\f'
case 13: // '\r'
u += 3;
break;
case 7: // '\007'
case 8: // '\b'
u += 5;
break;
case 16: // '\020'
default:
u += 4;
break;
}
}
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);
String type = readUTF8(items[readUnsignedShort(u + 8)], c);
mv.visitTryCatchBlock(start, end, handler, type);
u += 8;
}
u += 2;
int varTable = 0;
int varTypeTable = 0;
boolean zip = true;
boolean unzip = (context.flags & 8) != 0;
int stackMap = 0;
int stackMapSize = 0;
int frameCount = 0;
Context frame = null;
Attribute attributes = null;
for (int i = readUnsignedShort(u); i > 0; i--) {
String attrName = readUTF8(u + 2, c);
if ("LocalVariableTable".equals(attrName)) {
if ((context.flags & 2) == 0) {
varTable = u + 8;
int j = readUnsignedShort(u + 8);
int v = u;
for (; j > 0; j--) {
int label = readUnsignedShort(v + 10);
if (labels[label] == null)
readLabel(label, labels).status |= 1;
label += readUnsignedShort(v + 12);
if (labels[label] == null)
readLabel(label, labels).status |= 1;
v += 10;
}
}
} else if ("LocalVariableTypeTable".equals(attrName))
varTypeTable = u + 8;
else if ("LineNumberTable".equals(attrName)) {
if ((context.flags & 2) == 0) {
int j = readUnsignedShort(u + 8);
int v = u;
for (; j > 0; j--) {
int label = readUnsignedShort(v + 10);
if (labels[label] == null)
readLabel(label, labels).status |= 1;
labels[label].line = readUnsignedShort(v + 12);
v += 4;
}
}
} else if ("StackMapTable".equals(attrName)) {
if ((context.flags & 4) == 0) {
stackMap = u + 10;
stackMapSize = readInt(u + 4);
frameCount = readUnsignedShort(u + 8);
}
} else if ("StackMap".equals(attrName)) {
if ((context.flags & 4) == 0) {
zip = false;
stackMap = u + 10;
stackMapSize = readInt(u + 4);
frameCount = readUnsignedShort(u + 8);
}
} else {
for (int j = 0; j < context.attrs.length; j++)
if (context.attrs[j].type.equals(attrName)) {
Attribute attr = context.attrs[j].read(this, u + 8, readInt(u + 4), c, codeStart - 8, labels);
if (attr != null) {
attr.next = attributes;
attributes = attr;
}
}
}
u += 6 + readInt(u + 4);
}
u += 2;
if (stackMap != 0) {
frame = context;
frame.offset = -1;
frame.mode = 0;
frame.localCount = 0;
frame.localDiff = 0;
frame.stackCount = 0;
frame.local = new Object[maxLocals];
frame.stack = new Object[maxStack];
if (unzip)
getImplicitFrame(context);
for (int i = stackMap; i < (stackMap + stackMapSize) - 2; i++)
if (b[i] == 8) {
int v = readUnsignedShort(i + 1);
if (v >= 0 && v < codeLength && (b[codeStart + v] & 0xff) == 187)
readLabel(v, labels);
}
}
for (u = codeStart; u < codeEnd;) {
int offset = u - codeStart;
Label l = labels[offset];
if (l != null) {
mv.visitLabel(l);
if ((context.flags & 2) == 0 && l.line > 0)
mv.visitLineNumber(l.line, l);
}
while (frame != null && (frame.offset == offset || frame.offset == -1)) {
if (frame.offset != -1)
if (!zip || unzip)
mv.visitFrame(-1, frame.localCount, frame.local, frame.stackCount, frame.stack);
else
mv.visitFrame(frame.mode, frame.localDiff, frame.local, frame.stackCount, frame.stack);
if (frameCount > 0) {
stackMap = readFrame(stackMap, zip, unzip, labels, frame);
frameCount--;
} else {
frame = null;
}
}
int opcode = b[u] & 0xff;
switch (ClassWriter.TYPE[opcode]) {
case 0: // '\0'
{
mv.visitInsn(opcode);
u++;
break;
}
case 4: // '\004'
{
if (opcode > 54) {
opcode -= 59;
mv.visitVarInsn(54 + (opcode >> 2), opcode & 3);
} else {
opcode -= 26;
mv.visitVarInsn(21 + (opcode >> 2), opcode & 3);
}
u++;
break;
}
case 9: // '\t'
{
mv.visitJumpInsn(opcode, labels[offset + readShort(u + 1)]);
u += 3;
break;
}
case 10: // '\n'
{
mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]);
u += 5;
break;
}
case 17: // '\021'
{
opcode = b[u + 1] & 0xff;
if (opcode == 132) {
mv.visitIincInsn(readUnsignedShort(u + 2), readShort(u + 4));
u += 6;
} else {
mv.visitVarInsn(opcode, readUnsignedShort(u + 2));
u += 4;
}
break;
}
case 14: // '\016'
{
u = (u + 4) - (offset & 3);
int label = offset + readInt(u);
int min = readInt(u + 4);
int max = readInt(u + 8);
Label table[] = new Label[(max - min) + 1];
u += 12;
for (int i = 0; i < table.length; i++) {
table[i] = labels[offset + readInt(u)];
u += 4;
}
mv.visitTableSwitchInsn(min, max, labels[label], table);
break;
}
case 15: // '\017'
{
u = (u + 4) - (offset & 3);
int label = offset + readInt(u);
int len = readInt(u + 4);
int keys[] = new int[len];
Label values[] = new Label[len];
u += 8;
for (int i = 0; i < len; i++) {
keys[i] = readInt(u);
values[i] = labels[offset + readInt(u + 4)];
u += 8;
}
mv.visitLookupSwitchInsn(labels[label], keys, values);
break;
}
case 3: // '\003'
{
mv.visitVarInsn(opcode, b[u + 1] & 0xff);
u += 2;
break;
}
case 1: // '\001'
{
mv.visitIntInsn(opcode, b[u + 1]);
u += 2;
break;
}
case 2: // '\002'
{
mv.visitIntInsn(opcode, readShort(u + 1));
u += 3;
break;
}
case 11: // '\013'
{
mv.visitLdcInsn(readConst(b[u + 1] & 0xff, c));
u += 2;
break;
}
case 12: // '\f'
{
mv.visitLdcInsn(readConst(readUnsignedShort(u + 1), c));
u += 3;
break;
}
case 6: // '\006'
case 7: // '\007'
{
int cpIndex = items[readUnsignedShort(u + 1)];
String iowner = readClass(cpIndex, c);
cpIndex = items[readUnsignedShort(cpIndex + 2)];
String iname = readUTF8(cpIndex, c);
String idesc = readUTF8(cpIndex + 2, c);
if (opcode < 182)
mv.visitFieldInsn(opcode, iowner, iname, idesc);
else
mv.visitMethodInsn(opcode, iowner, iname, idesc);
if (opcode == 185)
u += 5;
else
u += 3;
break;
}
case 8: // '\b'
{
int cpIndex = items[readUnsignedShort(u + 1)];
int bsmIndex = context.bootstrapMethods[readUnsignedShort(cpIndex)];
Handle bsm = (Handle) readConst(readUnsignedShort(bsmIndex), c);
int bsmArgCount = readUnsignedShort(bsmIndex + 2);
Object bsmArgs[] = new Object[bsmArgCount];
bsmIndex += 4;
for (int i = 0; i < bsmArgCount; i++) {
bsmArgs[i] = readConst(readUnsignedShort(bsmIndex), c);
bsmIndex += 2;
}
cpIndex = items[readUnsignedShort(cpIndex + 2)];
String iname = readUTF8(cpIndex, c);
String idesc = readUTF8(cpIndex + 2, c);
mv.visitInvokeDynamicInsn(iname, idesc, bsm, bsmArgs);
u += 5;
break;
}
case 5: // '\005'
{
mv.visitTypeInsn(opcode, readClass(u + 1, c));
u += 3;
break;
}
case 13: // '\r'
{
mv.visitIincInsn(b[u + 1] & 0xff, b[u + 2]);
u += 3;
break;
}
case 16: // '\020'
default: {
mv.visitMultiANewArrayInsn(readClass(u + 1, c), b[u + 3] & 0xff);
u += 4;
break;
}
}
}
if (labels[codeLength] != null)
mv.visitLabel(labels[codeLength]);
if ((context.flags & 2) == 0 && varTable != 0) {
int typeTable[] = (int[]) null;
if (varTypeTable != 0) {
u = varTypeTable + 2;
typeTable = new int[readUnsignedShort(varTypeTable) * 3];
for (int i = typeTable.length; i > 0;) {
typeTable[--i] = u + 6;
typeTable[--i] = readUnsignedShort(u + 8);
typeTable[--i] = readUnsignedShort(u);
u += 10;
}
}
u = varTable + 2;
for (int i = readUnsignedShort(varTable); i > 0; i--) {
int start = readUnsignedShort(u);
int length = readUnsignedShort(u + 2);
int index = readUnsignedShort(u + 8);
String vsignature = null;
if (typeTable != null) {
for (int j = 0; j < typeTable.length; j += 3) {
if (typeTable[j] != start || typeTable[j + 1] != index)
continue;
vsignature = readUTF8(typeTable[j + 2], c);
break;
}
}
mv.visitLocalVariable(readUTF8(u + 4, c), readUTF8(u + 6, c), vsignature, labels[start], labels[start + length], index);
u += 10;
}
}
Attribute attr;
for (; attributes != null; attributes = attr) {
attr = attributes.next;
attributes.next = null;
mv.visitAttribute(attributes);
}
mv.visitMaxs(maxStack, maxLocals);
}
private void readParameterAnnotations(int v, String desc, char buf[], boolean visible, MethodVisitor mv) {
int n = b[v++] & 0xff;
int synthetics = Type.getArgumentTypes(desc).length - n;
int i;
for (i = 0; i < synthetics; i++) {
AnnotationVisitor av = mv.visitParameterAnnotation(i, "Ljava/lang/Synthetic;", false);
if (av != null)
av.visitEnd();
}
for (; i < n + synthetics; i++) {
int j = readUnsignedShort(v);
v += 2;
for (; j > 0; j--) {
AnnotationVisitor av = mv.visitParameterAnnotation(i, readUTF8(v, buf), visible);
v = readAnnotationValues(v + 2, buf, true, av);
}
}
}
private int readAnnotationValues(int v, char buf[], boolean named, AnnotationVisitor av) {
int i = readUnsignedShort(v);
v += 2;
if (named)
for (; i > 0; i--)
v = readAnnotationValue(v + 2, buf, readUTF8(v, buf), av);
else
for (; i > 0; i--)
v = readAnnotationValue(v, buf, null, av);
if (av != null)
av.visitEnd();
return v;
}
private int readAnnotationValue(int v, char buf[], String name, AnnotationVisitor av) {
if (av == null) {
switch (b[v] & 0xff) {
case 101: // 'e'
return v + 5;
case 64: // '@'
return readAnnotationValues(v + 3, buf, true, null);
case 91: // '['
return readAnnotationValues(v + 1, buf, false, null);
}
return v + 3;
}
label0: switch (b[v++] & 0xff) {
default:
break;
case 68: // 'D'
case 70: // 'F'
case 73: // 'I'
case 74: // 'J'
av.visit(name, readConst(readUnsignedShort(v), buf));
v += 2;
break;
case 66: // 'B'
av.visit(name, new Byte((byte) readInt(items[readUnsignedShort(v)])));
v += 2;
break;
case 90: // 'Z'
av.visit(name, readInt(items[readUnsignedShort(v)]) != 0 ? ((Object) (Boolean.TRUE)) : ((Object) (Boolean.FALSE)));
v += 2;
break;
case 83: // 'S'
av.visit(name, new Short((short) readInt(items[readUnsignedShort(v)])));
v += 2;
break;
case 67: // 'C'
av.visit(name, new Character((char) readInt(items[readUnsignedShort(v)])));
v += 2;
break;
case 115: // 's'
av.visit(name, readUTF8(v, buf));
v += 2;
break;
case 101: // 'e'
av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
v += 4;
break;
case 99: // 'c'
av.visit(name, Type.getType(readUTF8(v, buf)));
v += 2;
break;
case 64: // '@'
v = readAnnotationValues(v + 2, buf, true, av.visitAnnotation(name, readUTF8(v, buf)));
break;
case 91: // '['
int size = readUnsignedShort(v);
v += 2;
if (size == 0)
return readAnnotationValues(v - 2, buf, false, av.visitArray(name));
switch (b[v++] & 0xff) {
case 66: // 'B'
byte bv[] = new byte[size];
for (int i = 0; i < size; i++) {
bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
v += 3;
}
av.visit(name, bv);
v--;
break label0;
case 90: // 'Z'
boolean zv[] = new boolean[size];
for (int i = 0; i < size; i++) {
zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
v += 3;
}
av.visit(name, zv);
v--;
break label0;
case 83: // 'S'
short sv[] = new short[size];
for (int i = 0; i < size; i++) {
sv[i] = (short) readInt(items[readUnsignedShort(v)]);
v += 3;
}
av.visit(name, sv);
v--;
break label0;
case 67: // 'C'
char cv[] = new char[size];
for (int i = 0; i < size; i++) {
cv[i] = (char) readInt(items[readUnsignedShort(v)]);
v += 3;
}
av.visit(name, cv);
v--;
break label0;
case 73: // 'I'
int iv[] = new int[size];
for (int i = 0; i < size; i++) {
iv[i] = readInt(items[readUnsignedShort(v)]);
v += 3;
}
av.visit(name, iv);
v--;
break label0;
case 74: // 'J'
long lv[] = new long[size];
for (int i = 0; i < size; i++) {
lv[i] = readLong(items[readUnsignedShort(v)]);
v += 3;
}
av.visit(name, lv);
v--;
break label0;
case 70: // 'F'
float fv[] = new float[size];
for (int i = 0; i < size; i++) {
fv[i] = Float.intBitsToFloat(readInt(items[readUnsignedShort(v)]));
v += 3;
}
av.visit(name, fv);
v--;
break label0;
case 68: // 'D'
double dv[] = new double[size];
for (int i = 0; i < size; i++) {
dv[i] = Double.longBitsToDouble(readLong(items[readUnsignedShort(v)]));
v += 3;
}
av.visit(name, dv);
v--;
break;
default:
v = readAnnotationValues(v - 3, buf, false, av.visitArray(name));
break;
}
break;
}
return v;
}
private void getImplicitFrame(Context frame) {
String desc = frame.desc;
Object locals[] = frame.local;
int local = 0;
if ((frame.access & 8) == 0)
if ("".equals(frame.name))
locals[local++] = Opcodes.UNINITIALIZED_THIS;
else
locals[local++] = readClass(header + 2, frame.buffer);
int i = 1;
do {
int j = i;
switch (desc.charAt(i++)) {
case 66: // 'B'
case 67: // 'C'
case 73: // 'I'
case 83: // 'S'
case 90: // 'Z'
locals[local++] = Opcodes.INTEGER;
break;
case 70: // 'F'
locals[local++] = Opcodes.FLOAT;
break;
case 74: // 'J'
locals[local++] = Opcodes.LONG;
break;
case 68: // 'D'
locals[local++] = Opcodes.DOUBLE;
break;
case 91: // '['
for (; desc.charAt(i) == '['; i++)
;
if (desc.charAt(i) == 'L')
for (i++; desc.charAt(i) != ';'; i++)
;
locals[local++] = desc.substring(j, ++i);
break;
case 76: // 'L'
for (; desc.charAt(i) != ';'; i++)
;
locals[local++] = desc.substring(j + 1, i++);
break;
default:
frame.localCount = local;
return;
}
} while (true);
}
private int readFrame(int stackMap, boolean zip, boolean unzip, Label labels[], Context frame) {
char c[] = frame.buffer;
int tag;
if (zip) {
tag = b[stackMap++] & 0xff;
} else {
tag = 255;
frame.offset = -1;
}
frame.localDiff = 0;
int delta;
if (tag < 64) {
delta = tag;
frame.mode = 3;
frame.stackCount = 0;
} else if (tag < 128) {
delta = tag - 64;
stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
frame.mode = 4;
frame.stackCount = 1;
} else {
delta = readUnsignedShort(stackMap);
stackMap += 2;
if (tag == 247) {
stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
frame.mode = 4;
frame.stackCount = 1;
} else if (tag >= 248 && tag < 251) {
frame.mode = 2;
frame.localDiff = 251 - tag;
frame.localCount -= frame.localDiff;
frame.stackCount = 0;
} else if (tag == 251) {
frame.mode = 3;
frame.stackCount = 0;
} else if (tag < 255) {
int local = unzip ? frame.localCount : 0;
for (int i = tag - 251; i > 0; i--)
stackMap = readFrameType(frame.local, local++, stackMap, c, labels);
frame.mode = 1;
frame.localDiff = tag - 251;
frame.localCount += frame.localDiff;
frame.stackCount = 0;
} else {
frame.mode = 0;
int n = readUnsignedShort(stackMap);
stackMap += 2;
frame.localDiff = n;
frame.localCount = n;
int local = 0;
for (; n > 0; n--)
stackMap = readFrameType(frame.local, local++, stackMap, c, labels);
n = readUnsignedShort(stackMap);
stackMap += 2;
frame.stackCount = n;
int stack = 0;
for (; n > 0; n--)
stackMap = readFrameType(frame.stack, stack++, stackMap, c, labels);
}
}
frame.offset += delta + 1;
readLabel(frame.offset, labels);
return stackMap;
}
private int readFrameType(Object frame[], int index, int v, char buf[], Label labels[]) {
int type = b[v++] & 0xff;
switch (type) {
case 0: // '\0'
frame[index] = Opcodes.TOP;
break;
case 1: // '\001'
frame[index] = Opcodes.INTEGER;
break;
case 2: // '\002'
frame[index] = Opcodes.FLOAT;
break;
case 3: // '\003'
frame[index] = Opcodes.DOUBLE;
break;
case 4: // '\004'
frame[index] = Opcodes.LONG;
break;
case 5: // '\005'
frame[index] = Opcodes.NULL;
break;
case 6: // '\006'
frame[index] = Opcodes.UNINITIALIZED_THIS;
break;
case 7: // '\007'
frame[index] = readClass(v, buf);
v += 2;
break;
default:
frame[index] = readLabel(readUnsignedShort(v), labels);
v += 2;
break;
}
return v;
}
protected Label readLabel(int offset, Label labels[]) {
if (labels[offset] == null)
labels[offset] = new Label();
return labels[offset];
}
private int getAttributes() {
int u = header + 8 + readUnsignedShort(header + 6) * 2;
for (int i = readUnsignedShort(u); i > 0; i--) {
for (int j = readUnsignedShort(u + 8); j > 0; j--)
u += 6 + readInt(u + 12);
u += 8;
}
u += 2;
for (int i = readUnsignedShort(u); i > 0; i--) {
for (int j = readUnsignedShort(u + 8); j > 0; j--)
u += 6 + readInt(u + 12);
u += 8;
}
return u + 2;
}
private Attribute readAttribute(Attribute attrs[], String type, int off, int len, char buf[], int codeOff, Label labels[]) {
for (int i = 0; i < attrs.length; i++)
if (attrs[i].type.equals(type))
return attrs[i].read(this, off, len, buf, codeOff, labels);
return (new Attribute(type)).read(this, off, len, null, -1, null);
}
public int getItemCount() {
return items.length;
}
public int getItem(int item) {
return items[item];
}
public int getMaxStringLength() {
return maxStringLength;
}
public int readByte(int index) {
return b[index] & 0xff;
}
public int readUnsignedShort(int index) {
byte b[] = this.b;
return (b[index] & 0xff) << 8 | b[index + 1] & 0xff;
}
public short readShort(int index) {
byte b[] = this.b;
return (short) ((b[index] & 0xff) << 8 | b[index + 1] & 0xff);
}
public int readInt(int index) {
byte b[] = this.b;
return (b[index] & 0xff) << 24 | (b[index + 1] & 0xff) << 16 | (b[index + 2] & 0xff) << 8 | b[index + 3] & 0xff;
}
public long readLong(int index) {
long l1 = readInt(index);
long l0 = (long) readInt(index + 4) & 0xffffffffL;
return l1 << 32 | l0;
}
public String readUTF8(int index, char buf[]) {
int item = readUnsignedShort(index);
if (index == 0 || item == 0)
return null;
String s = strings[item];
if (s != null) {
return s;
} else {
index = items[item];
return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf);
}
}
private String readUTF(int index, int utfLen, char buf[]) {
int endIndex = index + utfLen;
byte b[] = this.b;
int strLen = 0;
int st = 0;
char cc = '\0';
while (index < endIndex) {
int c = b[index++];
switch (st) {
default:
break;
case 0: // '\0'
c &= 0xff;
if (c < 128) {
buf[strLen++] = (char) c;
break;
}
if (c < 224 && c > 191) {
cc = (char) (c & 0x1f);
st = 1;
} else {
cc = (char) (c & 0xf);
st = 2;
}
break;
case 1: // '\001'
buf[strLen++] = (char) (cc << 6 | c & 0x3f);
st = 0;
break;
case 2: // '\002'
cc = (char) (cc << 6 | c & 0x3f);
st = 1;
break;
}
}
return new String(buf, 0, strLen);
}
public String readClass(int index, char buf[]) {
return readUTF8(items[readUnsignedShort(index)], buf);
}
public Object readConst(int item, char buf[]) {
int index = this.items[item];
switch (b[index - 1]) {
case 3: // '\003'
return new Integer(readInt(index));
case 4: // '\004'
return new Float(Float.intBitsToFloat(readInt(index)));
case 5: // '\005'
return new Long(readLong(index));
case 6: // '\006'
return new Double(Double.longBitsToDouble(readLong(index)));
case 7: // '\007'
return Type.getObjectType(readUTF8(index, buf));
case 8: // '\b'
return readUTF8(index, buf);
case 16: // '\020'
return Type.getMethodType(readUTF8(index, buf));
case 9: // '\t'
case 10: // '\n'
case 11: // '\013'
case 12: // '\f'
case 13: // '\r'
case 14: // '\016'
case 15: // '\017'
default:
int tag = readByte(index);
int items[] = this.items;
int cpIndex = items[readUnsignedShort(index + 1)];
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);
}
}
public static final int SKIP_CODE = 1;
public static final int SKIP_DEBUG = 2;
public static final int SKIP_FRAMES = 4;
public final int header;
static final boolean SIGNATURES = true;
static final boolean ANNOTATIONS = true;
static final boolean FRAMES = true;
static final boolean WRITER = true;
static final boolean RESIZE = true;
public static final int EXPAND_FRAMES = 8;
public final byte b[];
private final int items[];
private final String strings[];
private final int maxStringLength;
}