List of usage examples for org.objectweb.asm Opcodes INVOKEVIRTUAL
int INVOKEVIRTUAL
To view the source code for org.objectweb.asm Opcodes INVOKEVIRTUAL.
Click Source Link
From source file:com.nway.spring.jdbc.bean.AsmBeanProcessor.java
License:Apache License
private void visitMethodWrap(MethodVisitor mv, int index, String beanSignature, int beanType, String writeMethod, String processorName) { mv.visitVarInsn(Opcodes.ALOAD, 3);//from ww w . j a v a2 s .co m mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 1); visitInsn(mv, index); switch (beanType) { case PROPERTY_TYPE_INTEGER: mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/sql/ResultSet", "getInt", "(I)I", true); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/sql/ResultSet", "wasNull", "()Z", true); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, processorName, "integerValue", "(IZ)Ljava/lang/Integer;", false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, beanSignature, writeMethod, "(Ljava/lang/Integer;)V", false); break; case PROPERTY_TYPE_LONG: mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/sql/ResultSet", "getLong", "(I)J", true); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/sql/ResultSet", "wasNull", "()Z", true); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, processorName, "longValue", "(JZ)Ljava/lang/Long;", false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, beanSignature, writeMethod, "(Ljava/lang/Long;)V", false); break; case PROPERTY_TYPE_BOOLEAN: mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/sql/ResultSet", "getBoolean", "(I)Z", true); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/sql/ResultSet", "wasNull", "()Z", true); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, processorName, "booleanValue", "(ZZ)Ljava/lang/Boolean;", false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, beanSignature, writeMethod, "(Ljava/lang/Boolean;)V", false); break; case PROPERTY_TYPE_FLOAT: mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/sql/ResultSet", "getFloat", "(I)F", true); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/sql/ResultSet", "wasNull", "()Z", true); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, processorName, "floatValue", "(FZ)Ljava/lang/Float;", false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, beanSignature, writeMethod, "(Ljava/lang/Float;)V", false); break; case PROPERTY_TYPE_DOUBLE: mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/sql/ResultSet", "getDouble", "(I)D", true); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/sql/ResultSet", "wasNull", "()Z", true); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, processorName, "doubleValue", "(DZ)Ljava/lang/Double;", false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, beanSignature, writeMethod, "(Ljava/lang/Double;)V", false); break; case PROPERTY_TYPE_BYTE: mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/sql/ResultSet", "getByte", "(I)B", true); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/sql/ResultSet", "wasNull", "()Z", true); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, processorName, "byteValue", "(BZ)Ljava/lang/Byte;", false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, beanSignature, writeMethod, "(Ljava/lang/Byte;)V", false); break; case PROPERTY_TYPE_SHORT: mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/sql/ResultSet", "getShort", "(I)S", true); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/sql/ResultSet", "wasNull", "()Z", true); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, processorName, "shortValue", "(SZ)Ljava/lang/Short;", false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, beanSignature, writeMethod, "(Ljava/lang/Short;)V", false); break; } }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Generates instructions for printing out a string constant using {@link System#out}. This is useful for debugging. For example, you * can print out lines around your instrumented code to make sure that what you think is being run is actually being run. * @param text text to print out/*from ww w .j a va 2 s. co m*/ * @return instructions to call System.out.println with a string constant * @throws NullPointerException if any argument is {@code null} */ public static InsnList debugPrint(String text) { Validate.notNull(text); InsnList ret = new InsnList(); ret.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;")); ret.add(new LdcInsnNode(text)); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false)); 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)./*from w w w . j a v a2 s.co m*/ * @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
private static InsnList loadOperandStack(Variable arrayStackVar, Variable tempObjectVar, Frame<BasicValue> frame, int start, int end) { Validate.notNull(arrayStackVar);// w ww .ja va2 s . c o m 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// w w w .j a v a2 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//from w w w . j a v a 2 s. com */ 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.MethodInvokeUtils.java
License:Open Source License
/** * Get the number of arguments required for an invocation of some method. This includes the 'this' argument for non-static methods. * <p>// w w w. ja va2s . com * NOTE THAT THIS IS NOT THE NUMBER OF ITEMS ON THE STACK. If the method takes in doubles or longs, each double or long encountered * would be 2 items on the stack. This method returns the number of arguments required for the method to be invoked, not the number of * items required to be on the stack for the method to be invoked. * @param invokeNode the invocation instruction (either normal invocation or invokedynamic) * @return number of arguments required by this method * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if {@code invokeNode} is neither of type {@link MethodInsnNode} nor {@link InvokeDynamicInsnNode}, * or if type of invocation ({@link MethodInsnNode}) cannot be determined */ public static int getArgumentCountRequiredForInvocation(AbstractInsnNode invokeNode) { Validate.notNull(invokeNode); if (invokeNode instanceof MethodInsnNode) { MethodInsnNode methodInsnNode = (MethodInsnNode) invokeNode; int extra; int paramCount; switch (methodInsnNode.getOpcode()) { case Opcodes.INVOKEVIRTUAL: case Opcodes.INVOKESPECIAL: case Opcodes.INVOKEINTERFACE: extra = 1; break; case Opcodes.INVOKESTATIC: extra = 0; break; default: throw new IllegalArgumentException(); // unknown invocation type? probably badly generated instruction node } Type methodType = Type.getType(methodInsnNode.desc); paramCount = methodType.getArgumentTypes().length; return paramCount + extra; } else if (invokeNode instanceof InvokeDynamicInsnNode) { InvokeDynamicInsnNode invokeDynamicInsnNode = (InvokeDynamicInsnNode) invokeNode; int paramCount; Type methodType = Type.getType(invokeDynamicInsnNode.desc); paramCount = methodType.getArgumentTypes().length; return paramCount; } else { throw new IllegalArgumentException(); } }
From source file:com.offbynull.coroutines.instrumenter.asm.MethodInvokeUtilsTest.java
License:Open Source License
@Test public void mustProperlyDetermineStackSizeForNormalMethod() { Type type = Type.getType(MethodUtils.getAccessibleMethod(Integer.class, "compareTo", Integer.class)); MethodInsnNode methodInsnNode = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/util/Integer", "compareTo", type.getDescriptor(), false); int reqStackCount = MethodInvokeUtils.getArgumentCountRequiredForInvocation(methodInsnNode); assertEquals(2, reqStackCount);/*from w w w. jav a 2s . c o m*/ }
From source file:com.offbynull.coroutines.instrumenter.asm.SearchUtils.java
License:Open Source License
/** * Get the number of items that need to be on the stack for an invocation of some method. * @param invokeNode the invocation instruction (either normal invocation or invokedynamic) * @return number of items required on the stack for this method * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if {@code invokeNode} is neither of type {@link MethodInsnNode} nor {@link InvokeDynamicInsnNode}, * or if type of invocation ({@link MethodInsnNode}) cannot be determined *//*from w w w . j a va 2 s . c o m*/ public static int getRequiredStackCountForInvocation(AbstractInsnNode invokeNode) { Validate.notNull(invokeNode); if (invokeNode instanceof MethodInsnNode) { MethodInsnNode methodInsnNode = (MethodInsnNode) invokeNode; int extra; int paramCount; switch (methodInsnNode.getOpcode()) { case Opcodes.INVOKEVIRTUAL: case Opcodes.INVOKESPECIAL: case Opcodes.INVOKEINTERFACE: extra = 1; break; case Opcodes.INVOKESTATIC: extra = 0; break; default: throw new IllegalArgumentException(); // unknown invocation type? probably badly generated instruction node } Type methodType = Type.getType(methodInsnNode.desc); paramCount = methodType.getArgumentTypes().length; return paramCount + extra; } else if (invokeNode instanceof InvokeDynamicInsnNode) { InvokeDynamicInsnNode invokeDynamicInsnNode = (InvokeDynamicInsnNode) invokeNode; int paramCount; Type methodType = Type.getType(invokeDynamicInsnNode.desc); paramCount = methodType.getArgumentTypes().length; return paramCount; } else { throw new IllegalArgumentException(); } }
From source file:com.offbynull.coroutines.instrumenter.asm.SearchUtilsTest.java
License:Open Source License
@Test public void mustProperlyDetermineStackSizeForNormalMethod() { Type type = Type.getType(MethodUtils.getAccessibleMethod(Integer.class, "compareTo", Integer.class)); MethodInsnNode methodInsnNode = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/util/Integer", "compareTo", type.getDescriptor(), false); int reqStackCount = SearchUtils.getRequiredStackCountForInvocation(methodInsnNode); assertEquals(2, reqStackCount);/*from w w w . ja v a 2 s. c o m*/ }