Example usage for org.springframework.expression.spel.ast SpelNodeImpl generateCode

List of usage examples for org.springframework.expression.spel.ast SpelNodeImpl generateCode

Introduction

In this page you can find the example usage for org.springframework.expression.spel.ast SpelNodeImpl generateCode.

Prototype

public void generateCode(MethodVisitor mv, CodeFlow cf) 

Source Link

Document

Generate the bytecode for this node into the supplied visitor.

Usage

From source file:org.springframework.expression.spel.standard.SpelCompiler.java

/**
 * Generate the class that encapsulates the compiled expression and define it.
 * The  generated class will be a subtype of CompiledExpression.
 * @param expressionToCompile the expression to be compiled
 * @return the expression call, or {@code null} if the decision was to opt out of
 * compilation during code generation/*from w w  w  . ja va 2  s.  c om*/
 */
@Nullable
private Class<? extends CompiledExpression> createExpressionClass(SpelNodeImpl expressionToCompile) {
    // Create class outline 'spel/ExNNN extends org.springframework.expression.spel.CompiledExpression'
    String clazzName = "spel/Ex" + getNextSuffix();
    ClassWriter cw = new ExpressionClassWriter();
    cw.visit(V1_5, ACC_PUBLIC, clazzName, null, "org/springframework/expression/spel/CompiledExpression", null);

    // Create default constructor
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, "org/springframework/expression/spel/CompiledExpression", "<init>", "()V",
            false);
    mv.visitInsn(RETURN);
    mv.visitMaxs(1, 1);
    mv.visitEnd();

    // Create getValue() method
    mv = cw.visitMethod(ACC_PUBLIC, "getValue",
            "(Ljava/lang/Object;Lorg/springframework/expression/EvaluationContext;)Ljava/lang/Object;", null,
            new String[] { "org/springframework/expression/EvaluationException" });
    mv.visitCode();

    CodeFlow cf = new CodeFlow(clazzName, cw);

    // Ask the expression AST to generate the body of the method
    try {
        expressionToCompile.generateCode(mv, cf);
    } catch (IllegalStateException ex) {
        if (logger.isDebugEnabled()) {
            logger.debug(expressionToCompile.getClass().getSimpleName()
                    + ".generateCode opted out of compilation: " + ex.getMessage());
        }
        return null;
    }

    CodeFlow.insertBoxIfNecessary(mv, cf.lastDescriptor());
    if ("V".equals(cf.lastDescriptor())) {
        mv.visitInsn(ACONST_NULL);
    }
    mv.visitInsn(ARETURN);

    mv.visitMaxs(0, 0); // not supplied due to COMPUTE_MAXS
    mv.visitEnd();
    cw.visitEnd();

    cf.finish();

    byte[] data = cw.toByteArray();
    // TODO need to make this conditionally occur based on a debug flag
    // dump(expressionToCompile.toStringAST(), clazzName, data);
    return loadClass(clazzName.replaceAll("/", "."), data);
}