List of usage examples for org.objectweb.asm Opcodes DUP
int DUP
To view the source code for org.objectweb.asm Opcodes DUP.
Click Source Link
From source file:org.jboss.byteman.rule.expression.ReturnExpression.java
License:Open Source License
public void compile(MethodVisitor mv, CompileContext compileContext) throws CompileException { // make sure we are at the right source line compileContext.notifySourceLine(line); Type valueType = (returnValue == null ? Type.VOID : returnValue.getType()); int currentStack = compileContext.getStackCount(); int expected = 1; // ok, we need to create the EarlyReturnException instance and then // initialise it using the appropriate return value or null if no // return value is needed. strictly we should maybe delay the // new until after computing the return expression so we avoid a new // if the expression throws an error. but that means we end up doing // stack manipulations so lets do it the easy way. // create am EarlyReturnException -- adds 1 to stack String exceptionClassName = Type.internalName(EarlyReturnException.class); mv.visitTypeInsn(Opcodes.NEW, exceptionClassName); compileContext.addStackCount(1);/*from ww w . jav a2 s. c om*/ // copy the exception so we can initialise it -- adds 1 to stack mv.visitInsn(Opcodes.DUP); compileContext.addStackCount(1); // stack a string constant to initialise the exception with -- adds 1 to stack mv.visitLdcInsn("return from " + rule.getName()); compileContext.addStackCount(1); // stack any required return value or null -- adds 1 to stack but may use 2 slots if (returnValue != null) { returnValue.compile(mv, compileContext); // we may need to convert from the value type to the return type if (valueType != type) { compileTypeConversion(valueType, type, mv, compileContext); } if (type.isPrimitive()) { // we need an object not a primitive compileBox(Type.boxType(type), mv, compileContext); } } else { // just push null mv.visitInsn(Opcodes.ACONST_NULL); compileContext.addStackCount(1); } // construct the exception -- pops 3 mv.visitMethodInsn(Opcodes.INVOKESPECIAL, exceptionClassName, "<init>", "(Ljava/lang/String;Ljava/lang/Object;)V"); compileContext.addStackCount(-3); // check current stack and increment max stack if necessary if (compileContext.getStackCount() != currentStack + expected) { throw new CompileException("ReturnExpression.compile : invalid stack height " + compileContext.getStackCount() + " expecting " + (currentStack + expected)); } // now insert the throw instruction and decrement the stack height accordingly mv.visitInsn(Opcodes.ATHROW); compileContext.addStackCount(-1); }
From source file:org.jboss.byteman.rule.expression.StaticExpression.java
License:Open Source License
@Override public void compileAssign(MethodVisitor mv, CompileContext compileContext) throws CompileException { // make sure we are at the right source line compileContext.notifySourceLine(line); int currentStack = compileContext.getStackCount(); int size = (type.getNBytes() > 4 ? 2 : 1); // copy the value so we leave a result // increases stack height by size words if (size == 1) { mv.visitInsn(Opcodes.DUP); } else {//from ww w. j ava2s .c o m mv.visitInsn(Opcodes.DUP2); } compileContext.addStackCount(size); // compile a static field update if (isPublicField) { String ownerType = Type.internalName(field.getDeclaringClass()); String fieldName = field.getName(); String fieldType = Type.internalName(field.getType(), true); compileContext.addStackCount(-size); mv.visitFieldInsn(Opcodes.PUTSTATIC, ownerType, fieldName, fieldType); } else { // since this is a private field we need to do the update using reflection // box the value to an object if necessary // [.. val(s) val(s) ==> val(s) valObj] if (type.isPrimitive()) { compileBox(Type.boxType(type), mv, compileContext); } // stack the helper and then swap it so it goes under the value // [.. val(s) valObj ==> val(s) valObj helper ==> val(s) helper valObj] mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitInsn(Opcodes.SWAP); // stack a null owner then swap it so it goes under the value // [val(s) helper valObj ==> val(s) helper valObj null ==> val(s) helper null valObj] mv.visitInsn(Opcodes.ACONST_NULL); mv.visitInsn(Opcodes.SWAP); // now stack the field index // [.. val(s) helper null valObj ==> val(s) helper null valObj index ] mv.visitLdcInsn(fieldIndex); // we added three more words compileContext.addStackCount(3); // use the HelperAdapter method setAccessibleField to set the field value mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.internalName(HelperAdapter.class), "setAccessibleField", "(Ljava/lang/Object;Ljava/lang/Object;I)V"); // we popped four args compileContext.addStackCount(-4); } if (compileContext.getStackCount() != currentStack) { throw new CompileException("StaticExpression.compileAssign : invalid stack height " + compileContext.getStackCount() + " expecting " + currentStack); } }
From source file:org.jboss.byteman.rule.expression.StringPlusExpression.java
License:Open Source License
public void compile(MethodVisitor mv, CompileContext compileContext) throws CompileException { // make sure we are at the right source line compileContext.notifySourceLine(line); Expression oper0 = getOperand(0); Expression oper1 = getOperand(1); int currentStack = compileContext.getStackCount(); int expected = 1; // compile and type convert each operand n.b. the type conversion will ensure that // null operands are replaced with "null" oper0.compile(mv, compileContext);/*from www.j a v a2 s .co m*/ compileTypeConversion(oper0.getType(), type, mv, compileContext); oper1.compile(mv, compileContext); compileTypeConversion(oper1.getType(), type, mv, compileContext); // ok, we could optimize this for the case where the left or right operand is a String plus expression // by employing a StringBuffer but for now we will just evaluate the left and right operand and // then call concat to join them // add two strings leaving one string // if second operand is null replace it with "null" Label skiptarget = new Label(); // this adds a word then removes it -- do so to ensure the max height gets updated if need be mv.visitInsn(Opcodes.DUP); compileContext.addStackCount(1); // if it is not null we skip to the concat operation mv.visitJumpInsn(Opcodes.IFNONNULL, skiptarget); compileContext.addStackCount(-1); // it's null so we have to swap it fdr "null" mv.visitInsn(Opcodes.POP); mv.visitLdcInsn("null"); mv.visitLabel(skiptarget); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "concat", "(Ljava/lang/String;)Ljava/lang/String;"); compileContext.addStackCount(-1); if (compileContext.getStackCount() != currentStack + expected) { throw new CompileException("StringPlusExpression.compile : invalid stack height " + compileContext.getStackCount() + " expecting " + currentStack + expected); } }
From source file:org.jboss.byteman.rule.expression.ThrowExpression.java
License:Open Source License
public void compile(MethodVisitor mv, CompileContext compileContext) throws CompileException { // make sure we are at the right source line compileContext.notifySourceLine(line); int currentStack = compileContext.getStackCount(); int expected = 1; int extraParams = 0; // ok, we need to create the thrown exception instance and then // initialise it. // create the thrown exception instance -- adds 1 to stack String exceptionClassName = type.getInternalName(); mv.visitTypeInsn(Opcodes.NEW, exceptionClassName); compileContext.addStackCount(1);/*from ww w .ja va2s.c o m*/ // copy the exception so we can init it mv.visitInsn(Opcodes.DUP); compileContext.addStackCount(1); int argCount = arguments.size(); // stack each of the arguments to the constructor for (int i = 0; i < argCount; i++) { Type argType = argumentTypes.get(i); Type paramType = paramTypes.get(i); int paramCount = (paramType.getNBytes() > 4 ? 2 : 1); // track extra storage used after type conversion extraParams += (paramCount); arguments.get(i).compile(mv, compileContext); compileTypeConversion(argType, paramType, mv, compileContext); } // construct the exception mv.visitMethodInsn(Opcodes.INVOKESPECIAL, exceptionClassName, "<init>", getDescriptor()); // modify the stack height to account for the removed exception and params compileContext.addStackCount(-(extraParams + 1)); if (compileContext.getStackCount() != currentStack + expected) { throw new CompileException("ThrowExpression.compile : invalid stack height " + compileContext.getStackCount() + " expecting " + (currentStack + expected)); } // now create a ThrowException to wrap the user exception // create the thrown exception instance -- adds 1 to stack [UE] --> [UE, THE] exceptionClassName = "org/jboss/byteman/rule/exception/ThrowException"; mv.visitTypeInsn(Opcodes.NEW, exceptionClassName); compileContext.addStackCount(1); // copy the ThrowException so we can init it [UE, THE] --> [THE, UE, THE] mv.visitInsn(Opcodes.DUP_X1); compileContext.addStackCount(1); // reverse the order of the top two words [THE, UE, THE] --> [THE, THE, UE] mv.visitInsn(Opcodes.SWAP); // construct the exception [THE, THE, UE] --> [UE] mv.visitMethodInsn(Opcodes.INVOKESPECIAL, exceptionClassName, "<init>", "(Ljava/lang/Throwable;)V"); // we should now have just the ThrowException on the stack compileContext.addStackCount(-2); if (compileContext.getStackCount() != currentStack + expected) { throw new CompileException("ThrowExpression.compile : invalid stack height " + compileContext.getStackCount() + " expecting " + (currentStack + expected)); } // now throw the exception and decrement the stack height mv.visitInsn(Opcodes.ATHROW); compileContext.addStackCount(-1); }
From source file:org.jboss.byteman.rule.expression.Variable.java
License:Open Source License
@Override public void compileAssign(MethodVisitor mv, CompileContext compileContext) throws CompileException { // make sure we are at the right source line compileContext.notifySourceLine(line); int currentStack = compileContext.getStackCount(); int size = ((type.getNBytes() > 4) ? 2 : 1); int max;//from w w w . j a v a 2s. c om // value to be assigned is TOS and will already be coerced to the correct value type // copy it so we leave it as a a return value on the stack if (size == 2) { // [... val1 val2 ==> ... val1 val2 val1 val2] mv.visitInsn(Opcodes.DUP2); } else { // [... val ==> ... val val] mv.visitInsn(Opcodes.DUP); } // stack the current helper then insert it below the value mv.visitVarInsn(Opcodes.ALOAD, 0); if (size == 2) { // use a DUP_X2 to push a copy below the value then pop the redundant value // [... val1 val2 val1 val2 helper ==> ... val1 val2 helper val1 val2 helper] mv.visitInsn(Opcodes.DUP_X2); // [... val1 val2 helper val1 val2 helper ==> ... val1 val2 helper val1 val2] mv.visitInsn(Opcodes.POP); } else { // we can just swap the two values // [... val val helper ==> ... val helper val] mv.visitInsn(Opcodes.SWAP); } // stack the name for the variable and swap below the value mv.visitLdcInsn(name); if (size == 2) { // use a DUP_X2 to push a copy below the value then pop the redundant value // [... val1 val2 helper val1 val2 name ==> [... val1 val2 helper name val1 val2 name] mv.visitInsn(Opcodes.DUP_X2); // this is the high water mark compileContext.addStackCount(5); // [... val1 val2 helper name val1 val2 name ==> [... val1 val2 helper name val1 val2] mv.visitInsn(Opcodes.POP); compileContext.addStackCount(-1); // and now we have the desired arrangement for the call[.. val1 val2 helper name val1 val2] } else { // this is the high water mark // at this point the stack has gone from [ .. val] to [.. val helper val name] compileContext.addStackCount(3); // we can just swap the two values // [... val helper val name ==> ... val helper name val] mv.visitInsn(Opcodes.SWAP); // and now we have the desired arrangement for the call[.. val helper name val] } // ensure we have an object compileObjectConversion(type, Type.OBJECT, mv, compileContext); // call the setBinding method mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.internalName(HelperAdapter.class), "setBinding", "(Ljava/lang/String;Ljava/lang/Object;)V"); // the call will remove 3 from the stack height compileContext.addStackCount(-3); // ok, the stack height should be as it was if (compileContext.getStackCount() != currentStack) { throw new CompileException("variable.compileAssignment : invalid stack height " + compileContext.getStackCount() + " expecting " + currentStack); } }
From source file:org.jboss.byteman.rule.RuleElement.java
License:Open Source License
protected void compileStringConversion(Type fromType, Type toType, MethodVisitor mv, CompileContext compileContext) throws CompileException { assert toType == Type.STRING; if (fromType.isObject() || fromType.isArray() || (fromType.isNumeric() && !fromType.isPrimitive())) { // use the toString method if the object is non null otherwise just replace it with null Label elseLabel = new Label(); Label endLabel = new Label(); // if (object == null) mv.visitInsn(Opcodes.DUP); // the above dup bumps the stack height compileContext.addStackCount(1); mv.visitJumpInsn(Opcodes.IFNONNULL, elseLabel); compileContext.addStackCount(-1); // then string = "null" mv.visitInsn(Opcodes.POP);/*from ww w . j a va 2s . co m*/ mv.visitInsn(Opcodes.ACONST_NULL); mv.visitJumpInsn(Opcodes.GOTO, endLabel); // else string = object.toString() mv.visitLabel(elseLabel); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;"); mv.visitLabel(endLabel); } else if (fromType == Type.Z) { // use the toString method mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "toString", "(Z)Ljava/lang/String;"); } else if (fromType == Type.B) { // use the toString method mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "toString", "(B)Ljava/lang/String;"); } else if (fromType == Type.S) { // use the toString method mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "toString", "(S)Ljava/lang/String;"); } else if (fromType == Type.C) { // use the toString method mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "toString", "(C)Ljava/lang/String;"); } else if (fromType == Type.I) { // use the toString method mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "toString", "(I)Ljava/lang/String;"); } else if (fromType == Type.J) { // use the toString method mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "toString", "(J)Ljava/lang/String;"); compileContext.addStackCount(-1); } else if (fromType == Type.F) { // use the toString method mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "toString", "(F)Ljava/lang/String;"); } else if (fromType == Type.D) { // use the toString method mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "toString", "(D)Ljava/lang/String;"); compileContext.addStackCount(-1); } }
From source file:org.jooby.internal.apitool.BytecodeRouteParser.java
License:Apache License
private java.lang.reflect.Type parameterType(final ClassLoader loader, final AbstractInsnNode n) { if (n instanceof MethodInsnNode) { MethodInsnNode node = (MethodInsnNode) n; if (mutantValue().test(node)) { /** value(); intValue(); booleanValue(); */ return TypeDescriptorParser.parse(loader, node.desc); } else if (mutantToSomething().test(node) || getOrCreateKotlinClass().test(node)) { /** to(String.class); toOptional; toList(); */ String owner = Type.getReturnType(node.desc).getClassName(); AbstractInsnNode prev = node.getPrevious(); if (prev instanceof FieldInsnNode && ((MethodInsnNode) n).name.equals("toEnum")) { /** toEnum(Letter.A); */ return loadType(loader, ((FieldInsnNode) prev).owner); }/*from w w w. j av a 2s. c o m*/ java.lang.reflect.Type toType = String.class; if (prev instanceof LdcInsnNode) { /** to(Foo.class); */ Object cst = ((LdcInsnNode) prev).cst; if (cst instanceof Type) { toType = loadType(loader, ((Type) cst).getClassName()); } } else if (prev instanceof FieldInsnNode) { toType = loadType(loader, ((FieldInsnNode) prev).owner); } // JoobyKt.toOptional AbstractInsnNode next = node.getNext(); if (next instanceof MethodInsnNode) { String joobyKt = ((MethodInsnNode) next).owner; String methodName = ((MethodInsnNode) next).name; if ("toOptional".equals(methodName) && "org/jooby/JoobyKt".equals(joobyKt)) { owner = Optional.class.getName(); } } Set<String> skipOwners = ImmutableSet.of(Object.class.getName(), Enum.class.getName(), "kotlin.reflect.KClass"); if (skipOwners.contains(owner)) { return toType; } /** toList(Foo.class); */ return Types.newParameterizedType(loadType(loader, owner), toType); } } else if (n instanceof VarInsnNode) { return new Insn<>(null, n).prev().filter(is(MethodInsnNode.class)).findFirst() .map(MethodInsnNode.class::cast).filter(file()).map(m -> { return m.name.equals("files") ? Types.newParameterizedType(List.class, File.class) : File.class; }).orElse(Object.class); } else if (n instanceof TypeInsnNode) { TypeInsnNode typeInsn = (TypeInsnNode) n; if (typeInsn.getOpcode() == Opcodes.CHECKCAST) { return loadType(loader, typeInsn.desc); } } else if (n != null && Opcodes.DUP == n.getOpcode()) { // Kotlin 1.2.x // mv.visitInsn(DUP); // mv.visitLdcInsn("req.param(\"p1\")"); // mv.visitMethodInsn(INVOKESTATIC, "kotlin/jvm/internal/Intrinsics", "checkExpressionValueIsNotNull", "(Ljava/lang/Object;Ljava/lang/String;)V", false); // mv.visitMethodInsn(INVOKESTATIC, "org/jooby/JoobyKt", "getValue", "(Lorg/jooby/Mutant;)Ljava/lang/String;", false); AbstractInsnNode next = new Insn<>(null, n).next().filter(MethodInsnNode.class::isInstance).skip(1) .findFirst().orElse(null); java.lang.reflect.Type result = parameterType(loader, next); if (result == Object.class) { next = new Insn<>(null, n).next().filter(TypeInsnNode.class::isInstance).findFirst().orElse(null); result = parameterType(loader, next); } return result; } else if (n instanceof FieldInsnNode) { AbstractInsnNode next = n.getNext(); if (next instanceof MethodInsnNode) { if (((MethodInsnNode) next).name.equals("toOptional")) { return Types.newParameterizedType(Optional.class, loadType(loader, ((FieldInsnNode) n).owner)); } else if (((MethodInsnNode) next).name.equals("getOrCreateKotlinClass")) { return loadType(loader, ((FieldInsnNode) n).owner); } } } return Object.class; }
From source file:org.lambdamatic.analyzer.ast.LambdaExpressionReader.java
License:Open Source License
/** * Reads the current {@link InsnNode} instruction and returns a {@link Statement} or {@code null} * if the instruction is not a full statement (in that case, the instruction is stored in the * given Expression {@link Stack}).//from w w w .j av a 2s. c o m * * @param insnNode the instruction to read * @param expressionStack the expression stack to put on or pop from. * @param localVariables the local variables * @return a {@link List} of {@link Statement} or empty list if no {@link Statement} was created * after reading the current instruction. * @see <a href="https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings">Java bytcode * instruction listings on Wikipedia</a> */ private List<Statement> readInstruction(final InsnCursor insnCursor, final Stack<Expression> expressionStack, final List<CapturedArgument> capturedArguments, final LocalVariables localVariables) { final List<Statement> statements = new ArrayList<>(); final AbstractInsnNode insnNode = insnCursor.getCurrent(); switch (insnNode.getOpcode()) { // return a reference from a method case Opcodes.ARETURN: // return an integer from a method case Opcodes.IRETURN: statements.add(new ReturnStatement(expressionStack.pop())); break; // return void from method case Opcodes.RETURN: // wrap all pending expressions into ExpressionStatements while (!expressionStack.isEmpty()) { final Expression pendingExpression = expressionStack.pop(); statements.add(new ExpressionStatement(pendingExpression)); } break; // push a null reference onto the stack case Opcodes.ACONST_NULL: expressionStack.add(new NullLiteral()); break; // load the int value 0 onto the stack case Opcodes.ICONST_0: // applies for byte, short, int and boolean expressionStack.add(new NumberLiteral(0)); break; // load the int value 1 onto the stack case Opcodes.ICONST_1: // applies for byte, short, int and boolean expressionStack.add(new NumberLiteral(1)); break; // load the int value 2 onto the stack case Opcodes.ICONST_2: expressionStack.add(new NumberLiteral(2)); break; // load the int value 3 onto the stack case Opcodes.ICONST_3: expressionStack.add(new NumberLiteral(3)); break; // load the int value 4 onto the stack case Opcodes.ICONST_4: expressionStack.add(new NumberLiteral(4)); break; // load the int value 5 onto the stack case Opcodes.ICONST_5: expressionStack.add(new NumberLiteral(5)); break; // push the long 0 onto the stack case Opcodes.LCONST_0: expressionStack.add(new NumberLiteral(0L)); break; // push the long 1 onto the stack case Opcodes.LCONST_1: expressionStack.add(new NumberLiteral(1L)); break; // push the 0.0f onto the stack case Opcodes.FCONST_0: expressionStack.add(new NumberLiteral(0f)); break; // push the 1.0f onto the stack case Opcodes.FCONST_1: expressionStack.add(new NumberLiteral(1f)); break; // push the 2.0f onto the stack case Opcodes.FCONST_2: expressionStack.add(new NumberLiteral(2f)); break; // push the constant 0.0 onto the stack case Opcodes.DCONST_0: expressionStack.add(new NumberLiteral(0d)); break; // push the constant 1.0 onto the stack case Opcodes.DCONST_1: expressionStack.add(new NumberLiteral(1d)); break; // compare two longs values case Opcodes.LCMP: // compare two doubles case Opcodes.DCMPL: // compare two doubles case Opcodes.DCMPG: // compare two floats case Opcodes.FCMPL: // compare two floats case Opcodes.FCMPG: statements.addAll( readJumpInstruction(insnCursor.next(), expressionStack, capturedArguments, localVariables)); break; // add 2 ints case Opcodes.IADD: expressionStack.add(readOperation(Operator.ADD, expressionStack)); break; // int subtract case Opcodes.ISUB: expressionStack.add(readOperation(Operator.SUBTRACT, expressionStack)); break; // multiply 2 integers case Opcodes.IMUL: expressionStack.add(readOperation(Operator.MULTIPLY, expressionStack)); break; // divide 2 integers case Opcodes.IDIV: expressionStack.add(readOperation(Operator.DIVIDE, expressionStack)); break; // negate int case Opcodes.INEG: expressionStack.add(inverseInteger(expressionStack)); break; // discard the top value on the stack case Opcodes.POP: statements.add(new ExpressionStatement(expressionStack.pop())); break; // duplicate the value on top of the stack case Opcodes.DUP: expressionStack.push(expressionStack.peek()); break; // insert a copy of the top value into the stack two values from the top. case Opcodes.DUP_X1: expressionStack.add(expressionStack.size() - 2, expressionStack.peek()); break; // store into a reference in an array case Opcodes.AASTORE: readArrayStoreInstruction(insnNode, expressionStack); break; // converts Float to Double -> ignored. case Opcodes.F2D: break; default: throw new AnalyzeException( "Bytecode instruction with OpCode '" + insnNode.getOpcode() + "' is not supported."); } return statements; }
From source file:org.mbte.groovypp.compiler.bytecode.BytecodeExpr.java
License:Apache License
/** * box the primitive value on the stack//from ww w. j a va2 s . co m * * @param type * @param mv */ public void quickBoxIfNecessary(ClassNode type, MethodVisitor mv) { String descr = getTypeDescription(type); if (type == boolean_TYPE) { boxBoolean(mv); } else if (isPrimitiveType(type) && type != VOID_TYPE) { ClassNode wrapper = TypeUtil.wrapSafely(type); String internName = getClassInternalName(wrapper); mv.visitTypeInsn(Opcodes.NEW, internName); mv.visitInsn(Opcodes.DUP); if (type == double_TYPE || type == long_TYPE) { mv.visitInsn(Opcodes.DUP2_X2); mv.visitInsn(Opcodes.POP2); } else { mv.visitInsn(Opcodes.DUP2_X1); mv.visitInsn(Opcodes.POP2); } mv.visitMethodInsn(Opcodes.INVOKESPECIAL, internName, "<init>", "(" + descr + ")V"); } }
From source file:org.mbte.groovypp.compiler.bytecode.BytecodeExpr.java
License:Apache License
/** * load the constant on the operand stack. primitives auto-boxed. *///ww w.ja va 2 s .c o m void loadConstant(Object value, MethodVisitor mv) { if (value == null) { mv.visitInsn(Opcodes.ACONST_NULL); } else if (value instanceof String) { mv.visitLdcInsn(value); } else if (value instanceof Character) { String className = "java/lang/Character"; mv.visitTypeInsn(Opcodes.NEW, className); mv.visitInsn(Opcodes.DUP); mv.visitLdcInsn(value); String methodType = "(C)V"; mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, "<init>", methodType); } else if (value instanceof Number) { /** todo it would be more efficient to generate class constants */ Number n = (Number) value; String className = BytecodeHelper.getClassInternalName(value.getClass().getName()); mv.visitTypeInsn(Opcodes.NEW, className); mv.visitInsn(Opcodes.DUP); String methodType; if (n instanceof Integer) { //pushConstant(n.intValue()); mv.visitLdcInsn(n); methodType = "(I)V"; } else if (n instanceof Double) { mv.visitLdcInsn(n); methodType = "(D)V"; } else if (n instanceof Float) { mv.visitLdcInsn(n); methodType = "(F)V"; } else if (n instanceof Long) { mv.visitLdcInsn(n); methodType = "(J)V"; } else if (n instanceof BigDecimal) { mv.visitLdcInsn(n.toString()); methodType = "(Ljava/lang/String;)V"; } else if (n instanceof BigInteger) { mv.visitLdcInsn(n.toString()); methodType = "(Ljava/lang/String;)V"; } else if (n instanceof Short) { mv.visitLdcInsn(n); methodType = "(S)V"; } else if (n instanceof Byte) { mv.visitLdcInsn(n); methodType = "(B)V"; } else { throw new ClassGeneratorException("Cannot generate bytecode for constant: " + value + " of type: " + value.getClass().getName() + ". Numeric constant type not supported."); } mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, "<init>", methodType); } else if (value instanceof Boolean) { Boolean bool = (Boolean) value; String text = (bool.booleanValue()) ? "TRUE" : "FALSE"; mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Boolean", text, "Ljava/lang/Boolean;"); } else if (value instanceof Class) { Class vc = (Class) value; if (vc.getName().equals("java.lang.Void")) { // load nothing here for void } else { throw new ClassGeneratorException("Cannot generate bytecode for constant: " + value + " of type: " + value.getClass().getName()); } } else { throw new ClassGeneratorException( "Cannot generate bytecode for constant: " + value + " of type: " + value.getClass().getName()); } }