org.springframework.asm.MethodVisitor

Here are the examples of the java api org.springframework.asm.MethodVisitor taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

89 Examples 7

19 View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus

/**
 * For use in mathematical operators, handles converting from a (possibly boxed)
 * number on the stack to a primitive numeric type.
 * <p>For example, from a Integer to a double, just need to call 'Number.doubleValue()'
 * but from an int to a double, need to use the bytecode 'i2d'.
 * @param mv the method visitor when instructions should be appended
 * @param stackDescriptor a descriptor of the operand on the stack
 * @param targetDescriptor a primitive type descriptor
 */
public static void insertNumericUnboxOrPrimitiveTypeCoercion(MethodVisitor mv, @Nullable String stackDescriptor, char targetDescriptor) {
    if (!CodeFlow.isPrimitive(stackDescriptor)) {
        CodeFlow.insertUnboxNumberInsns(mv, targetDescriptor, stackDescriptor);
    } else {
        CodeFlow.insertAnyNecessaryTypeConversionBytecodes(mv, targetDescriptor, stackDescriptor);
    }
}

19 View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus

/**
 * Push the byte code to load the target (i.e. what was preplaceded as the first argument
 * to CompiledExpression.getValue(target, context))
 * @param mv the visitor into which the load instruction should be inserted
 */
public void loadTarget(MethodVisitor mv) {
    mv.visitVarInsn(ALOAD, 1);
}

19 View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus

/**
 * Push the bytecode to load the EvaluationContext (the second parameter preplaceded to
 * the compiled expression method).
 * @param mv the visitor into which the load instruction should be inserted
 * @since 4.3.4
 */
public void loadEvaluationContext(MethodVisitor mv) {
    mv.visitVarInsn(ALOAD, 2);
}

19 View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus

/**
 * Determine the appropriate boxing instruction for a specific type (if it needs
 * boxing) and insert the instruction into the supplied visitor.
 * @param mv the target visitor for the new instructions
 * @param descriptor the descriptor of a type that may or may not need boxing
 */
public static void insertBoxIfNecessary(MethodVisitor mv, @Nullable String descriptor) {
    if (descriptor != null && descriptor.length() == 1) {
        insertBoxIfNecessary(mv, descriptor.charAt(0));
    }
}

19 View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus

/**
 * If the codeflow shows the last expression evaluated to java.lang.Boolean then
 * insert the necessary instructions to unbox that to a boolean primitive.
 * @param mv the visitor into which new instructions should be inserted
 */
public void unboxBooleanIfNecessary(MethodVisitor mv) {
    if ("Ljava/lang/Boolean".equals(lastDescriptor())) {
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
    }
}

19 View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus

/**
 * Determine the appropriate boxing instruction for a specific type (if it needs
 * boxing) and insert the instruction into the supplied visitor.
 * @param mv the target visitor for the new instructions
 * @param ch the descriptor of the type that might need boxing
 */
public static void insertBoxIfNecessary(MethodVisitor mv, char ch) {
    switch(ch) {
        case 'Z':
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
            break;
        case 'B':
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
            break;
        case 'C':
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
            break;
        case 'D':
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
            break;
        case 'F':
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
            break;
        case 'I':
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
            break;
        case 'J':
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
            break;
        case 'S':
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
            break;
        case 'L':
        case 'V':
        case '[':
            // no box needed
            break;
        default:
            throw new IllegalArgumentException("Boxing should not be attempted for descriptor '" + ch + "'");
    }
}

19 View Source File : SpelNodeImpl.java
License : MIT License
Project Creator : Vip-Augus

/**
 * Generate the bytecode for this node into the supplied visitor. Context info about
 * the current expression being compiled is available in the codeflow object, e.g.
 * including information about the type of the object currently on the stack.
 * @param mv the ASM MethodVisitor into which code should be generated
 * @param cf a context object with info about what is on the stack
 */
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    throw new IllegalStateException(getClreplaced().getName() + " has no generateCode(..) method");
}

19 View Source File : CodeFlow.java
License : Apache License 2.0
Project Creator : langtianya

/**
 * Determine the appropriate boxing instruction for a specific type (if it needs
 * boxing) and insert the instruction into the supplied visitor.
 * @param mv the target visitor for the new instructions
 * @param descriptor the descriptor of a type that may or may not need boxing
 */
public static void insertBoxIfNecessary(MethodVisitor mv, String descriptor) {
    if (descriptor.length() == 1) {
        insertBoxIfNecessary(mv, descriptor.charAt(0));
    }
}

19 View Source File : CodeFlow.java
License : Apache License 2.0
Project Creator : langtianya

/**
 * If the codeflow shows the last expression evaluated to java.lang.Boolean then
 * insert the necessary instructions to unbox that to a boolean primitive.
 * @param mv the visitor into which new instructions should be inserted
 */
public void unboxBooleanIfNecessary(MethodVisitor mv) {
    if (lastDescriptor().equals("Ljava/lang/Boolean")) {
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
    }
}

19 View Source File : CodeFlow.java
License : Apache License 2.0
Project Creator : langtianya

/**
 * For use in mathematical operators, handles converting from a (possibly boxed)
 * number on the stack to a primitive numeric type.
 * <p>For example, from a Integer to a double, just need to call 'Number.doubleValue()'
 * but from an int to a double, need to use the bytecode 'i2d'.
 * @param mv the method visitor when instructions should be appended
 * @param stackDescriptor a descriptor of the operand on the stack
 * @param targetDescriptor a primitive type descriptor
 */
public static void insertNumericUnboxOrPrimitiveTypeCoercion(MethodVisitor mv, String stackDescriptor, char targetDescriptor) {
    if (!CodeFlow.isPrimitive(stackDescriptor)) {
        CodeFlow.insertUnboxNumberInsns(mv, targetDescriptor, stackDescriptor);
    } else {
        CodeFlow.insertAnyNecessaryTypeConversionBytecodes(mv, targetDescriptor, stackDescriptor);
    }
}

19 View Source File : SpelNodeImpl.java
License : Apache License 2.0
Project Creator : langtianya

/**
 * Generate the bytecode for this node into the supplied visitor. Context info about
 * the current expression being compiled is available in the codeflow object. For
 * example it will include information about the type of the object currently
 * on the stack.
 * @param mv the ASM MethodVisitor into which code should be generated
 * @param cf a context object with info about what is on the stack
 */
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    throw new IllegalStateException(getClreplaced().getName() + " has no generateCode(..) method");
}

18 View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus

/**
 * Insert any necessary cast and value call to convert from a boxed type to a
 * primitive value.
 * @param mv the method visitor into which instructions should be inserted
 * @param ch the primitive type desired as output
 * @param stackDescriptor the descriptor of the type on top of the stack
 */
public static void insertUnboxInsns(MethodVisitor mv, char ch, @Nullable String stackDescriptor) {
    if (stackDescriptor == null) {
        return;
    }
    switch(ch) {
        case 'Z':
            if (!stackDescriptor.equals("Ljava/lang/Boolean")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
            break;
        case 'B':
            if (!stackDescriptor.equals("Ljava/lang/Byte")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Byte");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false);
            break;
        case 'C':
            if (!stackDescriptor.equals("Ljava/lang/Character")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false);
            break;
        case 'D':
            if (!stackDescriptor.equals("Ljava/lang/Double")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Double");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
            break;
        case 'F':
            if (!stackDescriptor.equals("Ljava/lang/Float")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Float");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
            break;
        case 'I':
            if (!stackDescriptor.equals("Ljava/lang/Integer")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
            break;
        case 'J':
            if (!stackDescriptor.equals("Ljava/lang/Long")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Long");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
            break;
        case 'S':
            if (!stackDescriptor.equals("Ljava/lang/Short")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Short");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false);
            break;
        default:
            throw new IllegalArgumentException("Unboxing should not be attempted for descriptor '" + ch + "'");
    }
}

18 View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus

/**
 * Insert the appropriate CHECKCAST instruction for the supplied descriptor.
 * @param mv the target visitor into which the instruction should be inserted
 * @param descriptor the descriptor of the type to cast to
 */
public static void insertCheckCast(MethodVisitor mv, @Nullable String descriptor) {
    if (descriptor != null && descriptor.length() != 1) {
        if (descriptor.charAt(0) == '[') {
            if (isPrimitiveArray(descriptor)) {
                mv.visitTypeInsn(CHECKCAST, descriptor);
            } else {
                mv.visitTypeInsn(CHECKCAST, descriptor + ";");
            }
        } else {
            if (!descriptor.equals("Ljava/lang/Object")) {
                // This is chopping off the 'L' to leave us with "java/lang/String"
                mv.visitTypeInsn(CHECKCAST, descriptor.substring(1));
            }
        }
    }
}

18 View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus

/**
 * Insert any necessary numeric conversion bytecodes based upon what is on the stack and the desired target type.
 * @param mv the method visitor into which instructions should be placed
 * @param targetDescriptor the (primitive) descriptor of the target type
 * @param stackDescriptor the descriptor of the operand on top of the stack
 */
public static void insertAnyNecessaryTypeConversionBytecodes(MethodVisitor mv, char targetDescriptor, String stackDescriptor) {
    if (CodeFlow.isPrimitive(stackDescriptor)) {
        char stackTop = stackDescriptor.charAt(0);
        if (stackTop == 'I' || stackTop == 'B' || stackTop == 'S' || stackTop == 'C') {
            if (targetDescriptor == 'D') {
                mv.visitInsn(I2D);
            } else if (targetDescriptor == 'F') {
                mv.visitInsn(I2F);
            } else if (targetDescriptor == 'J') {
                mv.visitInsn(I2L);
            } else if (targetDescriptor == 'I') {
            // nop
            } else {
                throw new IllegalStateException("Cannot get from " + stackTop + " to " + targetDescriptor);
            }
        } else if (stackTop == 'J') {
            if (targetDescriptor == 'D') {
                mv.visitInsn(L2D);
            } else if (targetDescriptor == 'F') {
                mv.visitInsn(L2F);
            } else if (targetDescriptor == 'J') {
            // nop
            } else if (targetDescriptor == 'I') {
                mv.visitInsn(L2I);
            } else {
                throw new IllegalStateException("Cannot get from " + stackTop + " to " + targetDescriptor);
            }
        } else if (stackTop == 'F') {
            if (targetDescriptor == 'D') {
                mv.visitInsn(F2D);
            } else if (targetDescriptor == 'F') {
            // nop
            } else if (targetDescriptor == 'J') {
                mv.visitInsn(F2L);
            } else if (targetDescriptor == 'I') {
                mv.visitInsn(F2I);
            } else {
                throw new IllegalStateException("Cannot get from " + stackTop + " to " + targetDescriptor);
            }
        } else if (stackTop == 'D') {
            if (targetDescriptor == 'D') {
            // nop
            } else if (targetDescriptor == 'F') {
                mv.visitInsn(D2F);
            } else if (targetDescriptor == 'J') {
                mv.visitInsn(D2L);
            } else if (targetDescriptor == 'I') {
                mv.visitInsn(D2I);
            } else {
                throw new IllegalStateException("Cannot get from " + stackDescriptor + " to " + targetDescriptor);
            }
        }
    }
}

18 View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus

/**
 * For numbers, use the appropriate method on the number to convert it to the primitive type requested.
 * @param mv the method visitor into which instructions should be inserted
 * @param targetDescriptor the primitive type desired as output
 * @param stackDescriptor the descriptor of the type on top of the stack
 */
public static void insertUnboxNumberInsns(MethodVisitor mv, char targetDescriptor, @Nullable String stackDescriptor) {
    if (stackDescriptor == null) {
        return;
    }
    switch(targetDescriptor) {
        case 'D':
            if (stackDescriptor.equals("Ljava/lang/Object")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "doubleValue", "()D", false);
            break;
        case 'F':
            if (stackDescriptor.equals("Ljava/lang/Object")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "floatValue", "()F", false);
            break;
        case 'J':
            if (stackDescriptor.equals("Ljava/lang/Object")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "longValue", "()J", false);
            break;
        case 'I':
            if (stackDescriptor.equals("Ljava/lang/Object")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "intValue", "()I", false);
            break;
        // does not handle Z, B, C, S
        default:
            throw new IllegalArgumentException("Unboxing should not be attempted for descriptor '" + targetDescriptor + "'");
    }
}

18 View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus

/**
 * Produce appropriate bytecode to store a stack item in an array. The
 * instruction to use varies depending on whether the type
 * is a primitive or reference type.
 * @param mv where to insert the bytecode
 * @param arrayElementType the type of the array elements
 */
public static void insertArrayStore(MethodVisitor mv, String arrayElementType) {
    if (arrayElementType.length() == 1) {
        switch(arrayElementType.charAt(0)) {
            case 'I':
                mv.visitInsn(IASTORE);
                break;
            case 'J':
                mv.visitInsn(LASTORE);
                break;
            case 'F':
                mv.visitInsn(FASTORE);
                break;
            case 'D':
                mv.visitInsn(DASTORE);
                break;
            case 'B':
                mv.visitInsn(BASTORE);
                break;
            case 'C':
                mv.visitInsn(CASTORE);
                break;
            case 'S':
                mv.visitInsn(SASTORE);
                break;
            case 'Z':
                mv.visitInsn(BASTORE);
                break;
            default:
                throw new IllegalArgumentException("Unexpected arraytype " + arrayElementType.charAt(0));
        }
    } else {
        mv.visitInsn(AASTORE);
    }
}

18 View Source File : StringLiteral.java
License : MIT License
Project Creator : Vip-Augus

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    mv.visitLdcInsn(this.value.getValue());
    cf.pushDescriptor(this.exitTypeDescriptor);
}

18 View Source File : OpLT.java
License : MIT License
Project Creator : Vip-Augus

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    generateComparisonCode(mv, cf, IFGE, IF_ICMPGE);
}

18 View Source File : OpLE.java
License : MIT License
Project Creator : Vip-Augus

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    generateComparisonCode(mv, cf, IFGT, IF_ICMPGT);
}

18 View Source File : OpGT.java
License : MIT License
Project Creator : Vip-Augus

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    generateComparisonCode(mv, cf, IFLE, IF_ICMPLE);
}

18 View Source File : OpGE.java
License : MIT License
Project Creator : Vip-Augus

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    generateComparisonCode(mv, cf, IFLT, IF_ICMPLT);
}

18 View Source File : CompoundExpression.java
License : MIT License
Project Creator : Vip-Augus

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    for (SpelNodeImpl child : this.children) {
        child.generateCode(mv, cf);
    }
    cf.pushDescriptor(this.exitTypeDescriptor);
}

18 View Source File : BooleanLiteral.java
License : MIT License
Project Creator : Vip-Augus

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    if (this.value == BooleanTypedValue.TRUE) {
        mv.visitLdcInsn(1);
    } else {
        mv.visitLdcInsn(0);
    }
    cf.pushDescriptor(this.exitTypeDescriptor);
}

18 View Source File : CompoundExpression.java
License : MIT License
Project Creator : mindcarver

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    for (int i = 0; i < this.children.length; i++) {
        this.children[i].generateCode(mv, cf);
    }
    cf.pushDescriptor(this.exitTypeDescriptor);
}

18 View Source File : CodeFlow.java
License : Apache License 2.0
Project Creator : langtianya

/**
 * Insert the appropriate CHECKCAST instruction for the supplied descriptor.
 * @param mv the target visitor into which the instruction should be inserted
 * @param descriptor the descriptor of the type to cast to
 */
public static void insertCheckCast(MethodVisitor mv, String descriptor) {
    if (descriptor.length() != 1) {
        if (descriptor.charAt(0) == '[') {
            if (isPrimitiveArray(descriptor)) {
                mv.visitTypeInsn(CHECKCAST, descriptor);
            } else {
                mv.visitTypeInsn(CHECKCAST, descriptor + ";");
            }
        } else {
            if (!descriptor.equals("Ljava/lang/Object")) {
                // This is chopping off the 'L' to leave us with "java/lang/String"
                mv.visitTypeInsn(CHECKCAST, descriptor.substring(1));
            }
        }
    }
}

18 View Source File : CodeFlow.java
License : Apache License 2.0
Project Creator : langtianya

/**
 * Insert any necessary numeric conversion bytecodes based upon what is on the stack and the desired target type.
 * @param mv the method visitor into which instructions should be placed
 * @param targetDescriptor the (primitive) descriptor of the target type
 * @param stackDescriptor the descriptor of the operand on top of the stack
 */
public static void insertAnyNecessaryTypeConversionBytecodes(MethodVisitor mv, char targetDescriptor, String stackDescriptor) {
    if (CodeFlow.isPrimitive(stackDescriptor)) {
        char stackTop = stackDescriptor.charAt(0);
        if (stackTop == 'I' || stackTop == 'B' || stackTop == 'S' || stackTop == 'C') {
            if (targetDescriptor == 'D') {
                mv.visitInsn(I2D);
            } else if (targetDescriptor == 'F') {
                mv.visitInsn(I2F);
            } else if (targetDescriptor == 'J') {
                mv.visitInsn(I2L);
            } else if (targetDescriptor == 'I') {
            // nop
            } else {
                throw new IllegalStateException("cannot get from " + stackTop + " to " + targetDescriptor);
            }
        } else if (stackTop == 'J') {
            if (targetDescriptor == 'D') {
                mv.visitInsn(L2D);
            } else if (targetDescriptor == 'F') {
                mv.visitInsn(L2F);
            } else if (targetDescriptor == 'J') {
            // nop
            } else if (targetDescriptor == 'I') {
                mv.visitInsn(L2I);
            } else {
                throw new IllegalStateException("cannot get from " + stackTop + " to " + targetDescriptor);
            }
        } else if (stackTop == 'F') {
            if (targetDescriptor == 'D') {
                mv.visitInsn(F2D);
            } else if (targetDescriptor == 'F') {
            // nop
            } else if (targetDescriptor == 'J') {
                mv.visitInsn(F2L);
            } else if (targetDescriptor == 'I') {
                mv.visitInsn(F2I);
            } else {
                throw new IllegalStateException("cannot get from " + stackTop + " to " + targetDescriptor);
            }
        } else if (stackTop == 'D') {
            if (targetDescriptor == 'D') {
            // nop
            } else if (targetDescriptor == 'F') {
                mv.visitInsn(D2F);
            } else if (targetDescriptor == 'J') {
                mv.visitInsn(D2L);
            } else if (targetDescriptor == 'I') {
                mv.visitInsn(D2I);
            } else {
                throw new IllegalStateException("cannot get from " + stackDescriptor + " to " + targetDescriptor);
            }
        }
    }
}

18 View Source File : CodeFlow.java
License : Apache License 2.0
Project Creator : langtianya

/**
 * Insert any necessary cast and value call to convert from a boxed type to a
 * primitive value
 * @param mv the method visitor into which instructions should be inserted
 * @param ch the primitive type desired as output
 * @param stackDescriptor the descriptor of the type on top of the stack
 */
public static void insertUnboxInsns(MethodVisitor mv, char ch, String stackDescriptor) {
    switch(ch) {
        case 'Z':
            if (!stackDescriptor.equals("Ljava/lang/Boolean")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
            break;
        case 'B':
            if (!stackDescriptor.equals("Ljava/lang/Byte")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Byte");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false);
            break;
        case 'C':
            if (!stackDescriptor.equals("Ljava/lang/Character")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false);
            break;
        case 'D':
            if (!stackDescriptor.equals("Ljava/lang/Double")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Double");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
            break;
        case 'F':
            if (!stackDescriptor.equals("Ljava/lang/Float")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Float");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
            break;
        case 'I':
            if (!stackDescriptor.equals("Ljava/lang/Integer")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
            break;
        case 'J':
            if (!stackDescriptor.equals("Ljava/lang/Long")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Long");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
            break;
        case 'S':
            if (!stackDescriptor.equals("Ljava/lang/Short")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Short");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false);
            break;
        default:
            throw new IllegalArgumentException("Unboxing should not be attempted for descriptor '" + ch + "'");
    }
}

18 View Source File : CodeFlow.java
License : Apache License 2.0
Project Creator : langtianya

/**
 * For numbers, use the appropriate method on the number to convert it to the primitive type requested.
 * @param mv the method visitor into which instructions should be inserted
 * @param targetDescriptor the primitive type desired as output
 * @param stackDescriptor the descriptor of the type on top of the stack
 */
public static void insertUnboxNumberInsns(MethodVisitor mv, char targetDescriptor, String stackDescriptor) {
    switch(targetDescriptor) {
        case 'D':
            if (stackDescriptor.equals("Ljava/lang/Object")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "doubleValue", "()D", false);
            break;
        case 'F':
            if (stackDescriptor.equals("Ljava/lang/Object")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "floatValue", "()F", false);
            break;
        case 'J':
            if (stackDescriptor.equals("Ljava/lang/Object")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "longValue", "()J", false);
            break;
        case 'I':
            if (stackDescriptor.equals("Ljava/lang/Object")) {
                mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "intValue", "()I", false);
            break;
        // does not handle Z, B, C, S
        default:
            throw new IllegalArgumentException("Unboxing should not be attempted for descriptor '" + targetDescriptor + "'");
    }
}

17 View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus

/**
 * Produce the correct bytecode to build an array. The opcode to use and the
 * signature to preplaced along with the opcode can vary depending on the signature
 * of the array type.
 * @param mv the methodvisitor into which code should be inserted
 * @param size the size of the array
 * @param arraytype the type of the array
 */
public static void insertNewArrayCode(MethodVisitor mv, int size, String arraytype) {
    insertOptimalLoad(mv, size);
    if (arraytype.length() == 1) {
        mv.visitIntInsn(NEWARRAY, CodeFlow.arrayCodeFor(arraytype));
    } else {
        if (arraytype.charAt(0) == '[') {
            // Handling the nested array case here.
            // If vararg is [[I then we want [I and not [I;
            if (CodeFlow.isReferenceTypeArray(arraytype)) {
                mv.visitTypeInsn(ANEWARRAY, arraytype + ";");
            } else {
                mv.visitTypeInsn(ANEWARRAY, arraytype);
            }
        } else {
            mv.visitTypeInsn(ANEWARRAY, arraytype.substring(1));
        }
    }
}

17 View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus

/**
 * Create the optimal instruction for loading a number on the stack.
 * @param mv where to insert the bytecode
 * @param value the value to be loaded
 */
public static void insertOptimalLoad(MethodVisitor mv, int value) {
    if (value < 6) {
        mv.visitInsn(ICONST_0 + value);
    } else if (value < Byte.MAX_VALUE) {
        mv.visitIntInsn(BIPUSH, value);
    } else if (value < Short.MAX_VALUE) {
        mv.visitIntInsn(SIPUSH, value);
    } else {
        mv.visitLdcInsn(value);
    }
}

17 View Source File : VariableReference.java
License : MIT License
Project Creator : Vip-Augus

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    if (this.name.equals(ROOT)) {
        mv.visitVarInsn(ALOAD, 1);
    } else {
        mv.visitVarInsn(ALOAD, 2);
        mv.visitLdcInsn(this.name);
        mv.visitMethodInsn(INVOKEINTERFACE, "org/springframework/expression/EvaluationContext", "lookupVariable", "(Ljava/lang/String;)Ljava/lang/Object;", true);
    }
    CodeFlow.insertCheckCast(mv, this.exitTypeDescriptor);
    cf.pushDescriptor(this.exitTypeDescriptor);
}

17 View Source File : NullLiteral.java
License : MIT License
Project Creator : Vip-Augus

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    mv.visitInsn(ACONST_NULL);
    cf.pushDescriptor(this.exitTypeDescriptor);
}

17 View Source File : IntLiteral.java
License : MIT License
Project Creator : Vip-Augus

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    Integer intValue = (Integer) this.value.getValue();
    replacedert.state(intValue != null, "No int value");
    if (intValue == -1) {
        // Not sure we can get here because -1 is OpMinus
        mv.visitInsn(ICONST_M1);
    } else if (intValue >= 0 && intValue < 6) {
        mv.visitInsn(ICONST_0 + intValue);
    } else {
        mv.visitLdcInsn(intValue);
    }
    cf.pushDescriptor(this.exitTypeDescriptor);
}

17 View Source File : CodeFlow.java
License : Apache License 2.0
Project Creator : langtianya

/**
 * Produce the correct bytecode to build an array. The opcode to use and the
 * signature to preplaced along with the opcode can vary depending on the signature
 * of the array type.
 * @param mv the methodvisitor into which code should be inserted
 * @param size the size of the array
 * @param arraytype the type of the array
 */
public static void insertNewArrayCode(MethodVisitor mv, int size, String arraytype) {
    insertOptimalLoad(mv, size);
    if (arraytype.length() == 1) {
        mv.visitIntInsn(NEWARRAY, CodeFlow.arrayCodeFor(arraytype));
    } else {
        if (arraytype.charAt(0) == '[') {
            // Handling the nested array case here. If vararg
            // is [[I then we want [I and not [I;
            if (CodeFlow.isReferenceTypeArray(arraytype)) {
                mv.visitTypeInsn(ANEWARRAY, arraytype + ";");
            } else {
                mv.visitTypeInsn(ANEWARRAY, arraytype);
            }
        } else {
            mv.visitTypeInsn(ANEWARRAY, arraytype.substring(1));
        }
    }
}

17 View Source File : VariableReference.java
License : Apache License 2.0
Project Creator : langtianya

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    if (this.name.equals(ROOT)) {
        mv.visitVarInsn(ALOAD, 1);
    } else {
        mv.visitVarInsn(ALOAD, 2);
        mv.visitLdcInsn(name);
        mv.visitMethodInsn(INVOKEINTERFACE, "org/springframework/expression/EvaluationContext", "lookupVariable", "(Ljava/lang/String;)Ljava/lang/Object;", true);
    }
    CodeFlow.insertCheckCast(mv, this.exitTypeDescriptor);
    cf.pushDescriptor(this.exitTypeDescriptor);
}

17 View Source File : PropertyOrFieldReference.java
License : Apache License 2.0
Project Creator : langtianya

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    PropertyAccessor accessorToUse = this.cachedReadAccessor;
    if (!(accessorToUse instanceof CompilablePropertyAccessor)) {
        throw new IllegalStateException("Property accessor is not compilable: " + accessorToUse);
    }
    ((CompilablePropertyAccessor) accessorToUse).generateCode(this.name, mv, cf);
    cf.pushDescriptor(this.exitTypeDescriptor);
}

17 View Source File : IntLiteral.java
License : Apache License 2.0
Project Creator : langtianya

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    int intValue = (Integer) this.value.getValue();
    if (intValue == -1) {
        // Not sure we can get here because -1 is OpMinus
        mv.visitInsn(ICONST_M1);
    } else if (intValue >= 0 && intValue < 6) {
        mv.visitInsn(ICONST_0 + intValue);
    } else {
        mv.visitLdcInsn(intValue);
    }
    cf.pushDescriptor(this.exitTypeDescriptor);
}

17 View Source File : FunctionReference.java
License : Apache License 2.0
Project Creator : langtianya

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    String clreplacedDesc = this.method.getDeclaringClreplaced().getName().replace('.', '/');
    generateCodeForArguments(mv, cf, this.method, this.children);
    mv.visitMethodInsn(INVOKESTATIC, clreplacedDesc, this.method.getName(), CodeFlow.createSignatureDescriptor(this.method), false);
    cf.pushDescriptor(this.exitTypeDescriptor);
}

16 View Source File : TypeReference.java
License : MIT License
Project Creator : Vip-Augus

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    // TODO Future optimization - if followed by a static method call, skip generating code here
    replacedert.state(this.type != null, "No type available");
    if (this.type.isPrimitive()) {
        if (this.type == Boolean.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Clreplaced;");
        } else if (this.type == Byte.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Clreplaced;");
        } else if (this.type == Character.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Clreplaced;");
        } else if (this.type == Double.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Clreplaced;");
        } else if (this.type == Float.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Clreplaced;");
        } else if (this.type == Integer.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Clreplaced;");
        } else if (this.type == Long.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Clreplaced;");
        } else if (this.type == Short.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Clreplaced;");
        }
    } else {
        mv.visitLdcInsn(Type.getType(this.type));
    }
    cf.pushDescriptor(this.exitTypeDescriptor);
}

16 View Source File : MapAccessor.java
License : MIT License
Project Creator : Vip-Augus

@Override
public void generateCode(String propertyName, MethodVisitor mv, CodeFlow cf) {
    String descriptor = cf.lastDescriptor();
    if (descriptor == null || !descriptor.equals("Ljava/util/Map")) {
        if (descriptor == null) {
            cf.loadTarget(mv);
        }
        CodeFlow.insertCheckCast(mv, "Ljava/util/Map");
    }
    mv.visitLdcInsn(propertyName);
    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true);
}

16 View Source File : TypeReference.java
License : Apache License 2.0
Project Creator : langtianya

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    // TODO Future optimization - if followed by a static method call, skip generating code here
    if (this.type.isPrimitive()) {
        if (this.type == Integer.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Clreplaced;");
        } else if (this.type == Boolean.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Clreplaced;");
        } else if (this.type == Byte.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Clreplaced;");
        } else if (this.type == Short.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Clreplaced;");
        } else if (this.type == Double.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Clreplaced;");
        } else if (this.type == Character.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Clreplaced;");
        } else if (this.type == Float.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Clreplaced;");
        } else if (this.type == Long.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Clreplaced;");
        } else if (this.type == Boolean.TYPE) {
            mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Clreplaced;");
        }
    } else {
        mv.visitLdcInsn(Type.getType(this.type));
    }
    cf.pushDescriptor(this.exitTypeDescriptor);
}

16 View Source File : OperatorInstanceof.java
License : Apache License 2.0
Project Creator : langtianya

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    getLeftOperand().generateCode(mv, cf);
    mv.visitTypeInsn(INSTANCEOF, Type.getInternalName(this.type));
    cf.pushDescriptor(this.exitTypeDescriptor);
}

15 View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus

/**
 * Called after the main expression evaluation method has been generated, this
 * method will callback any registered FieldAdders or ClinitAdders to add any
 * extra information to the clreplaced representing the compiled expression.
 */
public void finish() {
    if (this.fieldAdders != null) {
        for (FieldAdder fieldAdder : this.fieldAdders) {
            fieldAdder.generateField(this.clreplacedWriter, this);
        }
    }
    if (this.clinitAdders != null) {
        MethodVisitor mv = this.clreplacedWriter.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", "()V", null, null);
        mv.visitCode();
        // to 0 because there is no 'this' in a clinit
        this.nextFreeVariableId = 0;
        for (ClinitAdder clinitAdder : this.clinitAdders) {
            clinitAdder.generateCode(mv, this);
        }
        mv.visitInsn(RETURN);
        // not supplied due to COMPUTE_MAXS
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
}

15 View Source File : SpelNodeImpl.java
License : MIT License
Project Creator : Vip-Augus

/**
 * Generate code that handles building the argument values for the specified method.
 * This method will take account of whether the invoked method is a varargs method
 * and if it is then the argument values will be appropriately packaged into an array.
 * @param mv the method visitor where code should be generated
 * @param cf the current codeflow
 * @param member the method or constructor for which arguments are being setup
 * @param arguments the expression nodes for the expression supplied argument values
 */
protected static void generateCodeForArguments(MethodVisitor mv, CodeFlow cf, Member member, SpelNodeImpl[] arguments) {
    String[] paramDescriptors = null;
    boolean isVarargs = false;
    if (member instanceof Constructor) {
        Constructor<?> ctor = (Constructor<?>) member;
        paramDescriptors = CodeFlow.toDescriptors(ctor.getParameterTypes());
        isVarargs = ctor.isVarArgs();
    } else {
        // Method
        Method method = (Method) member;
        paramDescriptors = CodeFlow.toDescriptors(method.getParameterTypes());
        isVarargs = method.isVarArgs();
    }
    if (isVarargs) {
        // The final parameter may or may not need packaging into an array, or nothing may
        // have been preplaceded to satisfy the varargs and so something needs to be built.
        // Current supplied argument being processed
        int p = 0;
        int childCount = arguments.length;
        // Fulfill all the parameter requirements except the last one
        for (p = 0; p < paramDescriptors.length - 1; p++) {
            generateCodeForArgument(mv, cf, arguments[p], paramDescriptors[p]);
        }
        SpelNodeImpl lastChild = (childCount == 0 ? null : arguments[childCount - 1]);
        String arrayType = paramDescriptors[paramDescriptors.length - 1];
        // Determine if the final preplaceded argument is already suitably packaged in array
        // form to be preplaceded to the method
        if (lastChild != null && arrayType.equals(lastChild.getExitDescriptor())) {
            generateCodeForArgument(mv, cf, lastChild, paramDescriptors[p]);
        } else {
            // trim the leading '[', may leave other '['
            arrayType = arrayType.substring(1);
            // build array big enough to hold remaining arguments
            CodeFlow.insertNewArrayCode(mv, childCount - p, arrayType);
            // Package up the remaining arguments into the array
            int arrayindex = 0;
            while (p < childCount) {
                SpelNodeImpl child = arguments[p];
                mv.visitInsn(DUP);
                CodeFlow.insertOptimalLoad(mv, arrayindex++);
                generateCodeForArgument(mv, cf, child, arrayType);
                CodeFlow.insertArrayStore(mv, arrayType);
                p++;
            }
        }
    } else {
        for (int i = 0; i < paramDescriptors.length; i++) {
            generateCodeForArgument(mv, cf, arguments[i], paramDescriptors[i]);
        }
    }
}

15 View Source File : OpPlus.java
License : MIT License
Project Creator : Vip-Augus

/**
 * Walk through a possible tree of nodes that combine strings and append
 * them all to the same (on stack) StringBuilder.
 */
private void walk(MethodVisitor mv, CodeFlow cf, @Nullable SpelNodeImpl operand) {
    if (operand instanceof OpPlus) {
        OpPlus plus = (OpPlus) operand;
        walk(mv, cf, plus.getLeftOperand());
        walk(mv, cf, plus.getRightOperand());
    } else if (operand != null) {
        cf.enterCompilationScope();
        operand.generateCode(mv, cf);
        if (!"Ljava/lang/String".equals(cf.lastDescriptor())) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/String");
        }
        cf.exitCompilationScope();
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
    }
}

15 View Source File : OperatorNot.java
License : MIT License
Project Creator : Vip-Augus

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    this.children[0].generateCode(mv, cf);
    cf.unboxBooleanIfNecessary(mv);
    Label elseTarget = new Label();
    Label endOfIf = new Label();
    mv.visitJumpInsn(IFNE, elseTarget);
    // TRUE
    mv.visitInsn(ICONST_1);
    mv.visitJumpInsn(GOTO, endOfIf);
    mv.visitLabel(elseTarget);
    // FALSE
    mv.visitInsn(ICONST_0);
    mv.visitLabel(endOfIf);
    cf.pushDescriptor(this.exitTypeDescriptor);
}

15 View Source File : SpelNodeImpl.java
License : Apache License 2.0
Project Creator : langtianya

/**
 * Generate code that handles building the argument values for the specified method. This method will take account
 * of whether the invoked method is a varargs method and if it is then the argument values will be appropriately
 * packaged into an array.
 * @param mv the method visitor where code should be generated
 * @param cf the current codeflow
 * @param member the method or constructor for which arguments are being setup
 * @param arguments the expression nodes for the expression supplied argument values
 */
protected static void generateCodeForArguments(MethodVisitor mv, CodeFlow cf, Member member, SpelNodeImpl[] arguments) {
    String[] paramDescriptors = null;
    boolean isVarargs = false;
    if (member instanceof Constructor) {
        Constructor<?> ctor = (Constructor<?>) member;
        paramDescriptors = CodeFlow.toDescriptors(ctor.getParameterTypes());
        isVarargs = ctor.isVarArgs();
    } else {
        // Method
        Method method = (Method) member;
        paramDescriptors = CodeFlow.toDescriptors(method.getParameterTypes());
        isVarargs = method.isVarArgs();
    }
    if (isVarargs) {
        // The final parameter may or may not need packaging into an array, or nothing may
        // have been preplaceded to satisfy the varargs and so something needs to be built.
        // Current supplied argument being processed
        int p = 0;
        int childCount = arguments.length;
        // Fulfill all the parameter requirements except the last one
        for (p = 0; p < paramDescriptors.length - 1; p++) {
            generateCodeForArgument(mv, cf, arguments[p], paramDescriptors[p]);
        }
        SpelNodeImpl lastchild = (childCount == 0 ? null : arguments[childCount - 1]);
        String arraytype = paramDescriptors[paramDescriptors.length - 1];
        // Determine if the final preplaceded argument is already suitably packaged in array
        // form to be preplaceded to the method
        if (lastchild != null && lastchild.getExitDescriptor().equals(arraytype)) {
            generateCodeForArgument(mv, cf, lastchild, paramDescriptors[p]);
        } else {
            // trim the leading '[', may leave other '['
            arraytype = arraytype.substring(1);
            // build array big enough to hold remaining arguments
            CodeFlow.insertNewArrayCode(mv, childCount - p, arraytype);
            // Package up the remaining arguments into the array
            int arrayindex = 0;
            while (p < childCount) {
                SpelNodeImpl child = arguments[p];
                mv.visitInsn(DUP);
                CodeFlow.insertOptimalLoad(mv, arrayindex++);
                generateCodeForArgument(mv, cf, child, arraytype);
                CodeFlow.insertArrayStore(mv, arraytype);
                p++;
            }
        }
    } else {
        for (int i = 0; i < paramDescriptors.length; i++) {
            generateCodeForArgument(mv, cf, arguments[i], paramDescriptors[i]);
        }
    }
}

15 View Source File : OpPlus.java
License : Apache License 2.0
Project Creator : langtianya

/**
 * Walk through a possible tree of nodes that combine strings and append
 * them all to the same (on stack) StringBuilder.
 */
private void walk(MethodVisitor mv, CodeFlow cf, SpelNodeImpl operand) {
    if (operand instanceof OpPlus) {
        OpPlus plus = (OpPlus) operand;
        walk(mv, cf, plus.getLeftOperand());
        walk(mv, cf, plus.getRightOperand());
    } else {
        cf.enterCompilationScope();
        operand.generateCode(mv, cf);
        if (!"Ljava/lang/String".equals(cf.lastDescriptor())) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/String");
        }
        cf.exitCompilationScope();
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
    }
}

14 View Source File : OpEQ.java
License : MIT License
Project Creator : Vip-Augus

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    cf.loadEvaluationContext(mv);
    String leftDesc = getLeftOperand().exitTypeDescriptor;
    String rightDesc = getRightOperand().exitTypeDescriptor;
    boolean leftPrim = CodeFlow.isPrimitive(leftDesc);
    boolean rightPrim = CodeFlow.isPrimitive(rightDesc);
    cf.enterCompilationScope();
    getLeftOperand().generateCode(mv, cf);
    cf.exitCompilationScope();
    if (leftPrim) {
        CodeFlow.insertBoxIfNecessary(mv, leftDesc.charAt(0));
    }
    cf.enterCompilationScope();
    getRightOperand().generateCode(mv, cf);
    cf.exitCompilationScope();
    if (rightPrim) {
        CodeFlow.insertBoxIfNecessary(mv, rightDesc.charAt(0));
    }
    String operatorClreplacedName = Operator.clreplaced.getName().replace('.', '/');
    String evaluationContextClreplacedName = EvaluationContext.clreplaced.getName().replace('.', '/');
    mv.visitMethodInsn(INVOKESTATIC, operatorClreplacedName, "equalityCheck", "(L" + evaluationContextClreplacedName + ";Ljava/lang/Object;Ljava/lang/Object;)Z", false);
    cf.pushDescriptor("Z");
}

14 View Source File : InlineList.java
License : MIT License
Project Creator : Vip-Augus

@Override
public void generateCode(MethodVisitor mv, CodeFlow codeflow) {
    final String constantFieldName = "inlineList$" + codeflow.nextFieldId();
    final String clreplacedName = codeflow.getClreplacedName();
    codeflow.registerNewField((cw, cflow) -> cw.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, constantFieldName, "Ljava/util/List;", null, null));
    codeflow.registerNewClinit((mVisitor, cflow) -> generateClinitCode(clreplacedName, constantFieldName, mVisitor, cflow, false));
    mv.visitFieldInsn(GETSTATIC, clreplacedName, constantFieldName, "Ljava/util/List;");
    codeflow.pushDescriptor("Ljava/util/List");
}

See More Examples