List of usage examples for org.objectweb.asm.tree InsnList InsnList
InsnList
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Copies a local variable on to the stack. * @param variable variable within the local variable table to load from * @return instructions to load a local variable on to the stack * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if {@code variable} has been released *//*from ww w . jav a 2s . co m*/ public static InsnList loadVar(Variable variable) { Validate.notNull(variable); InsnList ret = new InsnList(); switch (variable.getType().getSort()) { case Type.BOOLEAN: case Type.BYTE: case Type.CHAR: case Type.SHORT: case Type.INT: ret.add(new VarInsnNode(Opcodes.ILOAD, variable.getIndex())); break; case Type.LONG: ret.add(new VarInsnNode(Opcodes.LLOAD, variable.getIndex())); break; case Type.FLOAT: ret.add(new VarInsnNode(Opcodes.FLOAD, variable.getIndex())); break; case Type.DOUBLE: ret.add(new VarInsnNode(Opcodes.DLOAD, variable.getIndex())); break; case Type.OBJECT: case Type.ARRAY: ret.add(new VarInsnNode(Opcodes.ALOAD, variable.getIndex())); ret.add(new TypeInsnNode(Opcodes.CHECKCAST, variable.getType().getInternalName())); break; default: throw new IllegalStateException(); // should never happen, there is code in Variable/VariableTable to make sure invalid // types aren't set } return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Pops the stack in to the the local variable table. You may run in to problems if the item on top of the stack isn't of the same type * as the variable it's being put in to. * @param variable variable within the local variable table to save to * @return instructions to pop an item off the top of the stack and save it to {@code variable} * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if {@code variable} has been released *//*from w ww.j a v a 2s . com*/ public static InsnList saveVar(Variable variable) { Validate.notNull(variable); InsnList ret = new InsnList(); switch (variable.getType().getSort()) { case Type.BOOLEAN: case Type.BYTE: case Type.CHAR: case Type.SHORT: case Type.INT: ret.add(new VarInsnNode(Opcodes.ISTORE, variable.getIndex())); break; case Type.LONG: ret.add(new VarInsnNode(Opcodes.LSTORE, variable.getIndex())); break; case Type.FLOAT: ret.add(new VarInsnNode(Opcodes.FSTORE, variable.getIndex())); break; case Type.DOUBLE: ret.add(new VarInsnNode(Opcodes.DSTORE, variable.getIndex())); break; case Type.OBJECT: case Type.ARRAY: ret.add(new VarInsnNode(Opcodes.ASTORE, variable.getIndex())); break; default: throw new IllegalStateException(); // should never happen, there is code in Variable/VariableTable to make sure invalid // types aren't set } return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Calls a constructor with a set of arguments. After execution the stack should have an extra item pushed on it: the object that was * created by this constructor.// w w w .j a va2 s . c o m * @param constructor constructor to call * @param args constructor argument instruction lists -- each instruction list must leave one item on the stack of the type expected * by the constructor * @return instructions to invoke a constructor * @throws NullPointerException if any argument is {@code null} or array contains {@code null} * @throws IllegalArgumentException if the length of {@code args} doesn't match the number of parameters in {@code constructor} */ public static InsnList construct(Constructor<?> constructor, InsnList... args) { Validate.notNull(constructor); Validate.notNull(args); Validate.noNullElements(args); Validate.isTrue(constructor.getParameterCount() == args.length); InsnList ret = new InsnList(); Type clsType = Type.getType(constructor.getDeclaringClass()); Type methodType = Type.getType(constructor); ret.add(new TypeInsnNode(Opcodes.NEW, clsType.getInternalName())); ret.add(new InsnNode(Opcodes.DUP)); for (InsnList arg : args) { ret.add(arg); } ret.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, clsType.getInternalName(), "<init>", methodType.getDescriptor(), false)); return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Compares two integers and performs some action if the integers are equal. * @param lhs left hand side instruction list -- must leave an int on top of the stack * @param rhs right hand side instruction list -- must leave an int on top of the stack * @param action action to perform if results of {@code lhs} and {@code rhs} are equal * @return instructions instruction list to perform some action if two ints are equal * @throws NullPointerException if any argument is {@code null} *//* www.jav a2s .c o m*/ public static InsnList ifIntegersEqual(InsnList lhs, InsnList rhs, InsnList action) { Validate.notNull(lhs); Validate.notNull(rhs); Validate.notNull(action); InsnList ret = new InsnList(); LabelNode notEqualLabelNode = new LabelNode(); ret.add(lhs); ret.add(rhs); ret.add(new JumpInsnNode(Opcodes.IF_ICMPNE, notEqualLabelNode)); ret.add(action); ret.add(notEqualLabelNode); return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Compares two objects and performs some action if the objects are the same (uses == to check if same, not the equals method). * @param lhs left hand side instruction list -- must leave an object on top of the stack * @param rhs right hand side instruction list -- must leave an object on top of the stack * @param action action to perform if results of {@code lhs} and {@code rhs} are equal * @return instructions instruction list to perform some action if two objects are equal * @throws NullPointerException if any argument is {@code null} *//*from ww w .j a va2s .c om*/ public static InsnList ifObjectsEqual(InsnList lhs, InsnList rhs, InsnList action) { Validate.notNull(lhs); Validate.notNull(rhs); Validate.notNull(action); InsnList ret = new InsnList(); LabelNode notEqualLabelNode = new LabelNode(); ret.add(lhs); ret.add(rhs); ret.add(new JumpInsnNode(Opcodes.IF_ACMPNE, notEqualLabelNode)); ret.add(action); ret.add(notEqualLabelNode); return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * For each element in an object array, performs an action. * @param counterVar parameter used to keep track of count in loop * @param arrayLenVar parameter used to keep track of array length * @param array object array instruction list -- must leave an array on top of the stack * @param action action to perform on each element -- element will be at top of stack and must be consumed by these instructions * @return instructions instruction list to perform some action if two ints are equal * @throws NullPointerException if any argument is {@code null} *//*from w ww . ja va 2 s. c o m*/ public static InsnList forEach(Variable counterVar, Variable arrayLenVar, InsnList array, InsnList action) { Validate.notNull(counterVar); Validate.notNull(arrayLenVar); Validate.notNull(array); Validate.notNull(action); Validate.isTrue(counterVar.getType().equals(Type.INT_TYPE)); Validate.isTrue(arrayLenVar.getType().equals(Type.INT_TYPE)); InsnList ret = new InsnList(); LabelNode doneLabelNode = new LabelNode(); LabelNode loopLabelNode = new LabelNode(); // put zero in to counterVar ret.add(new LdcInsnNode(0)); // int ret.add(new VarInsnNode(Opcodes.ISTORE, counterVar.getIndex())); // // load array we'll be traversing over ret.add(array); // object[] // put array length in to arrayLenVar ret.add(new InsnNode(Opcodes.DUP)); // object[], object[] ret.add(new InsnNode(Opcodes.ARRAYLENGTH)); // object[], int ret.add(new VarInsnNode(Opcodes.ISTORE, arrayLenVar.getIndex())); // object[] // loopLabelNode: test if counterVar == arrayLenVar, if it does then jump to doneLabelNode ret.add(loopLabelNode); ret.add(new VarInsnNode(Opcodes.ILOAD, counterVar.getIndex())); // object[], int ret.add(new VarInsnNode(Opcodes.ILOAD, arrayLenVar.getIndex())); // object[], int, int ret.add(new JumpInsnNode(Opcodes.IF_ICMPEQ, doneLabelNode)); // object[] // load object from object[] ret.add(new InsnNode(Opcodes.DUP)); // object[], object[] ret.add(new VarInsnNode(Opcodes.ILOAD, counterVar.getIndex())); // object[], object[], int ret.add(new InsnNode(Opcodes.AALOAD)); // object[], object // call action ret.add(action); // object[] // increment counter var and goto loopLabelNode ret.add(new IincInsnNode(counterVar.getIndex(), 1)); // object[] ret.add(new JumpInsnNode(Opcodes.GOTO, loopLabelNode)); // object[] // doneLabelNode: pop object[] off of stack ret.add(doneLabelNode); ret.add(new InsnNode(Opcodes.POP)); // return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Calls a method with a set of arguments. After execution the stack may have an extra item pushed on it: the object that was returned * by this method (if any)./* www . j av a 2 s . c om*/ * @param method method to call * @param args method argument instruction lists -- each instruction list must leave one item on the stack of the type expected * by the method (note that if this is a non-static method, the first argument must always evaluate to the "this" pointer/reference) * @return instructions to invoke a method * @throws NullPointerException if any argument is {@code null} or array contains {@code null} * @throws IllegalArgumentException if the length of {@code args} doesn't match the number of parameters in {@code method} */ public static InsnList call(Method method, InsnList... args) { Validate.notNull(method); Validate.notNull(args); Validate.noNullElements(args); InsnList ret = new InsnList(); for (InsnList arg : args) { ret.add(arg); } Type clsType = Type.getType(method.getDeclaringClass()); Type methodType = Type.getType(method); if ((method.getModifiers() & Modifier.STATIC) == Modifier.STATIC) { Validate.isTrue(method.getParameterCount() == args.length); ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, clsType.getInternalName(), method.getName(), methodType.getDescriptor(), false)); } else if (method.getDeclaringClass().isInterface()) { Validate.isTrue(method.getParameterCount() + 1 == args.length); ret.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, clsType.getInternalName(), method.getName(), methodType.getDescriptor(), true)); } else { Validate.isTrue(method.getParameterCount() + 1 == args.length); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, clsType.getInternalName(), method.getName(), methodType.getDescriptor(), false)); } return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Generates instructions to throw an exception of type {@link RuntimeException} with a constant message. * @param message message of exception//from w ww .j ava 2 s . c om * @return instructions to throw an exception * @throws NullPointerException if any argument is {@code null} */ public static InsnList throwException(String message) { Validate.notNull(message); InsnList ret = new InsnList(); ret.add(new TypeInsnNode(Opcodes.NEW, "java/lang/RuntimeException")); ret.add(new InsnNode(Opcodes.DUP)); ret.add(new LdcInsnNode(message)); ret.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false)); ret.add(new InsnNode(Opcodes.ATHROW)); return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Generates instructions for a switch table. This does not automatically generate jumps at the end of each default/case statement. It's * your responsibility to either add the relevant jumps, throws, or returns at each default/case statement, otherwise the code will * just fall through (which is likely not what you want). * @param indexInsnList instructions to calculate the index -- must leave an int on top of the stack * @param defaultInsnList instructions to execute on default statement -- must leave the stack unchanged * @param caseStartIdx the number which the case statements start at * @param caseInsnLists instructions to execute on each case statement -- must leave the stack unchanged * @return instructions for a table switch * @throws NullPointerException if any argument is {@code null} or contains {@code null} * @throws IllegalArgumentException if any numeric argument is {@code < 0}, or if {@code caseInsnLists} is empty *///w w w. j a v a 2s . c om public static InsnList tableSwitch(InsnList indexInsnList, InsnList defaultInsnList, int caseStartIdx, InsnList... caseInsnLists) { Validate.notNull(defaultInsnList); Validate.notNull(indexInsnList); Validate.isTrue(caseStartIdx >= 0); Validate.notNull(caseInsnLists); Validate.noNullElements(caseInsnLists); Validate.isTrue(caseInsnLists.length > 0); InsnList ret = new InsnList(); LabelNode defaultLabelNode = new LabelNode(); LabelNode[] caseLabelNodes = new LabelNode[caseInsnLists.length]; for (int i = 0; i < caseInsnLists.length; i++) { caseLabelNodes[i] = new LabelNode(); } ret.add(indexInsnList); ret.add(new TableSwitchInsnNode(caseStartIdx, caseStartIdx + caseInsnLists.length - 1, defaultLabelNode, caseLabelNodes)); for (int i = 0; i < caseInsnLists.length; i++) { LabelNode caseLabelNode = caseLabelNodes[i]; InsnList caseInsnList = caseInsnLists[i]; if (caseInsnList != null) { ret.add(caseLabelNode); ret.add(caseInsnList); } } if (defaultInsnList != null) { ret.add(defaultLabelNode); ret.add(defaultInsnList); } return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Generates instructions for a try-catch block. * @param tryCatchBlockNode try catch block node to populate to with label with relevant information * @param exceptionType exception type to catch ({@code null} means catch any exception) * @param tryInsnList instructions to execute for try block * @param catchInsnList instructions to execute for catch block * @return instructions for a try catch block * @throws NullPointerException if any argument other than {@code exceptionType} is {@code null} or contains {@code null} * @throws IllegalArgumentException if {@code exceptionType} is not an object type (technically must inherit from {@link Throwable}, * but no way to check this)/*from w w w . ja va 2s .c om*/ */ public static InsnList tryCatchBlock(TryCatchBlockNode tryCatchBlockNode, Type exceptionType, InsnList tryInsnList, InsnList catchInsnList) { Validate.notNull(tryInsnList); // exceptionType can be null Validate.notNull(catchInsnList); if (exceptionType != null) { Validate.isTrue(exceptionType.getSort() == Type.OBJECT); } InsnList ret = new InsnList(); LabelNode tryLabelNode = new LabelNode(); LabelNode catchLabelNode = new LabelNode(); LabelNode endLabelNode = new LabelNode(); tryCatchBlockNode.start = tryLabelNode; tryCatchBlockNode.end = catchLabelNode; tryCatchBlockNode.handler = catchLabelNode; tryCatchBlockNode.type = exceptionType == null ? null : exceptionType.getInternalName(); ret.add(tryLabelNode); ret.add(tryInsnList); ret.add(new JumpInsnNode(Opcodes.GOTO, endLabelNode)); ret.add(catchLabelNode); ret.add(catchInsnList); ret.add(endLabelNode); return ret; }