package org.apache.bcel.util;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.BitSet;
import org.apache.bcel.Const;
import org.apache.bcel.classfile.Attribute;
import org.apache.bcel.classfile.Code;
import org.apache.bcel.classfile.CodeException;
import org.apache.bcel.classfile.ConstantFieldref;
import org.apache.bcel.classfile.ConstantInterfaceMethodref;
import org.apache.bcel.classfile.ConstantInvokeDynamic;
import org.apache.bcel.classfile.ConstantMethodref;
import org.apache.bcel.classfile.ConstantNameAndType;
import org.apache.bcel.classfile.ConstantPool;
import org.apache.bcel.classfile.LocalVariableTable;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.classfile.Utility;
/* loaded from: org_apache_bcel_util.jar:org/apache/bcel/util/CodeHTML.class */
final class CodeHTML {
private static boolean wide;
private final String className;
private final PrintWriter printWriter;
private BitSet gotoSet;
private final ConstantPool constantPool;
private final ConstantHTML constantHtml;
/* JADX INFO: Access modifiers changed from: package-private */
public CodeHTML(String dir, String className, Method[] methods, ConstantPool constantPool, ConstantHTML constantHtml, Charset charset) throws IOException {
this.className = className;
this.constantPool = constantPool;
this.constantHtml = constantHtml;
PrintWriter newPrintWriter = new PrintWriter(dir + className + "_code.html", charset.name());
Throwable th = null;
try {
try {
this.printWriter = newPrintWriter;
this.printWriter.print("
");
this.printWriter.println("");
for (int i = 0; i < methods.length; i++) {
writeMethod(methods[i], i);
}
this.printWriter.println("");
if (newPrintWriter != null) {
if (0 != 0) {
try {
newPrintWriter.close();
return;
} catch (Throwable th2) {
th.addSuppressed(th2);
return;
}
}
newPrintWriter.close();
}
} catch (Throwable th3) {
th = th3;
throw th3;
}
} catch (Throwable th4) {
if (newPrintWriter != null) {
if (th != null) {
try {
newPrintWriter.close();
} catch (Throwable th5) {
th.addSuppressed(th5);
}
} else {
newPrintWriter.close();
}
}
throw th4;
}
}
private String codeToHTML(ByteSequence bytes, int methodNumber) throws IOException {
int vindex;
int constant;
int index;
String name;
int vindex2;
short opcode = (short) bytes.readUnsignedByte();
int defaultOffset = 0;
int noPadBytes = 0;
StringBuilder buf = new StringBuilder(256);
buf.append("").append(Const.getOpcodeName(opcode)).append("");
if (opcode == 170 || opcode == 171) {
int remainder = bytes.getIndex() % 4;
noPadBytes = remainder == 0 ? 0 : 4 - remainder;
for (int i = 0; i < noPadBytes; i++) {
bytes.readByte();
}
defaultOffset = bytes.readInt();
}
switch (opcode) {
case 18:
int index2 = bytes.readUnsignedByte();
buf.append("").append(Class2HTML.toHTML(this.constantPool.constantToString(index2, this.constantPool.getConstant(index2).getTag()))).append("");
break;
case 19:
case 20:
int index3 = bytes.readShort();
buf.append("").append(Class2HTML.toHTML(this.constantPool.constantToString(index3, this.constantPool.getConstant(index3).getTag()))).append("");
break;
case 21:
case 22:
case 23:
case 24:
case 25:
case 54:
case 55:
case 56:
case 57:
case 58:
case 169:
if (wide) {
vindex2 = bytes.readShort();
wide = false;
} else {
vindex2 = bytes.readUnsignedByte();
}
buf.append("%").append(vindex2);
break;
case 26:
case 27:
case 28:
case 29:
case 30:
case 31:
case 32:
case 33:
case 34:
case 35:
case 36:
case 37:
case 38:
case 39:
case 40:
case 41:
case 42:
case 43:
case 44:
case 45:
case 46:
case 47:
case 48:
case 49:
case 50:
case 51:
case 52:
case 53:
case 59:
case 60:
case 61:
case 62:
case 63:
case 64:
case 65:
case 66:
case 67:
case 68:
case 69:
case 70:
case 71:
case 72:
case 73:
case 74:
case 75:
case 76:
case 77:
case 78:
case 79:
case 80:
case 81:
case 82:
case 83:
case 84:
case 85:
case 86:
case 87:
case 88:
case 89:
case 90:
case 91:
case 92:
case 93:
case 94:
case 95:
case 96:
case 97:
case 98:
case 99:
case 100:
case 101:
case 102:
case 103:
case 104:
case 105:
case 106:
case 107:
case 108:
case 109:
case 110:
case 111:
case 112:
case 113:
case 114:
case 115:
case 116:
case 117:
case 118:
case 119:
case 120:
case 121:
case 122:
case 123:
case 124:
case 125:
case 126:
case 127:
case 128:
case 129:
case 130:
case 131:
case 133:
case 134:
case 135:
case 136:
case 137:
case 138:
case 139:
case 140:
case 141:
case 142:
case 143:
case 144:
case 145:
case 146:
case 147:
case 148:
case 149:
case 150:
case 151:
case 152:
case 172:
case 173:
case 174:
case 175:
case 176:
case 177:
case 190:
case 191:
case 194:
case 195:
default:
if (Const.getNoOfOperands(opcode) > 0) {
for (int i2 = 0; i2 < Const.getOperandTypeCount(opcode); i2++) {
switch (Const.getOperandType(opcode, i2)) {
case 8:
buf.append(bytes.readUnsignedByte());
break;
case 9:
buf.append((int) bytes.readShort());
break;
case 10:
buf.append(bytes.readInt());
break;
default:
throw new IllegalStateException("Unreachable default case reached! " + ((int) Const.getOperandType(opcode, i2)));
}
buf.append(" ");
}
break;
}
break;
case 132:
if (wide) {
vindex = bytes.readShort();
constant = bytes.readShort();
wide = false;
} else {
vindex = bytes.readUnsignedByte();
constant = bytes.readByte();
}
buf.append("%").append(vindex).append(" ").append(constant);
break;
case 153:
case 154:
case 155:
case 156:
case 157:
case 158:
case 159:
case 160:
case 161:
case 162:
case 163:
case 164:
case 165:
case 166:
case 167:
case 168:
case 198:
case 199:
int index4 = (bytes.getIndex() + bytes.readShort()) - 1;
buf.append("").append(index4).append("");
break;
case 170:
int low = bytes.readInt();
int high = bytes.readInt();
int offset = ((bytes.getIndex() - 12) - noPadBytes) - 1;
int defaultOffset2 = defaultOffset + offset;
buf.append("");
int[] jumpTable = new int[(high - low) + 1];
for (int i3 = 0; i3 < jumpTable.length; i3++) {
jumpTable[i3] = offset + bytes.readInt();
buf.append("").append(low + i3).append(" | ");
}
buf.append("default | \n");
for (int element : jumpTable) {
buf.append("").append(element).append(" | ");
}
buf.append("").append(defaultOffset2).append(" | \n \n");
break;
case 171:
int npairs = bytes.readInt();
int offset2 = ((bytes.getIndex() - 8) - noPadBytes) - 1;
int[] jumpTable2 = new int[npairs];
int defaultOffset3 = defaultOffset + offset2;
buf.append("\n");
break;
case 178:
case 179:
case 180:
case 181:
int index5 = bytes.readShort();
ConstantFieldref c1 = this.constantPool.getConstant(index5, (byte) 9, ConstantFieldref.class);
int classIndex = c1.getClassIndex();
String name2 = this.constantPool.getConstantString(classIndex, (byte) 7);
String name3 = Utility.compactClassName(name2, false);
int index6 = c1.getNameAndTypeIndex();
String fieldName = this.constantPool.constantToString(index6, (byte) 12);
if (name3.equals(this.className)) {
buf.append("").append(fieldName).append("\n");
break;
} else {
buf.append(this.constantHtml.referenceConstant(classIndex)).append(".").append(fieldName);
break;
}
case 182:
case 183:
case 184:
case 185:
case 186:
int mIndex = bytes.readShort();
if (opcode == 185) {
bytes.readUnsignedByte();
bytes.readUnsignedByte();
ConstantInterfaceMethodref c = this.constantPool.getConstant(mIndex, (byte) 11, ConstantInterfaceMethodref.class);
int classIndex2 = c.getClassIndex();
index = c.getNameAndTypeIndex();
name = Class2HTML.referenceClass(classIndex2);
} else if (opcode == 186) {
bytes.readUnsignedByte();
bytes.readUnsignedByte();
ConstantInvokeDynamic c2 = this.constantPool.getConstant(mIndex, (byte) 18, ConstantInvokeDynamic.class);
index = c2.getNameAndTypeIndex();
name = "#" + c2.getBootstrapMethodAttrIndex();
} else {
ConstantMethodref c3 = this.constantPool.getConstant(mIndex, (byte) 10, ConstantMethodref.class);
int classIndex3 = c3.getClassIndex();
index = c3.getNameAndTypeIndex();
name = Class2HTML.referenceClass(classIndex3);
}
String str = Class2HTML.toHTML(this.constantPool.constantToString(this.constantPool.getConstant(index, (byte) 12)));
ConstantNameAndType c22 = this.constantPool.getConstant(index, (byte) 12, ConstantNameAndType.class);
String signature = this.constantPool.constantToString(c22.getSignatureIndex(), (byte) 1);
String[] args = Utility.methodSignatureArgumentTypes(signature, false);
String type = Utility.methodSignatureReturnType(signature, false);
buf.append(name).append(".").append(str).append("").append("(");
for (int i6 = 0; i6 < args.length; i6++) {
buf.append(Class2HTML.referenceType(args[i6]));
if (i6 < args.length - 1) {
buf.append(", ");
}
}
buf.append("):").append(Class2HTML.referenceType(type));
break;
case 187:
case 192:
case 193:
int index7 = bytes.readShort();
buf.append(this.constantHtml.referenceConstant(index7));
break;
case 188:
buf.append("").append(Const.getTypeName(bytes.readByte())).append("");
break;
case 189:
int index8 = bytes.readShort();
buf.append(this.constantHtml.referenceConstant(index8));
break;
case 196:
wide = true;
buf.append("(wide)");
break;
case 197:
int index9 = bytes.readShort();
int dimensions = bytes.readByte();
buf.append(this.constantHtml.referenceConstant(index9)).append(":").append(dimensions).append("-dimensional");
break;
case 200:
case 201:
int windex = (bytes.getIndex() + bytes.readInt()) - 1;
buf.append("").append(windex).append("");
break;
}
buf.append(" | ");
return buf.toString();
}
private void findGotos(ByteSequence bytes, Code code) throws IOException {
this.gotoSet = new BitSet(bytes.available());
if (code != null) {
CodeException[] ce = code.getExceptionTable();
for (CodeException cex : ce) {
this.gotoSet.set(cex.getStartPC());
this.gotoSet.set(cex.getEndPC());
this.gotoSet.set(cex.getHandlerPC());
}
LocalVariableTable[] attributes = code.getAttributes();
int length = attributes.length;
int i = 0;
while (true) {
if (i >= length) {
break;
}
LocalVariableTable localVariableTable = attributes[i];
if (localVariableTable.getTag() != 5) {
i++;
} else {
localVariableTable.forEach(var -> {
int start = var.getStartPC();
this.gotoSet.set(start);
this.gotoSet.set(start + var.getLength());
});
break;
}
}
}
while (bytes.available() > 0) {
int opcode = bytes.readUnsignedByte();
switch (opcode) {
case 153:
case 154:
case 155:
case 156:
case 157:
case 158:
case 159:
case 160:
case 161:
case 162:
case 163:
case 164:
case 165:
case 166:
case 167:
case 168:
case 198:
case 199:
int index = (bytes.getIndex() + bytes.readShort()) - 1;
this.gotoSet.set(index);
break;
case 169:
case 172:
case 173:
case 174:
case 175:
case 176:
case 177:
case 178:
case 179:
case 180:
case 181:
case 182:
case 183:
case 184:
case 185:
case 186:
case 187:
case 188:
case 189:
case 190:
case 191:
case 192:
case 193:
case 194:
case 195:
case 196:
case 197:
default:
bytes.unreadByte();
codeToHTML(bytes, 0);
break;
case 170:
case 171:
int remainder = bytes.getIndex() % 4;
int noPadBytes = remainder == 0 ? 0 : 4 - remainder;
for (int j = 0; j < noPadBytes; j++) {
bytes.readByte();
}
int defaultOffset = bytes.readInt();
if (opcode == 170) {
int low = bytes.readInt();
int high = bytes.readInt();
int offset = ((bytes.getIndex() - 12) - noPadBytes) - 1;
this.gotoSet.set(defaultOffset + offset);
for (int j2 = 0; j2 < (high - low) + 1; j2++) {
int index2 = offset + bytes.readInt();
this.gotoSet.set(index2);
}
break;
} else {
int npairs = bytes.readInt();
int offset2 = ((bytes.getIndex() - 8) - noPadBytes) - 1;
this.gotoSet.set(defaultOffset + offset2);
for (int j3 = 0; j3 < npairs; j3++) {
bytes.readInt();
int index3 = offset2 + bytes.readInt();
this.gotoSet.set(index3);
}
break;
}
case 200:
case 201:
int index4 = (bytes.getIndex() + bytes.readInt()) - 1;
this.gotoSet.set(index4);
break;
}
}
}
private void writeMethod(Method method, int methodNumber) throws IOException {
String anchor2;
String signature = method.getSignature();
String[] args = Utility.methodSignatureArgumentTypes(signature, false);
String type = Utility.methodSignatureReturnType(signature, false);
String name = method.getName();
String htmlName = Class2HTML.toHTML(name);
String access = Utility.accessToString(method.getAccessFlags());
String access2 = Utility.replace(access, " ", " ");
Attribute[] attributes = method.getAttributes();
this.printWriter.print("" + access2 + " " + Class2HTML.referenceType(type) + " " + htmlName + "(");
for (int i = 0; i < args.length; i++) {
this.printWriter.print(Class2HTML.referenceType(args[i]));
if (i < args.length - 1) {
this.printWriter.print(", ");
}
}
this.printWriter.println(")
");
Code c = null;
byte[] code = null;
if (attributes.length > 0) {
this.printWriter.print("Attributes
\n");
for (int i2 = 0; i2 < attributes.length; i2++) {
byte tag = attributes[i2].getTag();
if (tag != -1) {
this.printWriter.print("- " + Const.getAttributeName(tag) + "
\n");
} else {
this.printWriter.print("- " + attributes[i2] + "
");
}
if (tag == 2) {
c = (Code) attributes[i2];
Attribute[] attributes2 = c.getAttributes();
code = c.getCode();
this.printWriter.print("");
}
}
this.printWriter.println("
");
}
if (code != null) {
ByteSequence stream = new ByteSequence(code);
Throwable th = null;
try {
try {
stream.mark(stream.available());
findGotos(stream, c);
stream.reset();
this.printWriter.println("Byte offset | Instruction | Argument | ");
while (stream.available() > 0) {
int offset = stream.getIndex();
String str = codeToHTML(stream, methodNumber);
String anchor = "";
if (this.gotoSet.get(offset)) {
anchor = "";
}
if (stream.getIndex() == code.length) {
anchor2 = "" + offset + "";
} else {
anchor2 = "" + offset;
}
this.printWriter.println("
---|
" + anchor2 + " | " + anchor + str + " |
");
}
if (stream != null) {
if (0 != 0) {
try {
stream.close();
} catch (Throwable th2) {
th.addSuppressed(th2);
}
} else {
stream.close();
}
}
this.printWriter.println(" |
");
this.printWriter.println("
");
} catch (Throwable th3) {
th = th3;
throw th3;
}
} catch (Throwable th4) {
if (stream != null) {
if (th != null) {
try {
stream.close();
} catch (Throwable th5) {
th.addSuppressed(th5);
}
} else {
stream.close();
}
}
throw th4;
}
}
}
}