Skip to content

Commit 76b38b8

Browse files
authored
Improvement: Avoid reflection in Bytecode opcode name utils. (FabricMC#186)
1 parent 5250ed3 commit 76b38b8

File tree

1 file changed

+41
-47
lines changed

1 file changed

+41
-47
lines changed

src/main/java/org/spongepowered/asm/util/Bytecode.java

Lines changed: 41 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.objectweb.asm.Type;
4242
import org.objectweb.asm.tree.*;
4343
import org.objectweb.asm.util.CheckClassAdapter;
44+
import org.objectweb.asm.util.Printer;
4445
import org.objectweb.asm.util.TraceClassVisitor;
4546
import org.spongepowered.asm.util.asm.ASM;
4647
import org.spongepowered.asm.util.asm.MarkerNode;
@@ -464,7 +465,7 @@ public static String describeNode(AbstractInsnNode node, boolean listFormat) {
464465
} else if (node instanceof InvokeDynamicInsnNode) {
465466
InvokeDynamicInsnNode idc = (InvokeDynamicInsnNode)node;
466467
out += String.format("[%s] %s%s { %s %s::%s%s }", Bytecode.getOpcodeName(node), idc.name, idc.desc,
467-
Bytecode.getOpcodeName(idc.bsm.getTag(), "H_GETFIELD", 1), idc.bsm.getOwner(), idc.bsm.getName(), idc.bsm.getDesc());
468+
Bytecode.getOpcodeName(idc.bsm.getTag(), Printer.HANDLE_TAG), idc.bsm.getOwner(), idc.bsm.getName(), idc.bsm.getDesc());
468469
} else if (node instanceof LineNumberNode) {
469470
LineNumberNode ln = (LineNumberNode)node;
470471
out += String.format("LINE=[%d] LABEL=[%s]", ln.line, ln.start.getLabel());
@@ -473,7 +474,7 @@ public static String describeNode(AbstractInsnNode node, boolean listFormat) {
473474
} else if (node instanceof IntInsnNode) {
474475
out += (((IntInsnNode)node).operand);
475476
} else if (node instanceof FrameNode) {
476-
out += String.format("[%s] ", Bytecode.getOpcodeName(((FrameNode)node).type, "H_INVOKEINTERFACE", -1));
477+
out += String.format("[%s] ", getFrameTypeName((FrameNode) node));
477478
} else if (node instanceof TypeInsnNode) {
478479
out += String.format("[%s] %s", Bytecode.getOpcodeName(node), ((TypeInsnNode)node).desc);
479480
} else {
@@ -483,53 +484,56 @@ public static String describeNode(AbstractInsnNode node, boolean listFormat) {
483484
}
484485

485486
/**
486-
* Uses reflection to find an approximate constant name match for the
487-
* supplied node's opcode
487+
* Finds a constant name match for the supplied node's opcode
488488
*
489489
* @param node Node to query for opcode
490-
* @return Approximate opcode name (approximate because some constants in
491-
* the {@link Opcodes} class have the same value as opcodes
490+
* @return opcode name
492491
*/
493492
public static String getOpcodeName(AbstractInsnNode node) {
494493
return node != null ? Bytecode.getOpcodeName(node.getOpcode()) : "";
495494
}
496495

497496
/**
498-
* Uses reflection to find an approximate constant name match for the
499-
* supplied opcode
497+
* Finds a constant name match for the supplied node's opcode
500498
*
501499
* @param opcode Opcode to look up
502-
* @return Approximate opcode name (approximate because some constants in
503-
* the {@link Opcodes} class have the same value as opcodes
500+
* @return opcode name
504501
*/
505502
public static String getOpcodeName(int opcode) {
506-
return Bytecode.getOpcodeName(opcode, "UNINITIALIZED_THIS", 1);
503+
return Bytecode.getOpcodeName(opcode, Printer.OPCODES);
507504
}
508505

509-
private static String getOpcodeName(int opcode, String start, int min) {
510-
if (opcode >= min) {
511-
boolean found = false;
512-
513-
try {
514-
for (java.lang.reflect.Field f : Opcodes.class.getDeclaredFields()) {
515-
if (!found && !f.getName().equals(start)) {
516-
continue;
517-
}
518-
found = true;
519-
if (f.getType() == Integer.TYPE && f.getInt(null) == opcode) {
520-
return f.getName();
521-
}
522-
}
523-
} catch (Exception ex) {
524-
// derp
525-
}
526-
}
527-
528-
return opcode >= 0 ? String.valueOf(opcode) : "UNKNOWN";
506+
private static String getOpcodeName(int opcode, String[] names) {
507+
if (opcode < 0) {
508+
return "UNKNOWN";
509+
}
510+
if (opcode < names.length) {
511+
return names[opcode];
512+
}
513+
return String.valueOf(opcode);
514+
}
515+
516+
private static String getFrameTypeName(FrameNode node) {
517+
switch (node.type) {
518+
case Opcodes.F_NEW:
519+
return "F_NEW";
520+
case Opcodes.F_FULL:
521+
return "F_FULL";
522+
case Opcodes.F_APPEND:
523+
return "F_APPEND";
524+
case Opcodes.F_CHOP:
525+
return "F_CHOP";
526+
case Opcodes.F_SAME:
527+
return "F_SAME";
528+
case Opcodes.F_SAME1:
529+
return "F_SAME1";
530+
default:
531+
return "UNKNOWN";
532+
}
529533
}
530534

531535
/**
532-
* Uses reflection to find a matching constant in the {@link Opcodes}
536+
* Finds a matching constant in the {@link Opcodes}
533537
* interface for the specified opcode name. Supported formats are raw
534538
* numeric values, bare constant names (eg. <tt>ACONST_NULL</tt>) or
535539
* qualified names (eg. <tt>Opcodes.ACONST_NULL</tt>). Returns the value if
@@ -556,24 +560,14 @@ public static int parseOpcodeName(String opcodeName) {
556560
return -1;
557561
}
558562

559-
return Bytecode.parseOpcodeName(opcodeName, "UNINITIALIZED_THIS", 1);
563+
return Bytecode.parseOpcodeName(opcodeName, Printer.OPCODES);
560564
}
561565

562-
private static int parseOpcodeName(String opcodeName, String start, int min) {
563-
boolean found = false;
564-
565-
try {
566-
for (java.lang.reflect.Field f : Opcodes.class.getDeclaredFields()) {
567-
if (!found && !f.getName().equals(start)) {
568-
continue;
569-
}
570-
found = true;
571-
if (f.getType() == Integer.TYPE && f.getName().equalsIgnoreCase(opcodeName)) {
572-
return f.getInt(null);
573-
}
566+
private static int parseOpcodeName(String name, String[] names) {
567+
for (int i = 0; i < names.length; i++) {
568+
if (name.equalsIgnoreCase(names[i])) {
569+
return i;
574570
}
575-
} catch (Exception ex) {
576-
// well this is embarrassing
577571
}
578572

579573
return -1;

0 commit comments

Comments
 (0)