@Override public void generateCode(MethodVisitor mv, CodeFlow cf) { mv.visitInsn(ACONST_NULL); cf.pushDescriptor(this.exitTypeDescriptor); }
@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); }
@Override public void generateCode(MethodVisitor mv, CodeFlow cf) { Method method = this.method; Assert.state(method != null, "No method handle"); String classDesc = method.getDeclaringClass().getName().replace('.', '/'); generateCodeForArguments(mv, cf, method, this.children); mv.visitMethodInsn(INVOKESTATIC, classDesc, method.getName(), CodeFlow.createSignatureDescriptor(method), false); cf.pushDescriptor(this.exitTypeDescriptor); }
@Override public void generateCode(MethodVisitor mv, CodeFlow cf) { mv.visitLdcInsn(this.value.getValue()); cf.pushDescriptor(this.exitTypeDescriptor); }
@Override public void generateCode(MethodVisitor mv, CodeFlow cf) { if (this.value == BooleanTypedValue.TRUE) { mv.visitLdcInsn(1); } else { mv.visitLdcInsn(0); } cf.pushDescriptor(this.exitTypeDescriptor); }
@Override public void generateCode(MethodVisitor mv, CodeFlow cf) { mv.visitLdcInsn(this.value.getValue()); cf.pushDescriptor(this.exitTypeDescriptor); }
@Override public void generateCode(MethodVisitor mv, CodeFlow cf) { mv.visitLdcInsn(this.value.getValue()); cf.pushDescriptor(this.exitTypeDescriptor); }
@Override public void generateCode(MethodVisitor mv, CodeFlow cf) { mv.visitLdcInsn(this.value.getValue()); cf.pushDescriptor(this.exitTypeDescriptor); }
@Override public void generateCode(MethodVisitor mv, CodeFlow cf) { ReflectiveConstructorExecutor executor = ((ReflectiveConstructorExecutor) this.cachedExecutor); Assert.state(executor != null, "No cached executor"); Constructor<?> constructor = executor.getConstructor(); String classDesc = constructor.getDeclaringClass().getName().replace('.', '/'); mv.visitTypeInsn(NEW, classDesc); mv.visitInsn(DUP); // children[0] is the type of the constructor, don't want to include that in argument processing SpelNodeImpl[] arguments = new SpelNodeImpl[this.children.length - 1]; System.arraycopy(this.children, 1, arguments, 0, this.children.length - 1); generateCodeForArguments(mv, cf, constructor, arguments); mv.visitMethodInsn(INVOKESPECIAL, classDesc, "<init>", CodeFlow.createSignatureDescriptor(constructor), false); cf.pushDescriptor(this.exitTypeDescriptor); }
@Override public void generateCode(MethodVisitor mv, CodeFlow cf) { Integer intValue = (Integer) this.value.getValue(); Assert.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); }
@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); }
@Override public void generateCode(MethodVisitor mv, CodeFlow cf) { getLeftOperand().generateCode(mv, cf); CodeFlow.insertBoxIfNecessary(mv, cf.lastDescriptor()); Assert.state(this.type != null, "No type available"); if (this.type.isPrimitive()) { // always false - but left operand code always driven // in case it had side effects mv.visitInsn(POP); mv.visitInsn(ICONST_0); // value of false } else { mv.visitTypeInsn(INSTANCEOF, Type.getInternalName(this.type)); } cf.pushDescriptor(this.exitTypeDescriptor); }
@Override public void generateCode(MethodVisitor mv, CodeFlow codeflow) { final String constantFieldName = "inlineList$" + codeflow.nextFieldId(); final String className = codeflow.getClassName(); codeflow.registerNewField((cw, cflow) -> cw.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, constantFieldName, "Ljava/util/List;", null, null)); codeflow.registerNewClinit((mVisitor, cflow) -> generateClinitCode(className, constantFieldName, mVisitor, cflow, false)); mv.visitFieldInsn(GETSTATIC, className, constantFieldName, "Ljava/util/List;"); codeflow.pushDescriptor("Ljava/util/List"); }
@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 operatorClassName = Operator.class.getName().replace('.', '/'); String evaluationContextClassName = EvaluationContext.class.getName().replace('.', '/'); mv.visitMethodInsn(INVOKESTATIC, operatorClassName, "equalityCheck", "(L" + evaluationContextClassName + ";Ljava/lang/Object;Ljava/lang/Object;)Z", false); cf.pushDescriptor("Z"); }
cf.pushDescriptor(this.exitTypeDescriptor);
@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); } Label skipIfNull = null; if (this.nullSafe) { mv.visitInsn(DUP); skipIfNull = new Label(); Label continueLabel = new Label(); mv.visitJumpInsn(IFNONNULL, continueLabel); CodeFlow.insertCheckCast(mv, this.exitTypeDescriptor); mv.visitJumpInsn(GOTO, skipIfNull); mv.visitLabel(continueLabel); } ((CompilablePropertyAccessor) accessorToUse).generateCode(this.name, mv, cf); cf.pushDescriptor(this.exitTypeDescriptor); if (this.originalPrimitiveExitTypeDescriptor != null) { // The output of the accessor is a primitive but from the block above it might be null, // so to have a common stack element type at skipIfNull target it is necessary // to box the primitive CodeFlow.insertBoxIfNecessary(mv, this.originalPrimitiveExitTypeDescriptor); } if (skipIfNull != null) { mv.visitLabel(skipIfNull); } }
@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); mv.visitInsn(ICONST_1); // TRUE mv.visitJumpInsn(GOTO,endOfIf); mv.visitLabel(elseTarget); mv.visitInsn(ICONST_0); // FALSE mv.visitLabel(endOfIf); cf.pushDescriptor(this.exitTypeDescriptor); }
cf.pushDescriptor(this.exitTypeDescriptor);
@Override public void generateCode(MethodVisitor mv, CodeFlow cf) { // pseudo: if (leftOperandValue) { result=true; } else { result=rightOperandValue; } Label elseTarget = new Label(); Label endOfIf = new Label(); cf.enterCompilationScope(); getLeftOperand().generateCode(mv, cf); cf.unboxBooleanIfNecessary(mv); cf.exitCompilationScope(); mv.visitJumpInsn(IFEQ, elseTarget); mv.visitLdcInsn(1); // TRUE mv.visitJumpInsn(GOTO,endOfIf); mv.visitLabel(elseTarget); cf.enterCompilationScope(); getRightOperand().generateCode(mv, cf); cf.unboxBooleanIfNecessary(mv); cf.exitCompilationScope(); mv.visitLabel(endOfIf); cf.pushDescriptor(this.exitTypeDescriptor); }
@Override public void generateCode(MethodVisitor mv, CodeFlow cf) { // Pseudo: if (!leftOperandValue) { result=false; } else { result=rightOperandValue; } Label elseTarget = new Label(); Label endOfIf = new Label(); cf.enterCompilationScope(); getLeftOperand().generateCode(mv, cf); cf.unboxBooleanIfNecessary(mv); cf.exitCompilationScope(); mv.visitJumpInsn(IFNE, elseTarget); mv.visitLdcInsn(0); // FALSE mv.visitJumpInsn(GOTO,endOfIf); mv.visitLabel(elseTarget); cf.enterCompilationScope(); getRightOperand().generateCode(mv, cf); cf.unboxBooleanIfNecessary(mv); cf.exitCompilationScope(); mv.visitLabel(endOfIf); cf.pushDescriptor(this.exitTypeDescriptor); }