List of usage examples for org.objectweb.asm.tree InsnList add
public void add(final InsnList insnList)
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
private static InsnList loadOperandStack(Variable arrayStackVar, Variable tempObjectVar, Frame<BasicValue> frame, int start, int end) { Validate.notNull(arrayStackVar);//w ww . j av a 2s . c om Validate.notNull(tempObjectVar); Validate.notNull(frame); Validate.isTrue(arrayStackVar.getType().equals(Type.getType(Object[].class))); Validate.isTrue(tempObjectVar.getType().equals(Type.getType(Object.class))); validateLocalIndicies(arrayStackVar.getIndex(), tempObjectVar.getIndex()); Validate.isTrue(start >= 0); Validate.isTrue(end >= start); // end is exclusive Validate.isTrue(end <= frame.getStackSize()); InsnList ret = new InsnList(); // Restore the stack for (int i = start; i < end; i++) { BasicValue basicValue = frame.getStack(i); Type type = basicValue.getType(); // If type is 'Lnull;', this means that the slot has been assigned null and that "there has been no merge yet that would 'raise' // the type toward some class or interface type" (from ASM mailing list). We know this slot will always contain null at this // point in the code so there's no specific value to load up from the array. Instead we push a null in to that slot, thereby // keeping the same 'Lnull;' type originally assigned to that slot (it doesn't make sense to do a CHECKCAST because 'null' is // not a real class and can never be a real class -- null is a reserved word in Java). if (type.getSort() == Type.OBJECT && "Lnull;".equals(type.getDescriptor())) { ret.add(new InsnNode(Opcodes.ACONST_NULL)); continue; } // Load item from stack storage array ret.add(new VarInsnNode(Opcodes.ALOAD, arrayStackVar.getIndex())); ret.add(new LdcInsnNode(i)); ret.add(new InsnNode(Opcodes.AALOAD)); // Convert the item to an object (if not already an object) and stores it in local vars table. Item removed from stack. switch (type.getSort()) { case Type.BOOLEAN: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Boolean")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false)); break; case Type.BYTE: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Byte")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false)); break; case Type.SHORT: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Short")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false)); break; case Type.CHAR: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Character")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false)); break; case Type.INT: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Integer")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false)); break; case Type.FLOAT: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Float")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false)); break; case Type.LONG: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Long")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false)); break; case Type.DOUBLE: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Double")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false)); break; case Type.ARRAY: case Type.OBJECT: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, basicValue.getType().getInternalName())); break; case Type.METHOD: case Type.VOID: default: throw new IllegalArgumentException(); } } return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Generates instructions to save the operand stack to an object array. * @param arrayStackVar variable that the object array containing operand stack is stored * @param tempObjectVar variable to use for temporary objects * @param frame execution frame at the instruction where the operand stack is to be saved * @return instructions to save the operand stack in to an array and save it to the local variables table * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if variables have the same index, or if variables have been released, or if variables are of wrong * type/* ww w . j a v a 2 s. c o m*/ */ public static InsnList saveOperandStack(Variable arrayStackVar, Variable tempObjectVar, Frame<BasicValue> frame) { Validate.notNull(arrayStackVar); Validate.notNull(tempObjectVar); Validate.notNull(frame); Validate.isTrue(arrayStackVar.getType().equals(Type.getType(Object[].class))); Validate.isTrue(tempObjectVar.getType().equals(Type.getType(Object.class))); validateLocalIndicies(arrayStackVar.getIndex(), tempObjectVar.getIndex()); InsnList ret = new InsnList(); // Create stack storage array and save it in local vars table ret.add(new LdcInsnNode(frame.getStackSize())); ret.add(new TypeInsnNode(Opcodes.ANEWARRAY, "java/lang/Object")); ret.add(new VarInsnNode(Opcodes.ASTORE, arrayStackVar.getIndex())); // Save the stack for (int i = frame.getStackSize() - 1; i >= 0; i--) { BasicValue basicValue = frame.getStack(i); Type type = basicValue.getType(); // If type is 'Lnull;', this means that the slot has been assigned null and that "there has been no merge yet that would 'raise' // the type toward some class or interface type" (from ASM mailing list). We know this slot will always contain null at this // point in the code so we can avoid saving it (but we still need to do a POP to get rid of it). When we load it back up, we can // simply push a null in to that slot, thereby keeping the same 'Lnull;' type. if ("Lnull;".equals(type.getDescriptor())) { ret.add(new InsnNode(Opcodes.POP)); continue; } // Convert the item to an object (if not already an object) and stores it in local vars table. Item removed from stack. switch (type.getSort()) { case Type.BOOLEAN: ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;")); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.BYTE: ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false)); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.SHORT: ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false)); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.CHAR: ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false)); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.INT: ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false)); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.FLOAT: ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false)); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.LONG: ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false)); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.DOUBLE: ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false)); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.ARRAY: case Type.OBJECT: ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.METHOD: case Type.VOID: default: throw new IllegalArgumentException(); } // Store item in to stack storage array ret.add(new VarInsnNode(Opcodes.ALOAD, arrayStackVar.getIndex())); ret.add(new LdcInsnNode(i)); ret.add(new VarInsnNode(Opcodes.ALOAD, tempObjectVar.getIndex())); ret.add(new InsnNode(Opcodes.AASTORE)); } // Restore the stack for (int i = 0; i < frame.getStackSize(); i++) { BasicValue basicValue = frame.getStack(i); Type type = basicValue.getType(); // If type is 'Lnull;', this means that the slot has been assigned null and that "there has been no merge yet that would 'raise' // the type toward some class or interface type" (from ASM mailing list). We know this slot will always contain null at this // point in the code so there's no specific value to load up from the array. Instead we push a null in to that slot, thereby // keeping the same 'Lnull;' type originally assigned to that slot (it doesn't make sense to do a CHECKCAST because 'null' is // not a real class and can never be a real class -- null is a reserved word in Java). if (type.getSort() == Type.OBJECT && "Lnull;".equals(type.getDescriptor())) { ret.add(new InsnNode(Opcodes.ACONST_NULL)); continue; } // Load item from stack storage array ret.add(new VarInsnNode(Opcodes.ALOAD, arrayStackVar.getIndex())); ret.add(new LdcInsnNode(i)); ret.add(new InsnNode(Opcodes.AALOAD)); // Convert the item to an object (if not already an object) and stores it in local vars table. Item removed from stack. switch (type.getSort()) { case Type.BOOLEAN: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Boolean")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false)); break; case Type.BYTE: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Byte")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false)); break; case Type.SHORT: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Short")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false)); break; case Type.CHAR: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Character")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false)); break; case Type.INT: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Integer")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false)); break; case Type.FLOAT: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Float")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false)); break; case Type.LONG: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Long")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false)); break; case Type.DOUBLE: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Double")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false)); break; case Type.ARRAY: case Type.OBJECT: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, basicValue.getType().getInternalName())); break; case Type.METHOD: case Type.VOID: default: throw new IllegalArgumentException(); } } return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Generates instructions to load the local variables table from an object array. * * @param arrayLocalsVar variable that the object array containing local variables table is stored * @param tempObjectVar variable to use for temporary objects * @param frame execution frame at the instruction for which the local variables table is to be restored * @return instructions to load the local variables table from an array * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if variables have the same index, or if variables have been released, or if variables are of wrong * type/*ww w . j av a 2s . co m*/ */ public static InsnList loadLocalVariableTable(Variable arrayLocalsVar, Variable tempObjectVar, Frame<BasicValue> frame) { Validate.notNull(arrayLocalsVar); Validate.notNull(tempObjectVar); Validate.notNull(frame); Validate.isTrue(arrayLocalsVar.getType().equals(Type.getType(Object[].class))); Validate.isTrue(tempObjectVar.getType().equals(Type.getType(Object.class))); validateLocalIndicies(arrayLocalsVar.getIndex(), tempObjectVar.getIndex()); InsnList ret = new InsnList(); // Load the locals for (int i = 0; i < frame.getLocals(); i++) { BasicValue basicValue = frame.getLocal(i); Type type = basicValue.getType(); // If type == null, basicValue is pointing to uninitialized var -- basicValue.toString() will return ".". This means that this // slot contains nothing to load. So, skip this slot if we encounter it (such that it will remain uninitialized). if (type == null) { continue; } // If type is 'Lnull;', this means that the slot has been assigned null and that "there has been no merge yet that would 'raise' // the type toward some class or interface type" (from ASM mailing list). We know this slot will always contain null at this // point in the code so there's no specific value to load up from the array. Instead we push a null in to that slot, thereby // keeping the same 'Lnull;' type originally assigned to that slot (it doesn't make sense to do a CHECKCAST because 'null' is // not a real class and can never be a real class -- null is a reserved word in Java). if (type.getSort() == Type.OBJECT && "Lnull;".equals(type.getDescriptor())) { ret.add(new InsnNode(Opcodes.ACONST_NULL)); ret.add(new VarInsnNode(Opcodes.ASTORE, i)); continue; } // Load item from locals storage array ret.add(new VarInsnNode(Opcodes.ALOAD, arrayLocalsVar.getIndex())); ret.add(new LdcInsnNode(i)); ret.add(new InsnNode(Opcodes.AALOAD)); // Convert the item from an object stores it in local vars table. switch (type.getSort()) { case Type.BOOLEAN: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Boolean")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false)); ret.add(new VarInsnNode(Opcodes.ISTORE, i)); break; case Type.BYTE: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Byte")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false)); ret.add(new VarInsnNode(Opcodes.ISTORE, i)); break; case Type.SHORT: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Short")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false)); ret.add(new VarInsnNode(Opcodes.ISTORE, i)); break; case Type.CHAR: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Character")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false)); ret.add(new VarInsnNode(Opcodes.ISTORE, i)); break; case Type.INT: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Integer")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false)); ret.add(new VarInsnNode(Opcodes.ISTORE, i)); break; case Type.FLOAT: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Float")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false)); ret.add(new VarInsnNode(Opcodes.FSTORE, i)); break; case Type.LONG: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Long")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false)); ret.add(new VarInsnNode(Opcodes.LSTORE, i)); break; case Type.DOUBLE: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Double")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false)); ret.add(new VarInsnNode(Opcodes.DSTORE, i)); break; case Type.ARRAY: case Type.OBJECT: ret.add(new TypeInsnNode(Opcodes.CHECKCAST, basicValue.getType().getInternalName())); ret.add(new VarInsnNode(Opcodes.ASTORE, i)); break; case Type.METHOD: case Type.VOID: default: throw new IllegalStateException(); } } return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Generates instructions to save the local variables table to an object array. * * @param arrayLocalsVar variable that the object array containing local variables table is stored * @param tempObjectVar variable to use for temporary objects * @param frame execution frame at the instruction where the local variables table is to be saved * @return instructions to save the local variables table in to an array * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if variables have the same index, or if variables have been released, or if variables are of wrong * type//from www.j a v a 2s . c o m */ public static InsnList saveLocalVariableTable(Variable arrayLocalsVar, Variable tempObjectVar, Frame<BasicValue> frame) { Validate.notNull(arrayLocalsVar); Validate.notNull(tempObjectVar); Validate.notNull(frame); Validate.isTrue(arrayLocalsVar.getType().equals(Type.getType(Object[].class))); Validate.isTrue(tempObjectVar.getType().equals(Type.getType(Object.class))); validateLocalIndicies(arrayLocalsVar.getIndex(), tempObjectVar.getIndex()); InsnList ret = new InsnList(); // Create array and save it in local vars table ret.add(new LdcInsnNode(frame.getLocals())); ret.add(new TypeInsnNode(Opcodes.ANEWARRAY, "java/lang/Object")); ret.add(new VarInsnNode(Opcodes.ASTORE, arrayLocalsVar.getIndex())); // Save the locals for (int i = 0; i < frame.getLocals(); i++) { BasicValue basicValue = frame.getLocal(i); Type type = basicValue.getType(); // If type == null, basicValue is pointing to uninitialized var -- basicValue.toString() will return '.'. This means that this // slot contains nothing to save. So, skip this slot if we encounter it. if (type == null) { continue; } // If type is 'Lnull;', this means that the slot has been assigned null and that "there has been no merge yet that would 'raise' // the type toward some class or interface type" (from ASM mailing list). We know this slot will always contain null at this // point in the code so we can avoid saving it. When we load it back up, we can simply push a null in to that slot, thereby // keeping the same 'Lnull;' type. if ("Lnull;".equals(type.getDescriptor())) { continue; } // Convert the item to an object (if not already an object) and stores it in array. switch (type.getSort()) { case Type.BOOLEAN: ret.add(new VarInsnNode(Opcodes.ILOAD, i)); ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;")); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.BYTE: ret.add(new VarInsnNode(Opcodes.ILOAD, i)); ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false)); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.SHORT: ret.add(new VarInsnNode(Opcodes.ILOAD, i)); ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false)); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.CHAR: ret.add(new VarInsnNode(Opcodes.ILOAD, i)); ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false)); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.INT: ret.add(new VarInsnNode(Opcodes.ILOAD, i)); ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false)); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.FLOAT: ret.add(new VarInsnNode(Opcodes.FLOAD, i)); ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false)); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.LONG: ret.add(new VarInsnNode(Opcodes.LLOAD, i)); ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false)); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.DOUBLE: ret.add(new VarInsnNode(Opcodes.DLOAD, i)); ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false)); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.ARRAY: case Type.OBJECT: ret.add(new VarInsnNode(Opcodes.ALOAD, i)); ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex())); break; case Type.METHOD: case Type.VOID: default: throw new IllegalStateException(); } // Store item in to locals storage array ret.add(new VarInsnNode(Opcodes.ALOAD, arrayLocalsVar.getIndex())); ret.add(new LdcInsnNode(i)); ret.add(new VarInsnNode(Opcodes.ALOAD, tempObjectVar.getIndex())); ret.add(new InsnNode(Opcodes.AASTORE)); } return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Generates instructions that returns a dummy value. Return values are as follows: * <ul>//from w w w. j a v a 2s . com * <li>void -> no value</li> * <li>boolean -> false</li> * <li>byte/short/char/int -> 0</li> * <li>long -> 0L</li> * <li>float -> 0.0f</li> * <li>double -> 0.0</li> * <li>Object -> null</li> * </ul> * * @param returnType return type of the method this generated bytecode is for * @return instructions to return a dummy value * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if {@code returnType}'s sort is of {@link Type#METHOD} */ public static InsnList returnDummy(Type returnType) { Validate.notNull(returnType); Validate.isTrue(returnType.getSort() != Type.METHOD); InsnList ret = new InsnList(); switch (returnType.getSort()) { case Type.VOID: ret.add(new InsnNode(Opcodes.RETURN)); break; case Type.BOOLEAN: case Type.BYTE: case Type.SHORT: case Type.CHAR: case Type.INT: ret.add(new InsnNode(Opcodes.ICONST_0)); ret.add(new InsnNode(Opcodes.IRETURN)); break; case Type.LONG: ret.add(new InsnNode(Opcodes.LCONST_0)); ret.add(new InsnNode(Opcodes.LRETURN)); break; case Type.FLOAT: ret.add(new InsnNode(Opcodes.FCONST_0)); ret.add(new InsnNode(Opcodes.FRETURN)); break; case Type.DOUBLE: ret.add(new InsnNode(Opcodes.DCONST_0)); ret.add(new InsnNode(Opcodes.DRETURN)); break; case Type.OBJECT: case Type.ARRAY: ret.add(new InsnNode(Opcodes.ACONST_NULL)); ret.add(new InsnNode(Opcodes.ARETURN)); break; default: throw new IllegalStateException(); } return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Generates instructions that returns a value. * * @param returnType return type of the method this generated bytecode is for * @param returnValueInsnList instructions that produce the return value (should leave it on the top of the stack) * @return instructions to return a value * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if {@code returnType}'s sort is of {@link Type#METHOD} *//*from w w w.j a va2 s .c om*/ public static InsnList returnValue(Type returnType, InsnList returnValueInsnList) { Validate.notNull(returnType); Validate.isTrue(returnType.getSort() != Type.METHOD); InsnList ret = new InsnList(); ret.add(returnValueInsnList); switch (returnType.getSort()) { case Type.VOID: ret.add(new InsnNode(Opcodes.RETURN)); break; case Type.BOOLEAN: case Type.BYTE: case Type.SHORT: case Type.CHAR: case Type.INT: ret.add(new InsnNode(Opcodes.IRETURN)); break; case Type.LONG: ret.add(new InsnNode(Opcodes.LRETURN)); break; case Type.FLOAT: ret.add(new InsnNode(Opcodes.FRETURN)); break; case Type.DOUBLE: ret.add(new InsnNode(Opcodes.DRETURN)); break; case Type.OBJECT: case Type.ARRAY: ret.add(new InsnNode(Opcodes.ARETURN)); break; default: throw new IllegalStateException(); } return ret; }
From source file:com.offbynull.coroutines.instrumenter.ContinuationGenerators.java
License:Open Source License
/** * Generates instructions that returns a dummy value. Return values are as follows: * <ul>//from ww w .ja v a2s .c o m * <li>void -> no value</li> * <li>boolean -> false</li> * <li>byte/short/char/int -> 0</li> * <li>long -> 0L</li> * <li>float -> 0.0f</li> * <li>double -> 0.0</li> * <li>Object -> null</li> * </ul> * * @param returnType return type of the method this generated bytecode is for * @return instructions to return a dummy value * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if {@code returnType}'s sort is of {@link Type#METHOD} */ private static InsnList returnDummy(Type returnType) { Validate.notNull(returnType); Validate.isTrue(returnType.getSort() != Type.METHOD); InsnList ret = new InsnList(); switch (returnType.getSort()) { case Type.VOID: ret.add(new InsnNode(Opcodes.RETURN)); break; case Type.BOOLEAN: case Type.BYTE: case Type.SHORT: case Type.CHAR: case Type.INT: ret.add(new InsnNode(Opcodes.ICONST_0)); ret.add(new InsnNode(Opcodes.IRETURN)); break; case Type.LONG: ret.add(new InsnNode(Opcodes.LCONST_0)); ret.add(new InsnNode(Opcodes.LRETURN)); break; case Type.FLOAT: ret.add(new InsnNode(Opcodes.FCONST_0)); ret.add(new InsnNode(Opcodes.FRETURN)); break; case Type.DOUBLE: ret.add(new InsnNode(Opcodes.DCONST_0)); ret.add(new InsnNode(Opcodes.DRETURN)); break; case Type.OBJECT: case Type.ARRAY: ret.add(new InsnNode(Opcodes.ACONST_NULL)); ret.add(new InsnNode(Opcodes.ARETURN)); break; default: throw new IllegalStateException(); } return ret; }
From source file:com.offbynull.coroutines.instrumenter.ContinuationGenerators.java
License:Open Source License
/** * Generates instructions to pop the result of the method off the stack. This will only generate instructions if the method being * invoked generates a return value.//w ww .ja v a 2 s. c om * @param invokeInsnNode instruction for the method that was invoked (can either be of type {@link MethodInsnNode} or * {@link InvokeDynamicInsnNode} -- this is used to determine how many items to pop off the stack * @return instructions for a pop (only if the method being invoked generates a return value) * @throws IllegalArgumentException if {@code invokeInsnNode} isn't of type {@link MethodInsnNode} or {@link InvokeDynamicInsnNode} * @throws NullPointerException if any argument is {@code null} */ private static InsnList popMethodResult(AbstractInsnNode invokeInsnNode) { Validate.notNull(invokeInsnNode); Type returnType = getReturnTypeOfInvocation(invokeInsnNode); InsnList ret = new InsnList(); switch (returnType.getSort()) { case Type.LONG: case Type.DOUBLE: ret.add(new InsnNode(Opcodes.POP2)); break; case Type.VOID: break; case Type.METHOD: throw new IllegalStateException(); // this should never happen default: ret.add(new InsnNode(Opcodes.POP)); break; } return ret; }
From source file:com.offbynull.coroutines.instrumenter.ContinuationPointInstructionUtils.java
License:Open Source License
static InsnList castToObjectAndSave(Type originalType, Variable variable) { Validate.notNull(originalType);/*from w w w. ja v a2s . c o m*/ Validate.notNull(variable); Validate.isTrue(variable.getType().equals(Type.getType(Object.class))); InsnList ret = new InsnList(); switch (originalType.getSort()) { case Type.BOOLEAN: ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false)); ret.add(saveVar(variable)); // save it in to the returnValObj break; case Type.BYTE: ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false)); ret.add(saveVar(variable)); // save it in to the returnValObj break; case Type.SHORT: ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false)); ret.add(saveVar(variable)); // save it in to the returnValObj break; case Type.CHAR: ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false)); ret.add(saveVar(variable)); // save it in to the returnValObj break; case Type.INT: ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false)); ret.add(saveVar(variable)); // save it in to the returnValObj break; case Type.FLOAT: ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false)); ret.add(saveVar(variable)); // save it in to the returnValObj break; case Type.LONG: ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false)); ret.add(saveVar(variable)); // save it in to the returnValObj break; case Type.DOUBLE: ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false)); ret.add(saveVar(variable)); // save it in to the returnValObj break; case Type.ARRAY: case Type.OBJECT: ret.add(saveVar(variable)); // save it in to the returnValObj break; case Type.VOID: break; case Type.METHOD: default: throw new IllegalArgumentException(); } return ret; }
From source file:com.offbynull.coroutines.instrumenter.ContinuationPointInstructionUtils.java
License:Open Source License
static InsnList loadAndCastToOriginal(Type originalType, Variable variable) { Validate.notNull(originalType);//from ww w . j a v a 2 s . c o m Validate.notNull(variable); Validate.isTrue(variable.getType().equals(Type.getType(Object.class))); InsnList ret = new InsnList(); switch (originalType.getSort()) { case Type.BOOLEAN: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Boolean")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false)); break; case Type.BYTE: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Byte")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false)); break; case Type.SHORT: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Short")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false)); break; case Type.CHAR: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Character")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false)); break; case Type.INT: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Integer")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false)); break; case Type.FLOAT: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Float")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false)); break; case Type.LONG: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Long")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false)); break; case Type.DOUBLE: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Double")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false)); break; case Type.ARRAY: case Type.OBJECT: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, originalType.getInternalName())); break; case Type.VOID: break; case Type.METHOD: default: throw new IllegalArgumentException(); } return ret; }