下面列出了org.objectweb.asm.Opcodes# LOOKUPSWITCH 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public InsnValue getSwitchValue(AbstractInsnNode insn, InsnValue value) {
if (value.getValue() == null) {
return InsnValue.intValue(-1);
}
int i = (int) value.getValue();
switch (insn.getOpcode()) {
case Opcodes.TABLESWITCH:
TableSwitchInsnNode tsin = (TableSwitchInsnNode) insn;
if (i < tsin.min || i > tsin.max) {
return InsnValue.intValue(-1);
}
return InsnValue.intValue(i);
case Opcodes.LOOKUPSWITCH:
LookupSwitchInsnNode lsin = (LookupSwitchInsnNode) insn;
for (Object o : lsin.keys) {
if (o.equals(i)) {
return InsnValue.intValue(i);
}
}
return InsnValue.intValue(-1);
}
return null;
}
/**
* <p>
* This method finds Switch block in a method and processes it
* </p>.
*
* @param scanStartIndex Start index for the scan
* @param scanEndIndex End index for the scan
*/
private void instrumentswitchBlock(int scanStartIndex,
int scanEndIndex) {
for (scanIndexForswitch = scanStartIndex; scanIndexForswitch <= scanEndIndex; scanIndexForswitch++) {
AbstractInsnNode currentInsnNode = insnArr[scanIndexForswitch];
if (currentInsnNode instanceof TableSwitchInsnNode
&& Opcodes.TABLESWITCH == currentInsnNode.getOpcode()) {
processTableSwitchBlock((TableSwitchInsnNode) currentInsnNode);
} else if (currentInsnNode instanceof LookupSwitchInsnNode
&& Opcodes.LOOKUPSWITCH == currentInsnNode.getOpcode()) {
processLookupSwitchBlock((LookupSwitchInsnNode) currentInsnNode);
}
}
}
@Test
public void test_checkLookupSwitch() throws Exception {
List<BasicBlock> hashCodeBlocks = METHOD_BLOCKS.get("checkLookupSwitch(I)I");
int[][] expectedHashCodeBlocks = new int[][]{
{Opcodes.ICONST_5, Opcodes.ISTORE, Opcodes.ILOAD, Opcodes.LOOKUPSWITCH},
{Opcodes.ICONST_1, Opcodes.ISTORE, Opcodes.GOTO},
{Opcodes.ICONST_2, Opcodes.ISTORE, Opcodes.GOTO},
{Opcodes.ICONST_3, Opcodes.ISTORE, Opcodes.GOTO},
{Opcodes.ICONST_0, Opcodes.ISTORE},
{Opcodes.ILOAD, Opcodes.IRETURN},
};
int[][] expectedSwitchCounts = new int[][]{
{4},
{},
{},
{},
{},
{},
};
// Verify the shape of the blocks.
boolean didMatch = compareBlocks(expectedHashCodeBlocks, hashCodeBlocks);
Assert.assertTrue(didMatch);
// Verify the switch option value.
didMatch = compareSwitches(expectedSwitchCounts, hashCodeBlocks);
Assert.assertTrue(didMatch);
}
/**
* Constructs a new {@link LookupSwitchInsnNode}.
*
* @param dflt
* beginning of the default handler block.
* @param keys
* the values of the keys.
* @param labels
* beginnings of the handler blocks. <tt>labels[i]</tt> is the
* beginning of the handler block for the <tt>keys[i]</tt> key.
*/
public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys, final LabelNode[] labels) {
super(Opcodes.LOOKUPSWITCH);
this.dflt = dflt;
this.keys = new ArrayList<Integer>(keys == null ? 0 : keys.length);
this.labels = new ArrayList<LabelNode>(labels == null ? 0 : labels.length);
if (keys != null) {
for (int i = 0; i < keys.length; ++i) {
this.keys.add(keys[i]);
}
}
if (labels != null) {
this.labels.addAll(Arrays.asList(labels));
}
}
@Override
public final void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
AttributesImpl att = new AttributesImpl();
att.addAttribute("", "dflt", "dflt", "", getLabel(dflt));
String o = Printer.OPCODES[Opcodes.LOOKUPSWITCH];
sa.addStart(o, att);
for (int i = 0; i < labels.length; i++) {
AttributesImpl att2 = new AttributesImpl();
att2.addAttribute("", "name", "name", "", getLabel(labels[i]));
att2.addAttribute("", "key", "key", "", Integer.toString(keys[i]));
sa.addElement("label", att2);
}
sa.addEnd(o);
}
public LookupSwitchInsnNode() {
super(Opcodes.LOOKUPSWITCH);
keys = new ArrayList<>();
labels = new ArrayList<>();
}
/**
* Constructs a new {@link LookupSwitchInsnNode}.
*
* @param dflt
* beginning of the default handler block.
* @param keys
* the values of the keys.
* @param labels
* beginnings of the handler blocks. {@code labels[i]} is the beginning of the handler block for the {@code keys[i]} key.
*/
public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys, final LabelNode[] labels) {
super(Opcodes.LOOKUPSWITCH);
this.dflt = dflt;
this.keys = Util.asArrayList(keys);
this.labels = Util.asArrayList(labels);
}
/**
* Constructs a new {@link LookupSwitchInsnNode}.
*
* @param dflt beginning of the default handler block.
* @param keys the values of the keys.
* @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
* handler block for the {@code keys[i]} key.
*/
public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys, final LabelNode[] labels) {
super(Opcodes.LOOKUPSWITCH);
this.dflt = dflt;
this.keys = Util.asArrayList(keys);
this.labels = Util.asArrayList(labels);
}
/**
* Constructs a new {@link LookupSwitchInsnNode}.
*
* @param dflt beginning of the default handler block.
* @param keys the values of the keys.
* @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
* handler block for the {@code keys[i]} key.
*/
public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys, final LabelNode[] labels) {
super(Opcodes.LOOKUPSWITCH);
this.dflt = dflt;
this.keys = Util.asArrayList(keys);
this.labels = Util.asArrayList(labels);
}
/**
* Constructs a new {@link LookupSwitchInsnNode}.
*
* @param dflt beginning of the default handler block.
* @param keys the values of the keys.
* @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
* handler block for the {@code keys[i]} key.
*/
public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys, final LabelNode[] labels) {
super(Opcodes.LOOKUPSWITCH);
this.dflt = dflt;
this.keys = Util.asArrayList(keys);
this.labels = Util.asArrayList(labels);
}