List of usage examples for org.objectweb.asm Opcodes LOOKUPSWITCH
int LOOKUPSWITCH
To view the source code for org.objectweb.asm Opcodes LOOKUPSWITCH.
Click Source Link
From source file:com.android.tools.lint.checks.ApiDetector.java
License:Apache License
@SuppressWarnings("rawtypes") // ASM API private static void checkSwitchBlock(ClassContext context, ClassNode classNode, FieldInsnNode field, MethodNode method, String name, String owner, int api, int minSdk) { // Switch statements on enums are tricky. The compiler will generate a method // which returns an array of the enum constants, indexed by their ordinal() values. // However, we only want to complain if the code is actually referencing one of // the non-available enum fields. ///*from w w w.ja va 2s .c o m*/ // For the android.graphics.PorterDuff.Mode enum for example, the first few items // in the array are populated like this: // // L0 // ALOAD 0 // GETSTATIC android/graphics/PorterDuff$Mode.ADD : Landroid/graphics/PorterDuff$Mode; // INVOKEVIRTUAL android/graphics/PorterDuff$Mode.ordinal ()I // ICONST_1 // IASTORE // L1 // GOTO L3 // L2 // FRAME FULL [[I] [java/lang/NoSuchFieldError] // POP // L3 // FRAME SAME // ALOAD 0 // GETSTATIC android/graphics/PorterDuff$Mode.CLEAR : Landroid/graphics/PorterDuff$Mode; // INVOKEVIRTUAL android/graphics/PorterDuff$Mode.ordinal ()I // ICONST_2 // IASTORE // ... // So if we for example find that the "ADD" field isn't accessible, since it requires // API 11, we need to // (1) First find out what its ordinal number is. We can look at the following // instructions to discover this; it's the "ICONST_1" and "IASTORE" instructions. // (After ICONST_5 it moves on to BIPUSH 6, BIPUSH 7, etc.) // (2) Find the corresponding *usage* of this switch method. For the above enum, // the switch ordinal lookup method will be called // "$SWITCH_TABLE$android$graphics$PorterDuff$Mode" with desc "()[I". // This means we will be looking for an invocation in some other method which looks // like this: // INVOKESTATIC (current class).$SWITCH_TABLE$android$graphics$PorterDuff$Mode ()[I // (obviously, it can be invoked more than once) // Note that it can be used more than once in this class and all sites should be // checked! // (3) Look up the corresponding table switch, which should look something like this: // INVOKESTATIC (current class).$SWITCH_TABLE$android$graphics$PorterDuff$Mode ()[I // ALOAD 0 // INVOKEVIRTUAL android/graphics/PorterDuff$Mode.ordinal ()I // IALOAD // LOOKUPSWITCH // 2: L1 // 11: L2 // default: L3 // Here we need to see if the LOOKUPSWITCH instruction is referencing our target // case. Above we were looking for the "ADD" case which had ordinal 1. Since this // isn't explicitly referenced, we can ignore this field reference. AbstractInsnNode next = field.getNext(); if (next == null || next.getOpcode() != Opcodes.INVOKEVIRTUAL) { return; } next = next.getNext(); if (next == null) { return; } int ordinal; switch (next.getOpcode()) { case Opcodes.ICONST_0: ordinal = 0; break; case Opcodes.ICONST_1: ordinal = 1; break; case Opcodes.ICONST_2: ordinal = 2; break; case Opcodes.ICONST_3: ordinal = 3; break; case Opcodes.ICONST_4: ordinal = 4; break; case Opcodes.ICONST_5: ordinal = 5; break; case Opcodes.BIPUSH: { IntInsnNode iin = (IntInsnNode) next; ordinal = iin.operand; break; } default: return; } // Find usages of this call site List methodList = classNode.methods; for (Object m : methodList) { InsnList nodes = ((MethodNode) m).instructions; for (int i = 0, n = nodes.size(); i < n; i++) { AbstractInsnNode instruction = nodes.get(i); if (instruction.getOpcode() != Opcodes.INVOKESTATIC) { continue; } MethodInsnNode node = (MethodInsnNode) instruction; if (node.name.equals(method.name) && node.desc.equals(method.desc) && node.owner.equals(classNode.name)) { // Find lookup switch AbstractInsnNode target = getNextInstruction(node); while (target != null) { if (target.getOpcode() == Opcodes.LOOKUPSWITCH) { LookupSwitchInsnNode lookup = (LookupSwitchInsnNode) target; @SuppressWarnings("unchecked") // ASM API List<Integer> keys = lookup.keys; if (keys != null && keys.contains(ordinal)) { String fqcn = ClassContext.getFqcn(owner) + '#' + name; String message = String.format( "Enum value requires API level %1$d " + "(current min is %2$d): %3$s", api, minSdk, fqcn); report(context, message, lookup, (MethodNode) m, name, null, SearchHints.create(FORWARD).matchJavaSymbol()); // Break out of the inner target search only; the switch // statement could be used in other places in this class as // well and we want to report all problematic usages. break; } } target = getNextInstruction(target); } } } } }
From source file:com.gargoylesoftware.js.nashorn.internal.ir.debug.NashornTextifier.java
License:Open Source License
@Override public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { final StringBuilder sb = new StringBuilder(); appendOpcode(sb, Opcodes.LOOKUPSWITCH).append(' '); for (int i = 0; i < labels.length; ++i) { sb.append(tab3).append(keys[i]).append(": "); final String to = appendLabel(sb, labels[i]); graph.addEdge(currentBlock, to); sb.append('\n'); }//w ww .ja v a 2 s .c om sb.append(tab3).append("default: "); final String to = appendLabel(sb, dflt); graph.addEdge(currentBlock, to); sb.append('\n'); addText(sb.toString()); }
From source file:com.mebigfatguy.baremetal4j.Sourcifier.java
License:Apache License
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { lines.add(/*from w w w .jav a 2s . co m*/ "\t\tBCO = " + String.format("%05d", byteOffset) + "; // " + Printer.OPCODES[Opcodes.LOOKUPSWITCH]); byteOffset += 1; }
From source file:com.trigersoft.jaque.expression.ExpressionMethodVisitor.java
License:Apache License
@Override public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { throw notLambda(Opcodes.LOOKUPSWITCH); }
From source file:de.loskutov.bco.asm.CommentedASMifierClassVisitor.java
License:Open Source License
@Override public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { addIndex(Opcodes.LOOKUPSWITCH); super.visitLookupSwitchInsn(dflt, keys, labels); }
From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.LookupSwitchInstruction.java
License:Open Source License
public LookupSwitchInstruction(final ReadMethod readMethod, final int lineNumber, final LabelMarker defaultHandler, final IntegerMap<LabelMarker> handlers) { super(readMethod, Opcodes.LOOKUPSWITCH, lineNumber); this.defaultHandler = defaultHandler; this.handlers = handlers; }
From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.LookupSwitchInstruction.java
License:Open Source License
private LookupSwitchInstruction(final ReadMethod readMethod, final int lineNumber, final LabelMarker defaultHandler, final IntegerMap<LabelMarker> handlers, final int index) { super(readMethod, Opcodes.LOOKUPSWITCH, lineNumber, index); this.defaultHandler = defaultHandler; this.handlers = handlers; }
From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.LookupSwitchInstruction2.java
License:Open Source License
public LookupSwitchInstruction2(final ReadMethod readMethod, final int lineNumber, final int defaultHandler, final Map<Integer, Integer> handlers) { super(readMethod, Opcodes.LOOKUPSWITCH, lineNumber); this.defaultHandler = defaultHandler; this.handlers = handlers; }
From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.LookupSwitchInstruction2.java
License:Open Source License
public LookupSwitchInstruction2(final ReadMethod readMethod, final int lineNumber, final int defaultHandler, final Map<Integer, Integer> handlers, final int index) { super(readMethod, Opcodes.LOOKUPSWITCH, lineNumber, index); this.defaultHandler = defaultHandler; this.handlers = handlers; }
From source file:edu.mit.streamjit.util.bytecode.MethodResolver.java
License:Open Source License
private void interpret(LookupSwitchInsnNode insn, FrameState frame, BBInfo block) { assert insn.getOpcode() == Opcodes.LOOKUPSWITCH; ConstantFactory cf = module.constants(); SwitchInst inst = new SwitchInst(frame.stack.pop(), blockByInsn(insn.dflt).block); for (int i = 0; i < insn.keys.size(); ++i) inst.put(cf.getConstant((Integer) insn.keys.get(i)), blockByInsn((LabelNode) insn.labels.get(i)).block); block.block.instructions().add(inst); }