2022-03-02 20:59:20 +00:00
|
|
|
package org.objectweb.asm;
|
|
|
|
|
|
|
|
import com.discord.widgets.chat.input.MentionUtilsKt;
|
|
|
|
import org.objectweb.asm.Attribute;
|
2022-03-30 18:15:49 +00:00
|
|
|
/* loaded from: com.discord-120015.apk:org/objectweb/asm/MethodWriter.SCL.lombok */
|
2022-03-02 20:59:20 +00:00
|
|
|
final class MethodWriter extends MethodVisitor {
|
|
|
|
static final int COMPUTE_NOTHING = 0;
|
|
|
|
static final int COMPUTE_MAX_STACK_AND_LOCAL = 1;
|
|
|
|
static final int COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES = 2;
|
|
|
|
static final int COMPUTE_INSERTED_FRAMES = 3;
|
|
|
|
static final int COMPUTE_ALL_FRAMES = 4;
|
|
|
|
private static final int NA = 0;
|
|
|
|
private static final int[] STACK_SIZE_DELTA = {0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 0, 0, 1, 2, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, -1, -1, -1, -1, -1, -2, -1, -2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, -4, -3, -4, -3, -3, -3, -3, -1, -2, 1, 1, 1, 2, 2, 2, 0, -1, -2, -1, -2, -1, -2, -1, -2, -1, -2, -1, -2, -1, -2, -1, -2, -1, -2, -1, -2, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -2, -1, -2, -1, -2, 0, 1, 0, 1, -1, -1, 0, 0, 1, 1, -1, 0, -1, 0, 0, 0, -3, -1, -1, -3, -3, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -2, -2, -2, 0, 1, 0, -1, -1, -1, -2, -1, -2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, -1, -1, 0, 0};
|
|
|
|
private final SymbolTable symbolTable;
|
|
|
|
private final int accessFlags;
|
|
|
|
private final int nameIndex;
|
|
|
|
private final String name;
|
|
|
|
private final int descriptorIndex;
|
|
|
|
private final String descriptor;
|
|
|
|
private int maxStack;
|
|
|
|
private int maxLocals;
|
|
|
|
private final ByteVector code = new ByteVector();
|
|
|
|
private Handler firstHandler;
|
|
|
|
private Handler lastHandler;
|
|
|
|
private int lineNumberTableLength;
|
|
|
|
private ByteVector lineNumberTable;
|
|
|
|
private int localVariableTableLength;
|
|
|
|
private ByteVector localVariableTable;
|
|
|
|
private int localVariableTypeTableLength;
|
|
|
|
private ByteVector localVariableTypeTable;
|
|
|
|
private int stackMapTableNumberOfEntries;
|
|
|
|
private ByteVector stackMapTableEntries;
|
|
|
|
private AnnotationWriter lastCodeRuntimeVisibleTypeAnnotation;
|
|
|
|
private AnnotationWriter lastCodeRuntimeInvisibleTypeAnnotation;
|
|
|
|
private Attribute firstCodeAttribute;
|
|
|
|
private final int numberOfExceptions;
|
|
|
|
private final int[] exceptionIndexTable;
|
|
|
|
private final int signatureIndex;
|
|
|
|
private AnnotationWriter lastRuntimeVisibleAnnotation;
|
|
|
|
private AnnotationWriter lastRuntimeInvisibleAnnotation;
|
|
|
|
private int visibleAnnotableParameterCount;
|
|
|
|
private AnnotationWriter[] lastRuntimeVisibleParameterAnnotations;
|
|
|
|
private int invisibleAnnotableParameterCount;
|
|
|
|
private AnnotationWriter[] lastRuntimeInvisibleParameterAnnotations;
|
|
|
|
private AnnotationWriter lastRuntimeVisibleTypeAnnotation;
|
|
|
|
private AnnotationWriter lastRuntimeInvisibleTypeAnnotation;
|
|
|
|
private ByteVector defaultValue;
|
|
|
|
private int parametersCount;
|
|
|
|
private ByteVector parameters;
|
|
|
|
private Attribute firstAttribute;
|
|
|
|
private final int compute;
|
|
|
|
private Label firstBasicBlock;
|
|
|
|
private Label lastBasicBlock;
|
|
|
|
private Label currentBasicBlock;
|
|
|
|
private int relativeStackSize;
|
|
|
|
private int maxRelativeStackSize;
|
|
|
|
private int currentLocals;
|
|
|
|
private int previousFrameOffset;
|
|
|
|
private int[] previousFrame;
|
|
|
|
private int[] currentFrame;
|
|
|
|
private boolean hasSubroutines;
|
|
|
|
private boolean hasAsmInstructions;
|
|
|
|
private int lastBytecodeOffset;
|
|
|
|
private int sourceOffset;
|
|
|
|
private int sourceLength;
|
|
|
|
|
|
|
|
MethodWriter(SymbolTable symbolTable, int i, String str, String str2, String str3, String[] strArr, int i2) {
|
|
|
|
super(Opcodes.ASM9);
|
|
|
|
this.symbolTable = symbolTable;
|
|
|
|
this.accessFlags = "<init>".equals(str) ? i | 262144 : i;
|
|
|
|
this.nameIndex = symbolTable.addConstantUtf8(str);
|
|
|
|
this.name = str;
|
|
|
|
this.descriptorIndex = symbolTable.addConstantUtf8(str2);
|
|
|
|
this.descriptor = str2;
|
|
|
|
this.signatureIndex = str3 == null ? 0 : symbolTable.addConstantUtf8(str3);
|
|
|
|
if (strArr == null || strArr.length <= 0) {
|
|
|
|
this.numberOfExceptions = 0;
|
|
|
|
this.exceptionIndexTable = null;
|
|
|
|
} else {
|
|
|
|
this.numberOfExceptions = strArr.length;
|
|
|
|
this.exceptionIndexTable = new int[this.numberOfExceptions];
|
|
|
|
for (int i3 = 0; i3 < this.numberOfExceptions; i3++) {
|
|
|
|
this.exceptionIndexTable[i3] = symbolTable.addConstantClass(strArr[i3]).index;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.compute = i2;
|
|
|
|
if (i2 != 0) {
|
|
|
|
int argumentsAndReturnSizes = Type.getArgumentsAndReturnSizes(str2) >> 2;
|
|
|
|
argumentsAndReturnSizes = (i & 8) != 0 ? argumentsAndReturnSizes - 1 : argumentsAndReturnSizes;
|
|
|
|
this.maxLocals = argumentsAndReturnSizes;
|
|
|
|
this.currentLocals = argumentsAndReturnSizes;
|
|
|
|
this.firstBasicBlock = new Label();
|
|
|
|
visitLabel(this.firstBasicBlock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
boolean hasFrames() {
|
|
|
|
return this.stackMapTableNumberOfEntries > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
boolean hasAsmInstructions() {
|
|
|
|
return this.hasAsmInstructions;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitParameter(String str, int i) {
|
|
|
|
if (this.parameters == null) {
|
|
|
|
this.parameters = new ByteVector();
|
|
|
|
}
|
|
|
|
this.parametersCount++;
|
|
|
|
this.parameters.putShort(str == null ? 0 : this.symbolTable.addConstantUtf8(str)).putShort(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public AnnotationVisitor visitAnnotationDefault() {
|
|
|
|
this.defaultValue = new ByteVector();
|
|
|
|
return new AnnotationWriter(this.symbolTable, false, this.defaultValue, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public AnnotationVisitor visitAnnotation(String str, boolean z2) {
|
|
|
|
if (z2) {
|
|
|
|
AnnotationWriter create = AnnotationWriter.create(this.symbolTable, str, this.lastRuntimeVisibleAnnotation);
|
|
|
|
this.lastRuntimeVisibleAnnotation = create;
|
|
|
|
return create;
|
|
|
|
}
|
|
|
|
AnnotationWriter create2 = AnnotationWriter.create(this.symbolTable, str, this.lastRuntimeInvisibleAnnotation);
|
|
|
|
this.lastRuntimeInvisibleAnnotation = create2;
|
|
|
|
return create2;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public AnnotationVisitor visitTypeAnnotation(int i, TypePath typePath, String str, boolean z2) {
|
|
|
|
if (z2) {
|
|
|
|
AnnotationWriter create = AnnotationWriter.create(this.symbolTable, i, typePath, str, this.lastRuntimeVisibleTypeAnnotation);
|
|
|
|
this.lastRuntimeVisibleTypeAnnotation = create;
|
|
|
|
return create;
|
|
|
|
}
|
|
|
|
AnnotationWriter create2 = AnnotationWriter.create(this.symbolTable, i, typePath, str, this.lastRuntimeInvisibleTypeAnnotation);
|
|
|
|
this.lastRuntimeInvisibleTypeAnnotation = create2;
|
|
|
|
return create2;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitAnnotableParameterCount(int i, boolean z2) {
|
|
|
|
if (z2) {
|
|
|
|
this.visibleAnnotableParameterCount = i;
|
|
|
|
} else {
|
|
|
|
this.invisibleAnnotableParameterCount = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public AnnotationVisitor visitParameterAnnotation(int i, String str, boolean z2) {
|
|
|
|
if (z2) {
|
|
|
|
if (this.lastRuntimeVisibleParameterAnnotations == null) {
|
|
|
|
this.lastRuntimeVisibleParameterAnnotations = new AnnotationWriter[Type.getArgumentTypes(this.descriptor).length];
|
|
|
|
}
|
|
|
|
AnnotationWriter[] annotationWriterArr = this.lastRuntimeVisibleParameterAnnotations;
|
|
|
|
AnnotationWriter create = AnnotationWriter.create(this.symbolTable, str, this.lastRuntimeVisibleParameterAnnotations[i]);
|
|
|
|
annotationWriterArr[i] = create;
|
|
|
|
return create;
|
|
|
|
}
|
|
|
|
if (this.lastRuntimeInvisibleParameterAnnotations == null) {
|
|
|
|
this.lastRuntimeInvisibleParameterAnnotations = new AnnotationWriter[Type.getArgumentTypes(this.descriptor).length];
|
|
|
|
}
|
|
|
|
AnnotationWriter[] annotationWriterArr2 = this.lastRuntimeInvisibleParameterAnnotations;
|
|
|
|
AnnotationWriter create2 = AnnotationWriter.create(this.symbolTable, str, this.lastRuntimeInvisibleParameterAnnotations[i]);
|
|
|
|
annotationWriterArr2[i] = create2;
|
|
|
|
return create2;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitAttribute(Attribute attribute) {
|
|
|
|
if (attribute.isCodeAttribute()) {
|
|
|
|
attribute.nextAttribute = this.firstCodeAttribute;
|
|
|
|
this.firstCodeAttribute = attribute;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
attribute.nextAttribute = this.firstAttribute;
|
|
|
|
this.firstAttribute = attribute;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitCode() {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitFrame(int i, int i2, Object[] objArr, int i3, Object[] objArr2) {
|
|
|
|
int i4;
|
|
|
|
if (this.compute != 4) {
|
|
|
|
if (this.compute == 3) {
|
|
|
|
if (this.currentBasicBlock.frame == null) {
|
|
|
|
this.currentBasicBlock.frame = new CurrentFrame(this.currentBasicBlock);
|
|
|
|
this.currentBasicBlock.frame.setInputFrameFromDescriptor(this.symbolTable, this.accessFlags, this.descriptor, i2);
|
|
|
|
this.currentBasicBlock.frame.accept(this);
|
|
|
|
} else {
|
|
|
|
if (i == -1) {
|
|
|
|
this.currentBasicBlock.frame.setInputFrameFromApiFormat(this.symbolTable, i2, objArr, i3, objArr2);
|
|
|
|
}
|
|
|
|
this.currentBasicBlock.frame.accept(this);
|
|
|
|
}
|
|
|
|
} else if (i == -1) {
|
|
|
|
if (this.previousFrame == null) {
|
|
|
|
int argumentsAndReturnSizes = Type.getArgumentsAndReturnSizes(this.descriptor) >> 2;
|
|
|
|
Frame frame = new Frame(new Label());
|
|
|
|
frame.setInputFrameFromDescriptor(this.symbolTable, this.accessFlags, this.descriptor, argumentsAndReturnSizes);
|
|
|
|
frame.accept(this);
|
|
|
|
}
|
|
|
|
this.currentLocals = i2;
|
|
|
|
int visitFrameStart = visitFrameStart(this.code.length, i2, i3);
|
|
|
|
for (int i5 = 0; i5 < i2; i5++) {
|
|
|
|
visitFrameStart++;
|
|
|
|
this.currentFrame[visitFrameStart] = Frame.getAbstractTypeFromApiFormat(this.symbolTable, objArr[i5]);
|
|
|
|
}
|
|
|
|
for (int i6 = 0; i6 < i3; i6++) {
|
|
|
|
visitFrameStart++;
|
|
|
|
this.currentFrame[visitFrameStart] = Frame.getAbstractTypeFromApiFormat(this.symbolTable, objArr2[i6]);
|
|
|
|
}
|
|
|
|
visitFrameEnd();
|
|
|
|
} else if (this.symbolTable.getMajorVersion() < 50) {
|
|
|
|
throw new IllegalArgumentException("Class versions V1_5 or less must use F_NEW frames.");
|
|
|
|
} else {
|
|
|
|
if (this.stackMapTableEntries == null) {
|
|
|
|
this.stackMapTableEntries = new ByteVector();
|
|
|
|
i4 = this.code.length;
|
|
|
|
} else {
|
|
|
|
i4 = (this.code.length - this.previousFrameOffset) - 1;
|
|
|
|
if (i4 < 0) {
|
|
|
|
if (i != 3) {
|
|
|
|
throw new IllegalStateException();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch (i) {
|
|
|
|
case 0:
|
|
|
|
this.currentLocals = i2;
|
|
|
|
this.stackMapTableEntries.putByte(255).putShort(i4).putShort(i2);
|
|
|
|
for (int i7 = 0; i7 < i2; i7++) {
|
|
|
|
putFrameType(objArr[i7]);
|
|
|
|
}
|
|
|
|
this.stackMapTableEntries.putShort(i3);
|
|
|
|
for (int i8 = 0; i8 < i3; i8++) {
|
|
|
|
putFrameType(objArr2[i8]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
this.currentLocals += i2;
|
|
|
|
this.stackMapTableEntries.putByte(251 + i2).putShort(i4);
|
|
|
|
for (int i9 = 0; i9 < i2; i9++) {
|
|
|
|
putFrameType(objArr[i9]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
this.currentLocals -= i2;
|
|
|
|
this.stackMapTableEntries.putByte(251 - i2).putShort(i4);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
if (i4 < 64) {
|
|
|
|
this.stackMapTableEntries.putByte(i4);
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
this.stackMapTableEntries.putByte(251).putShort(i4);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 4:
|
|
|
|
if (i4 < 64) {
|
|
|
|
this.stackMapTableEntries.putByte(64 + i4);
|
|
|
|
} else {
|
|
|
|
this.stackMapTableEntries.putByte(247).putShort(i4);
|
|
|
|
}
|
|
|
|
putFrameType(objArr2[0]);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw new IllegalArgumentException();
|
|
|
|
}
|
|
|
|
this.previousFrameOffset = this.code.length;
|
|
|
|
this.stackMapTableNumberOfEntries++;
|
|
|
|
}
|
|
|
|
if (this.compute == 2) {
|
|
|
|
this.relativeStackSize = i3;
|
|
|
|
for (int i10 = 0; i10 < i3; i10++) {
|
|
|
|
if (objArr2[i10] == Opcodes.LONG || objArr2[i10] == Opcodes.DOUBLE) {
|
|
|
|
this.relativeStackSize++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (this.relativeStackSize > this.maxRelativeStackSize) {
|
|
|
|
this.maxRelativeStackSize = this.relativeStackSize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.maxStack = Math.max(this.maxStack, i3);
|
|
|
|
this.maxLocals = Math.max(this.maxLocals, this.currentLocals);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitInsn(int i) {
|
|
|
|
this.lastBytecodeOffset = this.code.length;
|
|
|
|
this.code.putByte(i);
|
|
|
|
if (this.currentBasicBlock != null) {
|
|
|
|
if (this.compute == 4 || this.compute == 3) {
|
|
|
|
this.currentBasicBlock.frame.execute(i, 0, null, null);
|
|
|
|
} else {
|
|
|
|
int i2 = this.relativeStackSize + STACK_SIZE_DELTA[i];
|
|
|
|
if (i2 > this.maxRelativeStackSize) {
|
|
|
|
this.maxRelativeStackSize = i2;
|
|
|
|
}
|
|
|
|
this.relativeStackSize = i2;
|
|
|
|
}
|
|
|
|
if ((i >= 172 && i <= 177) || i == 191) {
|
|
|
|
endCurrentBasicBlockWithNoSuccessor();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitIntInsn(int i, int i2) {
|
|
|
|
this.lastBytecodeOffset = this.code.length;
|
|
|
|
if (i == 17) {
|
|
|
|
this.code.put12(i, i2);
|
|
|
|
} else {
|
|
|
|
this.code.put11(i, i2);
|
|
|
|
}
|
|
|
|
if (this.currentBasicBlock == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (this.compute == 4 || this.compute == 3) {
|
|
|
|
this.currentBasicBlock.frame.execute(i, i2, null, null);
|
|
|
|
} else if (i != 188) {
|
|
|
|
int i3 = this.relativeStackSize + 1;
|
|
|
|
if (i3 > this.maxRelativeStackSize) {
|
|
|
|
this.maxRelativeStackSize = i3;
|
|
|
|
}
|
|
|
|
this.relativeStackSize = i3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitVarInsn(int i, int i2) {
|
|
|
|
this.lastBytecodeOffset = this.code.length;
|
|
|
|
if (i2 < 4 && i != 169) {
|
|
|
|
this.code.putByte(i < 54 ? 26 + ((i - 21) << 2) + i2 : 59 + ((i - 54) << 2) + i2);
|
|
|
|
} else if (i2 >= 256) {
|
|
|
|
this.code.putByte(196).put12(i, i2);
|
|
|
|
} else {
|
|
|
|
this.code.put11(i, i2);
|
|
|
|
}
|
|
|
|
if (this.currentBasicBlock != null) {
|
|
|
|
if (this.compute == 4 || this.compute == 3) {
|
|
|
|
this.currentBasicBlock.frame.execute(i, i2, null, null);
|
|
|
|
} else if (i == 169) {
|
|
|
|
Label label = this.currentBasicBlock;
|
|
|
|
label.flags = (short) (label.flags | 64);
|
|
|
|
this.currentBasicBlock.outputStackSize = (short) this.relativeStackSize;
|
|
|
|
endCurrentBasicBlockWithNoSuccessor();
|
|
|
|
} else {
|
|
|
|
int i3 = this.relativeStackSize + STACK_SIZE_DELTA[i];
|
|
|
|
if (i3 > this.maxRelativeStackSize) {
|
|
|
|
this.maxRelativeStackSize = i3;
|
|
|
|
}
|
|
|
|
this.relativeStackSize = i3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (this.compute != 0) {
|
|
|
|
int i4 = (i == 22 || i == 24 || i == 55 || i == 57) ? i2 + 2 : i2 + 1;
|
|
|
|
if (i4 > this.maxLocals) {
|
|
|
|
this.maxLocals = i4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (i >= 54 && this.compute == 4 && this.firstHandler != null) {
|
|
|
|
visitLabel(new Label());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitTypeInsn(int i, String str) {
|
|
|
|
this.lastBytecodeOffset = this.code.length;
|
|
|
|
Symbol addConstantClass = this.symbolTable.addConstantClass(str);
|
|
|
|
this.code.put12(i, addConstantClass.index);
|
|
|
|
if (this.currentBasicBlock == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (this.compute == 4 || this.compute == 3) {
|
|
|
|
this.currentBasicBlock.frame.execute(i, this.lastBytecodeOffset, addConstantClass, this.symbolTable);
|
|
|
|
} else if (i == 187) {
|
|
|
|
int i2 = this.relativeStackSize + 1;
|
|
|
|
if (i2 > this.maxRelativeStackSize) {
|
|
|
|
this.maxRelativeStackSize = i2;
|
|
|
|
}
|
|
|
|
this.relativeStackSize = i2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitFieldInsn(int i, String str, String str2, String str3) {
|
|
|
|
int i2;
|
|
|
|
this.lastBytecodeOffset = this.code.length;
|
|
|
|
Symbol addConstantFieldref = this.symbolTable.addConstantFieldref(str, str2, str3);
|
|
|
|
this.code.put12(i, addConstantFieldref.index);
|
|
|
|
if (this.currentBasicBlock == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (this.compute == 4 || this.compute == 3) {
|
|
|
|
this.currentBasicBlock.frame.execute(i, 0, addConstantFieldref, this.symbolTable);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
char charAt = str3.charAt(0);
|
|
|
|
switch (i) {
|
|
|
|
case Opcodes.GETSTATIC /* 178 */:
|
|
|
|
i2 = this.relativeStackSize + ((charAt == 'D' || charAt == 'J') ? 2 : 1);
|
|
|
|
break;
|
|
|
|
case Opcodes.PUTSTATIC /* 179 */:
|
|
|
|
i2 = this.relativeStackSize + ((charAt == 'D' || charAt == 'J') ? -2 : -1);
|
|
|
|
break;
|
|
|
|
case 180:
|
|
|
|
i2 = this.relativeStackSize + ((charAt == 'D' || charAt == 'J') ? 1 : 0);
|
|
|
|
break;
|
|
|
|
case Opcodes.PUTFIELD /* 181 */:
|
|
|
|
default:
|
|
|
|
i2 = this.relativeStackSize + ((charAt == 'D' || charAt == 'J') ? -3 : -2);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i2 > this.maxRelativeStackSize) {
|
|
|
|
this.maxRelativeStackSize = i2;
|
|
|
|
}
|
|
|
|
this.relativeStackSize = i2;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitMethodInsn(int i, String str, String str2, String str3, boolean z2) {
|
|
|
|
this.lastBytecodeOffset = this.code.length;
|
|
|
|
Symbol addConstantMethodref = this.symbolTable.addConstantMethodref(str, str2, str3, z2);
|
|
|
|
if (i == 185) {
|
|
|
|
this.code.put12(Opcodes.INVOKEINTERFACE, addConstantMethodref.index).put11(addConstantMethodref.getArgumentsAndReturnSizes() >> 2, 0);
|
|
|
|
} else {
|
|
|
|
this.code.put12(i, addConstantMethodref.index);
|
|
|
|
}
|
|
|
|
if (this.currentBasicBlock == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (this.compute == 4 || this.compute == 3) {
|
|
|
|
this.currentBasicBlock.frame.execute(i, 0, addConstantMethodref, this.symbolTable);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int argumentsAndReturnSizes = addConstantMethodref.getArgumentsAndReturnSizes();
|
|
|
|
int i2 = (argumentsAndReturnSizes & 3) - (argumentsAndReturnSizes >> 2);
|
|
|
|
int i3 = i == 184 ? this.relativeStackSize + i2 + 1 : this.relativeStackSize + i2;
|
|
|
|
if (i3 > this.maxRelativeStackSize) {
|
|
|
|
this.maxRelativeStackSize = i3;
|
|
|
|
}
|
|
|
|
this.relativeStackSize = i3;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitInvokeDynamicInsn(String str, String str2, Handle handle, Object... objArr) {
|
|
|
|
this.lastBytecodeOffset = this.code.length;
|
|
|
|
Symbol addConstantInvokeDynamic = this.symbolTable.addConstantInvokeDynamic(str, str2, handle, objArr);
|
|
|
|
this.code.put12(Opcodes.INVOKEDYNAMIC, addConstantInvokeDynamic.index);
|
|
|
|
this.code.putShort(0);
|
|
|
|
if (this.currentBasicBlock == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (this.compute == 4 || this.compute == 3) {
|
|
|
|
this.currentBasicBlock.frame.execute(Opcodes.INVOKEDYNAMIC, 0, addConstantInvokeDynamic, this.symbolTable);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int argumentsAndReturnSizes = addConstantInvokeDynamic.getArgumentsAndReturnSizes();
|
|
|
|
int i = this.relativeStackSize + ((argumentsAndReturnSizes & 3) - (argumentsAndReturnSizes >> 2)) + 1;
|
|
|
|
if (i > this.maxRelativeStackSize) {
|
|
|
|
this.maxRelativeStackSize = i;
|
|
|
|
}
|
|
|
|
this.relativeStackSize = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitJumpInsn(int i, Label label) {
|
|
|
|
this.lastBytecodeOffset = this.code.length;
|
|
|
|
int i2 = i >= 200 ? i - 33 : i;
|
|
|
|
boolean z2 = false;
|
|
|
|
if ((label.flags & 4) != 0 && label.bytecodeOffset - this.code.length < -32768) {
|
|
|
|
if (i2 == 167) {
|
|
|
|
this.code.putByte(200);
|
|
|
|
} else if (i2 == 168) {
|
|
|
|
this.code.putByte(201);
|
|
|
|
} else {
|
|
|
|
this.code.putByte(i2 >= 198 ? i2 ^ 1 : ((i2 + 1) ^ 1) - 1);
|
|
|
|
this.code.putShort(8);
|
|
|
|
this.code.putByte(220);
|
|
|
|
this.hasAsmInstructions = true;
|
|
|
|
z2 = true;
|
|
|
|
}
|
|
|
|
label.put(this.code, this.code.length - 1, true);
|
|
|
|
} else if (i2 != i) {
|
|
|
|
this.code.putByte(i);
|
|
|
|
label.put(this.code, this.code.length - 1, true);
|
|
|
|
} else {
|
|
|
|
this.code.putByte(i2);
|
|
|
|
label.put(this.code, this.code.length - 1, false);
|
|
|
|
}
|
|
|
|
if (this.currentBasicBlock != null) {
|
|
|
|
Label label2 = null;
|
|
|
|
if (this.compute == 4) {
|
|
|
|
this.currentBasicBlock.frame.execute(i2, 0, null, null);
|
|
|
|
Label canonicalInstance = label.getCanonicalInstance();
|
|
|
|
canonicalInstance.flags = (short) (canonicalInstance.flags | 2);
|
|
|
|
addSuccessorToCurrentBasicBlock(0, label);
|
|
|
|
if (i2 != 167) {
|
|
|
|
label2 = new Label();
|
|
|
|
}
|
|
|
|
} else if (this.compute == 3) {
|
|
|
|
this.currentBasicBlock.frame.execute(i2, 0, null, null);
|
|
|
|
} else if (this.compute == 2) {
|
|
|
|
this.relativeStackSize += STACK_SIZE_DELTA[i2];
|
|
|
|
} else if (i2 == 168) {
|
|
|
|
if ((label.flags & 32) == 0) {
|
|
|
|
label.flags = (short) (label.flags | 32);
|
|
|
|
this.hasSubroutines = true;
|
|
|
|
}
|
|
|
|
Label label3 = this.currentBasicBlock;
|
|
|
|
label3.flags = (short) (label3.flags | 16);
|
|
|
|
addSuccessorToCurrentBasicBlock(this.relativeStackSize + 1, label);
|
|
|
|
label2 = new Label();
|
|
|
|
} else {
|
|
|
|
this.relativeStackSize += STACK_SIZE_DELTA[i2];
|
|
|
|
addSuccessorToCurrentBasicBlock(this.relativeStackSize, label);
|
|
|
|
}
|
|
|
|
if (label2 != null) {
|
|
|
|
if (z2) {
|
|
|
|
label2.flags = (short) (label2.flags | 2);
|
|
|
|
}
|
|
|
|
visitLabel(label2);
|
|
|
|
}
|
|
|
|
if (i2 == 167) {
|
|
|
|
endCurrentBasicBlockWithNoSuccessor();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitLabel(Label label) {
|
|
|
|
this.hasAsmInstructions |= label.resolve(this.code.data, this.code.length);
|
|
|
|
if ((label.flags & 1) == 0) {
|
|
|
|
if (this.compute == 4) {
|
|
|
|
if (this.currentBasicBlock != null) {
|
|
|
|
if (label.bytecodeOffset == this.currentBasicBlock.bytecodeOffset) {
|
|
|
|
Label label2 = this.currentBasicBlock;
|
|
|
|
label2.flags = (short) (label2.flags | (label.flags & 2));
|
|
|
|
label.frame = this.currentBasicBlock.frame;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
addSuccessorToCurrentBasicBlock(0, label);
|
|
|
|
}
|
|
|
|
if (this.lastBasicBlock != null) {
|
|
|
|
if (label.bytecodeOffset == this.lastBasicBlock.bytecodeOffset) {
|
|
|
|
Label label3 = this.lastBasicBlock;
|
|
|
|
label3.flags = (short) (label3.flags | (label.flags & 2));
|
|
|
|
label.frame = this.lastBasicBlock.frame;
|
|
|
|
this.currentBasicBlock = this.lastBasicBlock;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.lastBasicBlock.nextBasicBlock = label;
|
|
|
|
}
|
|
|
|
this.lastBasicBlock = label;
|
|
|
|
this.currentBasicBlock = label;
|
|
|
|
label.frame = new Frame(label);
|
|
|
|
} else if (this.compute == 3) {
|
|
|
|
if (this.currentBasicBlock == null) {
|
|
|
|
this.currentBasicBlock = label;
|
|
|
|
} else {
|
|
|
|
this.currentBasicBlock.frame.owner = label;
|
|
|
|
}
|
|
|
|
} else if (this.compute == 1) {
|
|
|
|
if (this.currentBasicBlock != null) {
|
|
|
|
this.currentBasicBlock.outputStackMax = (short) this.maxRelativeStackSize;
|
|
|
|
addSuccessorToCurrentBasicBlock(this.relativeStackSize, label);
|
|
|
|
}
|
|
|
|
this.currentBasicBlock = label;
|
|
|
|
this.relativeStackSize = 0;
|
|
|
|
this.maxRelativeStackSize = 0;
|
|
|
|
if (this.lastBasicBlock != null) {
|
|
|
|
this.lastBasicBlock.nextBasicBlock = label;
|
|
|
|
}
|
|
|
|
this.lastBasicBlock = label;
|
|
|
|
} else if (this.compute == 2 && this.currentBasicBlock == null) {
|
|
|
|
this.currentBasicBlock = label;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitLdcInsn(Object obj) {
|
|
|
|
char charAt;
|
|
|
|
this.lastBytecodeOffset = this.code.length;
|
|
|
|
Symbol addConstant = this.symbolTable.addConstant(obj);
|
|
|
|
int i = addConstant.index;
|
|
|
|
boolean z2 = addConstant.tag == 5 || addConstant.tag == 6 || (addConstant.tag == 17 && ((charAt = addConstant.value.charAt(0)) == 'J' || charAt == 'D'));
|
|
|
|
if (z2) {
|
|
|
|
this.code.put12(20, i);
|
|
|
|
} else if (i >= 256) {
|
|
|
|
this.code.put12(19, i);
|
|
|
|
} else {
|
|
|
|
this.code.put11(18, i);
|
|
|
|
}
|
|
|
|
if (this.currentBasicBlock == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (this.compute == 4 || this.compute == 3) {
|
|
|
|
this.currentBasicBlock.frame.execute(18, 0, addConstant, this.symbolTable);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int i2 = this.relativeStackSize + (z2 ? 2 : 1);
|
|
|
|
if (i2 > this.maxRelativeStackSize) {
|
|
|
|
this.maxRelativeStackSize = i2;
|
|
|
|
}
|
|
|
|
this.relativeStackSize = i2;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitIincInsn(int i, int i2) {
|
|
|
|
int i3;
|
|
|
|
this.lastBytecodeOffset = this.code.length;
|
|
|
|
if (i > 255 || i2 > 127 || i2 < -128) {
|
|
|
|
this.code.putByte(196).put12(Opcodes.IINC, i).putShort(i2);
|
|
|
|
} else {
|
|
|
|
this.code.putByte(Opcodes.IINC).put11(i, i2);
|
|
|
|
}
|
|
|
|
if (this.currentBasicBlock != null && (this.compute == 4 || this.compute == 3)) {
|
|
|
|
this.currentBasicBlock.frame.execute(Opcodes.IINC, i, null, null);
|
|
|
|
}
|
|
|
|
if (this.compute != 0 && (i3 = i + 1) > this.maxLocals) {
|
|
|
|
this.maxLocals = i3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitTableSwitchInsn(int i, int i2, Label label, Label... labelArr) {
|
|
|
|
this.lastBytecodeOffset = this.code.length;
|
|
|
|
this.code.putByte(Opcodes.TABLESWITCH).putByteArray(null, 0, (4 - (this.code.length % 4)) % 4);
|
|
|
|
label.put(this.code, this.lastBytecodeOffset, true);
|
|
|
|
this.code.putInt(i).putInt(i2);
|
|
|
|
for (Label label2 : labelArr) {
|
|
|
|
label2.put(this.code, this.lastBytecodeOffset, true);
|
|
|
|
}
|
|
|
|
visitSwitchInsn(label, labelArr);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitLookupSwitchInsn(Label label, int[] iArr, Label[] labelArr) {
|
|
|
|
this.lastBytecodeOffset = this.code.length;
|
|
|
|
this.code.putByte(Opcodes.LOOKUPSWITCH).putByteArray(null, 0, (4 - (this.code.length % 4)) % 4);
|
|
|
|
label.put(this.code, this.lastBytecodeOffset, true);
|
|
|
|
this.code.putInt(labelArr.length);
|
|
|
|
for (int i = 0; i < labelArr.length; i++) {
|
|
|
|
this.code.putInt(iArr[i]);
|
|
|
|
labelArr[i].put(this.code, this.lastBytecodeOffset, true);
|
|
|
|
}
|
|
|
|
visitSwitchInsn(label, labelArr);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void visitSwitchInsn(Label label, Label[] labelArr) {
|
|
|
|
if (this.currentBasicBlock != null) {
|
|
|
|
if (this.compute == 4) {
|
|
|
|
this.currentBasicBlock.frame.execute(Opcodes.LOOKUPSWITCH, 0, null, null);
|
|
|
|
addSuccessorToCurrentBasicBlock(0, label);
|
|
|
|
Label canonicalInstance = label.getCanonicalInstance();
|
|
|
|
canonicalInstance.flags = (short) (canonicalInstance.flags | 2);
|
|
|
|
for (Label label2 : labelArr) {
|
|
|
|
addSuccessorToCurrentBasicBlock(0, label2);
|
|
|
|
Label canonicalInstance2 = label2.getCanonicalInstance();
|
|
|
|
canonicalInstance2.flags = (short) (canonicalInstance2.flags | 2);
|
|
|
|
}
|
|
|
|
} else if (this.compute == 1) {
|
|
|
|
this.relativeStackSize--;
|
|
|
|
addSuccessorToCurrentBasicBlock(this.relativeStackSize, label);
|
|
|
|
for (Label label3 : labelArr) {
|
|
|
|
addSuccessorToCurrentBasicBlock(this.relativeStackSize, label3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
endCurrentBasicBlockWithNoSuccessor();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitMultiANewArrayInsn(String str, int i) {
|
|
|
|
this.lastBytecodeOffset = this.code.length;
|
|
|
|
Symbol addConstantClass = this.symbolTable.addConstantClass(str);
|
|
|
|
this.code.put12(Opcodes.MULTIANEWARRAY, addConstantClass.index).putByte(i);
|
|
|
|
if (this.currentBasicBlock == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (this.compute == 4 || this.compute == 3) {
|
|
|
|
this.currentBasicBlock.frame.execute(Opcodes.MULTIANEWARRAY, i, addConstantClass, this.symbolTable);
|
|
|
|
} else {
|
|
|
|
this.relativeStackSize += 1 - i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public AnnotationVisitor visitInsnAnnotation(int i, TypePath typePath, String str, boolean z2) {
|
|
|
|
if (z2) {
|
|
|
|
AnnotationWriter create = AnnotationWriter.create(this.symbolTable, (i & (-16776961)) | (this.lastBytecodeOffset << 8), typePath, str, this.lastCodeRuntimeVisibleTypeAnnotation);
|
|
|
|
this.lastCodeRuntimeVisibleTypeAnnotation = create;
|
|
|
|
return create;
|
|
|
|
}
|
|
|
|
AnnotationWriter create2 = AnnotationWriter.create(this.symbolTable, (i & (-16776961)) | (this.lastBytecodeOffset << 8), typePath, str, this.lastCodeRuntimeInvisibleTypeAnnotation);
|
|
|
|
this.lastCodeRuntimeInvisibleTypeAnnotation = create2;
|
|
|
|
return create2;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitTryCatchBlock(Label label, Label label2, Label label3, String str) {
|
|
|
|
Handler handler = new Handler(label, label2, label3, str != null ? this.symbolTable.addConstantClass(str).index : 0, str);
|
|
|
|
if (this.firstHandler == null) {
|
|
|
|
this.firstHandler = handler;
|
|
|
|
} else {
|
|
|
|
this.lastHandler.nextHandler = handler;
|
|
|
|
}
|
|
|
|
this.lastHandler = handler;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public AnnotationVisitor visitTryCatchAnnotation(int i, TypePath typePath, String str, boolean z2) {
|
|
|
|
if (z2) {
|
|
|
|
AnnotationWriter create = AnnotationWriter.create(this.symbolTable, i, typePath, str, this.lastCodeRuntimeVisibleTypeAnnotation);
|
|
|
|
this.lastCodeRuntimeVisibleTypeAnnotation = create;
|
|
|
|
return create;
|
|
|
|
}
|
|
|
|
AnnotationWriter create2 = AnnotationWriter.create(this.symbolTable, i, typePath, str, this.lastCodeRuntimeInvisibleTypeAnnotation);
|
|
|
|
this.lastCodeRuntimeInvisibleTypeAnnotation = create2;
|
|
|
|
return create2;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitLocalVariable(String str, String str2, String str3, Label label, Label label2, int i) {
|
|
|
|
if (str3 != null) {
|
|
|
|
if (this.localVariableTypeTable == null) {
|
|
|
|
this.localVariableTypeTable = new ByteVector();
|
|
|
|
}
|
|
|
|
this.localVariableTypeTableLength++;
|
|
|
|
this.localVariableTypeTable.putShort(label.bytecodeOffset).putShort(label2.bytecodeOffset - label.bytecodeOffset).putShort(this.symbolTable.addConstantUtf8(str)).putShort(this.symbolTable.addConstantUtf8(str3)).putShort(i);
|
|
|
|
}
|
|
|
|
if (this.localVariableTable == null) {
|
|
|
|
this.localVariableTable = new ByteVector();
|
|
|
|
}
|
|
|
|
this.localVariableTableLength++;
|
|
|
|
this.localVariableTable.putShort(label.bytecodeOffset).putShort(label2.bytecodeOffset - label.bytecodeOffset).putShort(this.symbolTable.addConstantUtf8(str)).putShort(this.symbolTable.addConstantUtf8(str2)).putShort(i);
|
|
|
|
if (this.compute != 0) {
|
|
|
|
char charAt = str2.charAt(0);
|
|
|
|
int i2 = i + ((charAt == 'J' || charAt == 'D') ? 2 : 1);
|
|
|
|
if (i2 > this.maxLocals) {
|
|
|
|
this.maxLocals = i2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public AnnotationVisitor visitLocalVariableAnnotation(int i, TypePath typePath, Label[] labelArr, Label[] labelArr2, int[] iArr, String str, boolean z2) {
|
|
|
|
ByteVector byteVector = new ByteVector();
|
|
|
|
byteVector.putByte(i >>> 24).putShort(labelArr.length);
|
|
|
|
for (int i2 = 0; i2 < labelArr.length; i2++) {
|
|
|
|
byteVector.putShort(labelArr[i2].bytecodeOffset).putShort(labelArr2[i2].bytecodeOffset - labelArr[i2].bytecodeOffset).putShort(iArr[i2]);
|
|
|
|
}
|
|
|
|
TypePath.put(typePath, byteVector);
|
|
|
|
byteVector.putShort(this.symbolTable.addConstantUtf8(str)).putShort(0);
|
|
|
|
if (z2) {
|
|
|
|
AnnotationWriter annotationWriter = new AnnotationWriter(this.symbolTable, true, byteVector, this.lastCodeRuntimeVisibleTypeAnnotation);
|
|
|
|
this.lastCodeRuntimeVisibleTypeAnnotation = annotationWriter;
|
|
|
|
return annotationWriter;
|
|
|
|
}
|
|
|
|
AnnotationWriter annotationWriter2 = new AnnotationWriter(this.symbolTable, true, byteVector, this.lastCodeRuntimeInvisibleTypeAnnotation);
|
|
|
|
this.lastCodeRuntimeInvisibleTypeAnnotation = annotationWriter2;
|
|
|
|
return annotationWriter2;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitLineNumber(int i, Label label) {
|
|
|
|
if (this.lineNumberTable == null) {
|
|
|
|
this.lineNumberTable = new ByteVector();
|
|
|
|
}
|
|
|
|
this.lineNumberTableLength++;
|
|
|
|
this.lineNumberTable.putShort(label.bytecodeOffset);
|
|
|
|
this.lineNumberTable.putShort(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitMaxs(int i, int i2) {
|
|
|
|
if (this.compute == 4) {
|
|
|
|
computeAllFrames();
|
|
|
|
} else if (this.compute == 1) {
|
|
|
|
computeMaxStackAndLocal();
|
|
|
|
} else if (this.compute == 2) {
|
|
|
|
this.maxStack = this.maxRelativeStackSize;
|
|
|
|
} else {
|
|
|
|
this.maxStack = i;
|
|
|
|
this.maxLocals = i2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void computeAllFrames() {
|
|
|
|
for (Handler handler = this.firstHandler; handler != null; handler = handler.nextHandler) {
|
|
|
|
int abstractTypeFromInternalName = Frame.getAbstractTypeFromInternalName(this.symbolTable, handler.catchTypeDescriptor == null ? "java/lang/Throwable" : handler.catchTypeDescriptor);
|
|
|
|
Label canonicalInstance = handler.handlerPc.getCanonicalInstance();
|
|
|
|
canonicalInstance.flags = (short) (canonicalInstance.flags | 2);
|
|
|
|
Label canonicalInstance2 = handler.endPc.getCanonicalInstance();
|
|
|
|
for (Label canonicalInstance3 = handler.startPc.getCanonicalInstance(); canonicalInstance3 != canonicalInstance2; canonicalInstance3 = canonicalInstance3.nextBasicBlock) {
|
|
|
|
canonicalInstance3.outgoingEdges = new Edge(abstractTypeFromInternalName, canonicalInstance, canonicalInstance3.outgoingEdges);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Frame frame = this.firstBasicBlock.frame;
|
|
|
|
frame.setInputFrameFromDescriptor(this.symbolTable, this.accessFlags, this.descriptor, this.maxLocals);
|
|
|
|
frame.accept(this);
|
|
|
|
Label label = this.firstBasicBlock;
|
|
|
|
label.nextListElement = Label.EMPTY_LIST;
|
|
|
|
int i = 0;
|
|
|
|
while (label != Label.EMPTY_LIST) {
|
|
|
|
label = label.nextListElement;
|
|
|
|
label.nextListElement = null;
|
|
|
|
label.flags = (short) (label.flags | 8);
|
|
|
|
int inputStackSize = label.frame.getInputStackSize() + label.outputStackMax;
|
|
|
|
if (inputStackSize > i) {
|
|
|
|
i = inputStackSize;
|
|
|
|
}
|
|
|
|
for (Edge edge = label.outgoingEdges; edge != null; edge = edge.nextEdge) {
|
|
|
|
Label canonicalInstance4 = edge.successor.getCanonicalInstance();
|
|
|
|
if (label.frame.merge(this.symbolTable, canonicalInstance4.frame, edge.info) && canonicalInstance4.nextListElement == null) {
|
|
|
|
canonicalInstance4.nextListElement = label;
|
|
|
|
label = canonicalInstance4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (Label label2 = this.firstBasicBlock; label2 != null; label2 = label2.nextBasicBlock) {
|
|
|
|
if ((label2.flags & 10) == 10) {
|
|
|
|
label2.frame.accept(this);
|
|
|
|
}
|
|
|
|
if ((label2.flags & 8) == 0) {
|
|
|
|
Label label3 = label2.nextBasicBlock;
|
|
|
|
int i2 = label2.bytecodeOffset;
|
|
|
|
int i3 = (label3 == null ? this.code.length : label3.bytecodeOffset) - 1;
|
|
|
|
if (i3 >= i2) {
|
|
|
|
for (int i4 = i2; i4 < i3; i4++) {
|
|
|
|
this.code.data[i4] = 0;
|
|
|
|
}
|
|
|
|
this.code.data[i3] = -65;
|
|
|
|
this.currentFrame[visitFrameStart(i2, 0, 1)] = Frame.getAbstractTypeFromInternalName(this.symbolTable, "java/lang/Throwable");
|
|
|
|
visitFrameEnd();
|
|
|
|
this.firstHandler = Handler.removeRange(this.firstHandler, label2, label3);
|
|
|
|
i = Math.max(i, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.maxStack = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void computeMaxStackAndLocal() {
|
|
|
|
for (Handler handler = this.firstHandler; handler != null; handler = handler.nextHandler) {
|
|
|
|
Label label = handler.handlerPc;
|
|
|
|
Label label2 = handler.endPc;
|
|
|
|
for (Label label3 = handler.startPc; label3 != label2; label3 = label3.nextBasicBlock) {
|
|
|
|
if ((label3.flags & 16) == 0) {
|
|
|
|
label3.outgoingEdges = new Edge(Integer.MAX_VALUE, label, label3.outgoingEdges);
|
|
|
|
} else {
|
|
|
|
label3.outgoingEdges.nextEdge.nextEdge = new Edge(Integer.MAX_VALUE, label, label3.outgoingEdges.nextEdge.nextEdge);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (this.hasSubroutines) {
|
|
|
|
short s2 = 1;
|
|
|
|
this.firstBasicBlock.markSubroutine((short) 1);
|
|
|
|
for (short s3 = 1; s3 <= s2; s3 = (short) (s3 + 1)) {
|
|
|
|
for (Label label4 = this.firstBasicBlock; label4 != null; label4 = label4.nextBasicBlock) {
|
|
|
|
if ((label4.flags & 16) != 0 && label4.subroutineId == s3) {
|
|
|
|
Label label5 = label4.outgoingEdges.nextEdge.successor;
|
|
|
|
if (label5.subroutineId == 0) {
|
|
|
|
s2 = (short) (s2 + 1);
|
|
|
|
label5.markSubroutine(s2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (Label label6 = this.firstBasicBlock; label6 != null; label6 = label6.nextBasicBlock) {
|
|
|
|
if ((label6.flags & 16) != 0) {
|
|
|
|
label6.outgoingEdges.nextEdge.successor.addSubroutineRetSuccessors(label6);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Label label7 = this.firstBasicBlock;
|
|
|
|
label7.nextListElement = Label.EMPTY_LIST;
|
|
|
|
int i = this.maxStack;
|
|
|
|
while (label7 != Label.EMPTY_LIST) {
|
|
|
|
label7 = label7.nextListElement;
|
|
|
|
short s4 = label7.inputStackSize;
|
|
|
|
int i2 = s4 + label7.outputStackMax;
|
|
|
|
if (i2 > i) {
|
|
|
|
i = i2;
|
|
|
|
}
|
|
|
|
Edge edge = label7.outgoingEdges;
|
|
|
|
if ((label7.flags & 16) != 0) {
|
|
|
|
edge = edge.nextEdge;
|
|
|
|
}
|
|
|
|
while (edge != null) {
|
|
|
|
Label label8 = edge.successor;
|
|
|
|
if (label8.nextListElement == null) {
|
|
|
|
label8.inputStackSize = (short) (edge.info == Integer.MAX_VALUE ? 1 : s4 + edge.info);
|
|
|
|
label8.nextListElement = label7;
|
|
|
|
label7 = label8;
|
|
|
|
}
|
|
|
|
edge = edge.nextEdge;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.maxStack = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.objectweb.asm.MethodVisitor
|
|
|
|
public void visitEnd() {
|
|
|
|
}
|
|
|
|
|
|
|
|
private void addSuccessorToCurrentBasicBlock(int i, Label label) {
|
|
|
|
this.currentBasicBlock.outgoingEdges = new Edge(i, label, this.currentBasicBlock.outgoingEdges);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void endCurrentBasicBlockWithNoSuccessor() {
|
|
|
|
if (this.compute == 4) {
|
|
|
|
Label label = new Label();
|
|
|
|
label.frame = new Frame(label);
|
|
|
|
label.resolve(this.code.data, this.code.length);
|
|
|
|
this.lastBasicBlock.nextBasicBlock = label;
|
|
|
|
this.lastBasicBlock = label;
|
|
|
|
this.currentBasicBlock = null;
|
|
|
|
} else if (this.compute == 1) {
|
|
|
|
this.currentBasicBlock.outputStackMax = (short) this.maxRelativeStackSize;
|
|
|
|
this.currentBasicBlock = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int visitFrameStart(int i, int i2, int i3) {
|
|
|
|
int i4 = 3 + i2 + i3;
|
|
|
|
if (this.currentFrame == null || this.currentFrame.length < i4) {
|
|
|
|
this.currentFrame = new int[i4];
|
|
|
|
}
|
|
|
|
this.currentFrame[0] = i;
|
|
|
|
this.currentFrame[1] = i2;
|
|
|
|
this.currentFrame[2] = i3;
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
void visitAbstractType(int i, int i2) {
|
|
|
|
this.currentFrame[i] = i2;
|
|
|
|
}
|
|
|
|
|
|
|
|
void visitFrameEnd() {
|
|
|
|
if (this.previousFrame != null) {
|
|
|
|
if (this.stackMapTableEntries == null) {
|
|
|
|
this.stackMapTableEntries = new ByteVector();
|
|
|
|
}
|
|
|
|
putFrame();
|
|
|
|
this.stackMapTableNumberOfEntries++;
|
|
|
|
}
|
|
|
|
this.previousFrame = this.currentFrame;
|
|
|
|
this.currentFrame = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void putFrame() {
|
|
|
|
int i = this.currentFrame[1];
|
|
|
|
int i2 = this.currentFrame[2];
|
|
|
|
if (this.symbolTable.getMajorVersion() < 50) {
|
|
|
|
this.stackMapTableEntries.putShort(this.currentFrame[0]).putShort(i);
|
|
|
|
putAbstractTypes(3, 3 + i);
|
|
|
|
this.stackMapTableEntries.putShort(i2);
|
|
|
|
putAbstractTypes(3 + i, 3 + i + i2);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int i3 = this.stackMapTableNumberOfEntries == 0 ? this.currentFrame[0] : (this.currentFrame[0] - this.previousFrame[0]) - 1;
|
|
|
|
int i4 = this.previousFrame[1];
|
|
|
|
int i5 = i - i4;
|
|
|
|
char c = 255;
|
|
|
|
if (i2 == 0) {
|
|
|
|
switch (i5) {
|
|
|
|
case -3:
|
|
|
|
case -2:
|
|
|
|
case -1:
|
|
|
|
c = 248;
|
|
|
|
break;
|
|
|
|
case 0:
|
|
|
|
c = i3 < 64 ? (char) 0 : (char) 251;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
case 3:
|
|
|
|
c = 252;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (i5 == 0 && i2 == 1) {
|
|
|
|
c = i3 < 63 ? MentionUtilsKt.MENTIONS_CHAR : (char) 247;
|
|
|
|
}
|
|
|
|
if (c != 255) {
|
|
|
|
int i6 = 3;
|
|
|
|
int i7 = 0;
|
|
|
|
while (true) {
|
|
|
|
if (i7 < i4 && i7 < i) {
|
|
|
|
if (this.currentFrame[i6] != this.previousFrame[i6]) {
|
|
|
|
c = 255;
|
|
|
|
} else {
|
|
|
|
i6++;
|
|
|
|
i7++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch (c) {
|
|
|
|
case 0:
|
|
|
|
this.stackMapTableEntries.putByte(i3);
|
|
|
|
return;
|
|
|
|
case '@':
|
|
|
|
this.stackMapTableEntries.putByte(64 + i3);
|
|
|
|
putAbstractTypes(3 + i, 4 + i);
|
|
|
|
return;
|
|
|
|
case 247:
|
|
|
|
this.stackMapTableEntries.putByte(247).putShort(i3);
|
|
|
|
putAbstractTypes(3 + i, 4 + i);
|
|
|
|
return;
|
|
|
|
case 248:
|
|
|
|
this.stackMapTableEntries.putByte(251 + i5).putShort(i3);
|
|
|
|
return;
|
|
|
|
case 251:
|
|
|
|
this.stackMapTableEntries.putByte(251).putShort(i3);
|
|
|
|
return;
|
|
|
|
case 252:
|
|
|
|
this.stackMapTableEntries.putByte(251 + i5).putShort(i3);
|
|
|
|
putAbstractTypes(3 + i4, 3 + i);
|
|
|
|
return;
|
|
|
|
case 255:
|
|
|
|
default:
|
|
|
|
this.stackMapTableEntries.putByte(255).putShort(i3).putShort(i);
|
|
|
|
putAbstractTypes(3, 3 + i);
|
|
|
|
this.stackMapTableEntries.putShort(i2);
|
|
|
|
putAbstractTypes(3 + i, 3 + i + i2);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void putAbstractTypes(int i, int i2) {
|
|
|
|
for (int i3 = i; i3 < i2; i3++) {
|
|
|
|
Frame.putAbstractType(this.symbolTable, this.currentFrame[i3], this.stackMapTableEntries);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void putFrameType(Object obj) {
|
|
|
|
if (obj instanceof Integer) {
|
|
|
|
this.stackMapTableEntries.putByte(((Integer) obj).intValue());
|
|
|
|
} else if (obj instanceof String) {
|
|
|
|
this.stackMapTableEntries.putByte(7).putShort(this.symbolTable.addConstantClass((String) obj).index);
|
|
|
|
} else {
|
|
|
|
this.stackMapTableEntries.putByte(8).putShort(((Label) obj).bytecodeOffset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
boolean canCopyMethodAttributes(ClassReader classReader, boolean z2, boolean z3, int i, int i2, int i3) {
|
|
|
|
if (!(classReader == this.symbolTable.getSource() && i == this.descriptorIndex && i2 == this.signatureIndex)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (z3 != ((this.accessFlags & 131072) != 0)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (z2 != (this.symbolTable.getMajorVersion() < 49 && (this.accessFlags & 4096) != 0)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (i3 == 0) {
|
|
|
|
return this.numberOfExceptions == 0;
|
|
|
|
}
|
|
|
|
if (classReader.readUnsignedShort(i3) != this.numberOfExceptions) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
int i4 = i3 + 2;
|
|
|
|
for (int i5 = 0; i5 < this.numberOfExceptions; i5++) {
|
|
|
|
if (classReader.readUnsignedShort(i4) != this.exceptionIndexTable[i5]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
i4 += 2;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setMethodAttributesSource(int i, int i2) {
|
|
|
|
this.sourceOffset = i + 6;
|
|
|
|
this.sourceLength = i2 - 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
int computeMethodInfoSize() {
|
|
|
|
if (this.sourceOffset != 0) {
|
|
|
|
return 6 + this.sourceLength;
|
|
|
|
}
|
|
|
|
int i = 8;
|
|
|
|
if (this.code.length > 0) {
|
|
|
|
if (this.code.length > 65535) {
|
|
|
|
throw new MethodTooLargeException(this.symbolTable.getClassName(), this.name, this.descriptor, this.code.length);
|
|
|
|
}
|
|
|
|
this.symbolTable.addConstantUtf8("Code");
|
|
|
|
i = 8 + 16 + this.code.length + Handler.getExceptionTableSize(this.firstHandler);
|
|
|
|
if (this.stackMapTableEntries != null) {
|
|
|
|
this.symbolTable.addConstantUtf8(this.symbolTable.getMajorVersion() >= 50 ? "StackMapTable" : "StackMap");
|
|
|
|
i += 8 + this.stackMapTableEntries.length;
|
|
|
|
}
|
|
|
|
if (this.lineNumberTable != null) {
|
|
|
|
this.symbolTable.addConstantUtf8("LineNumberTable");
|
|
|
|
i += 8 + this.lineNumberTable.length;
|
|
|
|
}
|
|
|
|
if (this.localVariableTable != null) {
|
|
|
|
this.symbolTable.addConstantUtf8("LocalVariableTable");
|
|
|
|
i += 8 + this.localVariableTable.length;
|
|
|
|
}
|
|
|
|
if (this.localVariableTypeTable != null) {
|
|
|
|
this.symbolTable.addConstantUtf8("LocalVariableTypeTable");
|
|
|
|
i += 8 + this.localVariableTypeTable.length;
|
|
|
|
}
|
|
|
|
if (this.lastCodeRuntimeVisibleTypeAnnotation != null) {
|
|
|
|
i += this.lastCodeRuntimeVisibleTypeAnnotation.computeAnnotationsSize("RuntimeVisibleTypeAnnotations");
|
|
|
|
}
|
|
|
|
if (this.lastCodeRuntimeInvisibleTypeAnnotation != null) {
|
|
|
|
i += this.lastCodeRuntimeInvisibleTypeAnnotation.computeAnnotationsSize("RuntimeInvisibleTypeAnnotations");
|
|
|
|
}
|
|
|
|
if (this.firstCodeAttribute != null) {
|
|
|
|
i += this.firstCodeAttribute.computeAttributesSize(this.symbolTable, this.code.data, this.code.length, this.maxStack, this.maxLocals);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (this.numberOfExceptions > 0) {
|
|
|
|
this.symbolTable.addConstantUtf8("Exceptions");
|
|
|
|
i += 8 + (2 * this.numberOfExceptions);
|
|
|
|
}
|
|
|
|
int computeAttributesSize = i + Attribute.computeAttributesSize(this.symbolTable, this.accessFlags, this.signatureIndex) + AnnotationWriter.computeAnnotationsSize(this.lastRuntimeVisibleAnnotation, this.lastRuntimeInvisibleAnnotation, this.lastRuntimeVisibleTypeAnnotation, this.lastRuntimeInvisibleTypeAnnotation);
|
|
|
|
if (this.lastRuntimeVisibleParameterAnnotations != null) {
|
|
|
|
computeAttributesSize += AnnotationWriter.computeParameterAnnotationsSize("RuntimeVisibleParameterAnnotations", this.lastRuntimeVisibleParameterAnnotations, this.visibleAnnotableParameterCount == 0 ? this.lastRuntimeVisibleParameterAnnotations.length : this.visibleAnnotableParameterCount);
|
|
|
|
}
|
|
|
|
if (this.lastRuntimeInvisibleParameterAnnotations != null) {
|
|
|
|
computeAttributesSize += AnnotationWriter.computeParameterAnnotationsSize("RuntimeInvisibleParameterAnnotations", this.lastRuntimeInvisibleParameterAnnotations, this.invisibleAnnotableParameterCount == 0 ? this.lastRuntimeInvisibleParameterAnnotations.length : this.invisibleAnnotableParameterCount);
|
|
|
|
}
|
|
|
|
if (this.defaultValue != null) {
|
|
|
|
this.symbolTable.addConstantUtf8("AnnotationDefault");
|
|
|
|
computeAttributesSize += 6 + this.defaultValue.length;
|
|
|
|
}
|
|
|
|
if (this.parameters != null) {
|
|
|
|
this.symbolTable.addConstantUtf8("MethodParameters");
|
|
|
|
computeAttributesSize += 7 + this.parameters.length;
|
|
|
|
}
|
|
|
|
if (this.firstAttribute != null) {
|
|
|
|
computeAttributesSize += this.firstAttribute.computeAttributesSize(this.symbolTable);
|
|
|
|
}
|
|
|
|
return computeAttributesSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
void putMethodInfo(ByteVector byteVector) {
|
|
|
|
boolean z2 = this.symbolTable.getMajorVersion() < 49;
|
|
|
|
byteVector.putShort(this.accessFlags & ((z2 ? 4096 : 0) ^ (-1))).putShort(this.nameIndex).putShort(this.descriptorIndex);
|
|
|
|
if (this.sourceOffset != 0) {
|
|
|
|
byteVector.putByteArray(this.symbolTable.getSource().classFileBuffer, this.sourceOffset, this.sourceLength);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int i = 0;
|
|
|
|
if (this.code.length > 0) {
|
|
|
|
i = 0 + 1;
|
|
|
|
}
|
|
|
|
if (this.numberOfExceptions > 0) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if ((this.accessFlags & 4096) != 0 && z2) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (this.signatureIndex != 0) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if ((this.accessFlags & 131072) != 0) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (this.lastRuntimeVisibleAnnotation != null) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (this.lastRuntimeInvisibleAnnotation != null) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (this.lastRuntimeVisibleParameterAnnotations != null) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (this.lastRuntimeInvisibleParameterAnnotations != null) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (this.lastRuntimeVisibleTypeAnnotation != null) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (this.lastRuntimeInvisibleTypeAnnotation != null) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (this.defaultValue != null) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (this.parameters != null) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (this.firstAttribute != null) {
|
|
|
|
i += this.firstAttribute.getAttributeCount();
|
|
|
|
}
|
|
|
|
byteVector.putShort(i);
|
|
|
|
if (this.code.length > 0) {
|
|
|
|
int exceptionTableSize = 10 + this.code.length + Handler.getExceptionTableSize(this.firstHandler);
|
|
|
|
int i2 = 0;
|
|
|
|
if (this.stackMapTableEntries != null) {
|
|
|
|
exceptionTableSize += 8 + this.stackMapTableEntries.length;
|
|
|
|
i2 = 0 + 1;
|
|
|
|
}
|
|
|
|
if (this.lineNumberTable != null) {
|
|
|
|
exceptionTableSize += 8 + this.lineNumberTable.length;
|
|
|
|
i2++;
|
|
|
|
}
|
|
|
|
if (this.localVariableTable != null) {
|
|
|
|
exceptionTableSize += 8 + this.localVariableTable.length;
|
|
|
|
i2++;
|
|
|
|
}
|
|
|
|
if (this.localVariableTypeTable != null) {
|
|
|
|
exceptionTableSize += 8 + this.localVariableTypeTable.length;
|
|
|
|
i2++;
|
|
|
|
}
|
|
|
|
if (this.lastCodeRuntimeVisibleTypeAnnotation != null) {
|
|
|
|
exceptionTableSize += this.lastCodeRuntimeVisibleTypeAnnotation.computeAnnotationsSize("RuntimeVisibleTypeAnnotations");
|
|
|
|
i2++;
|
|
|
|
}
|
|
|
|
if (this.lastCodeRuntimeInvisibleTypeAnnotation != null) {
|
|
|
|
exceptionTableSize += this.lastCodeRuntimeInvisibleTypeAnnotation.computeAnnotationsSize("RuntimeInvisibleTypeAnnotations");
|
|
|
|
i2++;
|
|
|
|
}
|
|
|
|
if (this.firstCodeAttribute != null) {
|
|
|
|
exceptionTableSize += this.firstCodeAttribute.computeAttributesSize(this.symbolTable, this.code.data, this.code.length, this.maxStack, this.maxLocals);
|
|
|
|
i2 += this.firstCodeAttribute.getAttributeCount();
|
|
|
|
}
|
|
|
|
byteVector.putShort(this.symbolTable.addConstantUtf8("Code")).putInt(exceptionTableSize).putShort(this.maxStack).putShort(this.maxLocals).putInt(this.code.length).putByteArray(this.code.data, 0, this.code.length);
|
|
|
|
Handler.putExceptionTable(this.firstHandler, byteVector);
|
|
|
|
byteVector.putShort(i2);
|
|
|
|
if (this.stackMapTableEntries != null) {
|
|
|
|
byteVector.putShort(this.symbolTable.addConstantUtf8(this.symbolTable.getMajorVersion() >= 50 ? "StackMapTable" : "StackMap")).putInt(2 + this.stackMapTableEntries.length).putShort(this.stackMapTableNumberOfEntries).putByteArray(this.stackMapTableEntries.data, 0, this.stackMapTableEntries.length);
|
|
|
|
}
|
|
|
|
if (this.lineNumberTable != null) {
|
|
|
|
byteVector.putShort(this.symbolTable.addConstantUtf8("LineNumberTable")).putInt(2 + this.lineNumberTable.length).putShort(this.lineNumberTableLength).putByteArray(this.lineNumberTable.data, 0, this.lineNumberTable.length);
|
|
|
|
}
|
|
|
|
if (this.localVariableTable != null) {
|
|
|
|
byteVector.putShort(this.symbolTable.addConstantUtf8("LocalVariableTable")).putInt(2 + this.localVariableTable.length).putShort(this.localVariableTableLength).putByteArray(this.localVariableTable.data, 0, this.localVariableTable.length);
|
|
|
|
}
|
|
|
|
if (this.localVariableTypeTable != null) {
|
|
|
|
byteVector.putShort(this.symbolTable.addConstantUtf8("LocalVariableTypeTable")).putInt(2 + this.localVariableTypeTable.length).putShort(this.localVariableTypeTableLength).putByteArray(this.localVariableTypeTable.data, 0, this.localVariableTypeTable.length);
|
|
|
|
}
|
|
|
|
if (this.lastCodeRuntimeVisibleTypeAnnotation != null) {
|
|
|
|
this.lastCodeRuntimeVisibleTypeAnnotation.putAnnotations(this.symbolTable.addConstantUtf8("RuntimeVisibleTypeAnnotations"), byteVector);
|
|
|
|
}
|
|
|
|
if (this.lastCodeRuntimeInvisibleTypeAnnotation != null) {
|
|
|
|
this.lastCodeRuntimeInvisibleTypeAnnotation.putAnnotations(this.symbolTable.addConstantUtf8("RuntimeInvisibleTypeAnnotations"), byteVector);
|
|
|
|
}
|
|
|
|
if (this.firstCodeAttribute != null) {
|
|
|
|
this.firstCodeAttribute.putAttributes(this.symbolTable, this.code.data, this.code.length, this.maxStack, this.maxLocals, byteVector);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (this.numberOfExceptions > 0) {
|
|
|
|
byteVector.putShort(this.symbolTable.addConstantUtf8("Exceptions")).putInt(2 + (2 * this.numberOfExceptions)).putShort(this.numberOfExceptions);
|
|
|
|
for (int i3 : this.exceptionIndexTable) {
|
|
|
|
byteVector.putShort(i3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Attribute.putAttributes(this.symbolTable, this.accessFlags, this.signatureIndex, byteVector);
|
|
|
|
AnnotationWriter.putAnnotations(this.symbolTable, this.lastRuntimeVisibleAnnotation, this.lastRuntimeInvisibleAnnotation, this.lastRuntimeVisibleTypeAnnotation, this.lastRuntimeInvisibleTypeAnnotation, byteVector);
|
|
|
|
if (this.lastRuntimeVisibleParameterAnnotations != null) {
|
|
|
|
AnnotationWriter.putParameterAnnotations(this.symbolTable.addConstantUtf8("RuntimeVisibleParameterAnnotations"), this.lastRuntimeVisibleParameterAnnotations, this.visibleAnnotableParameterCount == 0 ? this.lastRuntimeVisibleParameterAnnotations.length : this.visibleAnnotableParameterCount, byteVector);
|
|
|
|
}
|
|
|
|
if (this.lastRuntimeInvisibleParameterAnnotations != null) {
|
|
|
|
AnnotationWriter.putParameterAnnotations(this.symbolTable.addConstantUtf8("RuntimeInvisibleParameterAnnotations"), this.lastRuntimeInvisibleParameterAnnotations, this.invisibleAnnotableParameterCount == 0 ? this.lastRuntimeInvisibleParameterAnnotations.length : this.invisibleAnnotableParameterCount, byteVector);
|
|
|
|
}
|
|
|
|
if (this.defaultValue != null) {
|
|
|
|
byteVector.putShort(this.symbolTable.addConstantUtf8("AnnotationDefault")).putInt(this.defaultValue.length).putByteArray(this.defaultValue.data, 0, this.defaultValue.length);
|
|
|
|
}
|
|
|
|
if (this.parameters != null) {
|
|
|
|
byteVector.putShort(this.symbolTable.addConstantUtf8("MethodParameters")).putInt(1 + this.parameters.length).putByte(this.parametersCount).putByteArray(this.parameters.data, 0, this.parameters.length);
|
|
|
|
}
|
|
|
|
if (this.firstAttribute != null) {
|
|
|
|
this.firstAttribute.putAttributes(this.symbolTable, byteVector);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
final void collectAttributePrototypes(Attribute.Set set) {
|
|
|
|
set.addAttributes(this.firstAttribute);
|
|
|
|
set.addAttributes(this.firstCodeAttribute);
|
|
|
|
}
|
|
|
|
}
|