下面列出了org.objectweb.asm.Opcodes# TABLESWITCH 实例代码,或者点击链接到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_checkTableSwitch() throws Exception {
List<BasicBlock> hashCodeBlocks = METHOD_BLOCKS.get("checkTableSwitch(I)I");
int[][] expectedHashCodeBlocks = new int[][]{
{Opcodes.ICONST_5, Opcodes.ISTORE, Opcodes.ILOAD, Opcodes.TABLESWITCH},
{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);
}
@Override
public final void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels) {
AttributesImpl attrs = new AttributesImpl();
attrs.addAttribute("", "min", "min", "", Integer.toString(min));
attrs.addAttribute("", "max", "max", "", Integer.toString(max));
attrs.addAttribute("", "dflt", "dflt", "", getLabel(dflt));
String o = Printer.OPCODES[Opcodes.TABLESWITCH];
sa.addStart(o, attrs);
for (int i = 0; i < labels.length; i++) {
AttributesImpl att2 = new AttributesImpl();
att2.addAttribute("", "name", "name", "", getLabel(labels[i]));
sa.addElement("label", att2);
}
sa.addEnd(o);
}
public SwitchInstruction(Label dflt, int[] keys, Label[] labels) {
super(Opcodes.TABLESWITCH);
this.dflt = dflt;
this.keys = keys;
this.labels = labels;
for(int iter = 0 ; iter < keys.length ; iter++) {
LabelInstruction.labelIsUsed(labels[iter]);
}
LabelInstruction.labelIsUsed(dflt);
}
public TableSwitchInsnNode() {
super(Opcodes.TABLESWITCH);
labels = new ArrayList<>();
}
/**
* Constructs a new {@link TableSwitchInsnNode}.
*
* @param min
* the minimum key value.
* @param max
* the maximum key value.
* @param dflt
* beginning of the default handler block.
* @param labels
* beginnings of the handler blocks. {@code labels[i]} is the beginning of the handler block for the {@code min + i} key.
*/
public TableSwitchInsnNode(final int min, final int max, final LabelNode dflt, final LabelNode... labels) {
super(Opcodes.TABLESWITCH);
this.min = min;
this.max = max;
this.dflt = dflt;
this.labels = Util.asArrayList(labels);
}
/**
* Constructs a new {@link TableSwitchInsnNode}.
*
* @param min the minimum key value.
* @param max the maximum key value.
* @param dflt beginning of the default handler block.
* @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
* handler block for the {@code min + i} key.
*/
public TableSwitchInsnNode(
final int min, final int max, final LabelNode dflt, final LabelNode... labels) {
super(Opcodes.TABLESWITCH);
this.min = min;
this.max = max;
this.dflt = dflt;
this.labels = Util.asArrayList(labels);
}
/**
* Constructs a new {@link TableSwitchInsnNode}.
*
* @param min
* the minimum key value.
* @param max
* the maximum key value.
* @param dflt
* beginning of the default handler block.
* @param labels
* beginnings of the handler blocks. <tt>labels[i]</tt> is the
* beginning of the handler block for the <tt>min + i</tt> key.
*/
public TableSwitchInsnNode(final int min, final int max, final LabelNode dflt, final LabelNode... labels) {
super(Opcodes.TABLESWITCH);
this.min = min;
this.max = max;
this.dflt = dflt;
this.labels = new ArrayList<LabelNode>();
if (labels != null) {
this.labels.addAll(Arrays.asList(labels));
}
}
/**
* Constructs a new {@link TableSwitchInsnNode}.
*
* @param min the minimum key value.
* @param max the maximum key value.
* @param dflt beginning of the default handler block.
* @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
* handler block for the {@code min + i} key.
*/
public TableSwitchInsnNode(
final int min, final int max, final LabelNode dflt, final LabelNode... labels) {
super(Opcodes.TABLESWITCH);
this.min = min;
this.max = max;
this.dflt = dflt;
this.labels = Util.asArrayList(labels);
}
/**
* Constructs a new {@link TableSwitchInsnNode}.
*
* @param min the minimum key value.
* @param max the maximum key value.
* @param dflt beginning of the default handler block.
* @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
* handler block for the {@code min + i} key.
*/
public TableSwitchInsnNode(
final int min, final int max, final LabelNode dflt, final LabelNode... labels) {
super(Opcodes.TABLESWITCH);
this.min = min;
this.max = max;
this.dflt = dflt;
this.labels = Util.asArrayList(labels);
}