@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); }
@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); }
/** * Ask an argument to generate its bytecode and then follow it up * with any boxing/unboxing/checkcasting to ensure it matches the expected parameter descriptor. */ protected static void generateCodeForArgument(MethodVisitor mv, CodeFlow cf, SpelNodeImpl argument, String paramDesc) { cf.enterCompilationScope(); argument.generateCode(mv, cf); String lastDesc = cf.lastDescriptor(); Assert.state(lastDesc != null, "No last descriptor"); boolean primitiveOnStack = CodeFlow.isPrimitive(lastDesc); // Check if need to box it for the method reference? if (primitiveOnStack && paramDesc.charAt(0) == 'L') { CodeFlow.insertBoxIfNecessary(mv, lastDesc.charAt(0)); } else if (paramDesc.length() == 1 && !primitiveOnStack) { CodeFlow.insertUnboxInsns(mv, paramDesc.charAt(0), lastDesc); } else if (!paramDesc.equals(lastDesc)) { // This would be unnecessary in the case of subtyping (e.g. method takes Number but Integer passed in) CodeFlow.insertCheckCast(mv, paramDesc); } cf.exitCompilationScope(); }
@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); }
Label continueLabel = new Label(); mv.visitJumpInsn(IFNONNULL, continueLabel); CodeFlow.insertCheckCast(mv, this.exitTypeDescriptor); mv.visitJumpInsn(GOTO, skipIfNull); mv.visitLabel(continueLabel); CodeFlow.insertCheckCast(mv, "L" + classDesc);
/** * Ask an argument to generate its bytecode and then follow it up * with any boxing/unboxing/checkcasting to ensure it matches the expected parameter descriptor. */ protected static void generateCodeForArgument(MethodVisitor mv, CodeFlow cf, SpelNodeImpl argument, String paramDesc) { cf.enterCompilationScope(); argument.generateCode(mv, cf); String lastDesc = cf.lastDescriptor(); Assert.state(lastDesc != null, "No last descriptor"); boolean primitiveOnStack = CodeFlow.isPrimitive(lastDesc); // Check if need to box it for the method reference? if (primitiveOnStack && paramDesc.charAt(0) == 'L') { CodeFlow.insertBoxIfNecessary(mv, lastDesc.charAt(0)); } else if (paramDesc.length() == 1 && !primitiveOnStack) { CodeFlow.insertUnboxInsns(mv, paramDesc.charAt(0), lastDesc); } else if (!paramDesc.equals(lastDesc)) { // This would be unnecessary in the case of subtyping (e.g. method takes Number but Integer passed in) CodeFlow.insertCheckCast(mv, paramDesc); } cf.exitCompilationScope(); }
@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) { 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); } }
Label continueLabel = new Label(); mv.visitJumpInsn(IFNONNULL, continueLabel); CodeFlow.insertCheckCast(mv, this.exitTypeDescriptor); mv.visitJumpInsn(GOTO, skipIfNull); mv.visitLabel(continueLabel); CodeFlow.insertCheckCast(mv, "L" + classDesc);
@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(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); }
/** * Ask an argument to generate its bytecode and then follow it up * with any boxing/unboxing/checkcasting to ensure it matches the expected parameter descriptor. */ protected static void generateCodeForArgument(MethodVisitor mv, CodeFlow cf, SpelNodeImpl argument, String paramDesc) { cf.enterCompilationScope(); argument.generateCode(mv, cf); String lastDesc = cf.lastDescriptor(); Assert.state(lastDesc != null, "No last descriptor"); boolean primitiveOnStack = CodeFlow.isPrimitive(lastDesc); // Check if need to box it for the method reference? if (primitiveOnStack && paramDesc.charAt(0) == 'L') { CodeFlow.insertBoxIfNecessary(mv, lastDesc.charAt(0)); } else if (paramDesc.length() == 1 && !primitiveOnStack) { CodeFlow.insertUnboxInsns(mv, paramDesc.charAt(0), lastDesc); } else if (!paramDesc.equals(lastDesc)) { // This would be unnecessary in the case of subtyping (e.g. method takes Number but Integer passed in) CodeFlow.insertCheckCast(mv, paramDesc); } cf.exitCompilationScope(); }
@Override public void generateCode(String propertyName, MethodVisitor mv, CodeFlow cf) { String descriptor = cf.lastDescriptor(); if (descriptor == null) { cf.loadTarget(mv); } if (descriptor == null || !mapClassDescriptor.equals(descriptor.substring(1))) { mv.visitTypeInsn(CHECKCAST, mapClassDescriptor); } mv.visitLdcInsn(propertyName); mv.visitMethodInsn(INVOKEINTERFACE, mapClassDescriptor, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true); if (typeDescriptor != null) { CodeFlow.insertCheckCast(mv, typeDescriptor); } }
@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); }
@Override public void generateCode(String propertyName, MethodVisitor mv, CodeFlow cf) { String descriptor = cf.lastDescriptor(); if (descriptor == null) { cf.loadTarget(mv); } if (descriptor == null || !messageClassDescriptor.equals(descriptor.substring(1))) { mv.visitTypeInsn(CHECKCAST, messageClassDescriptor); } mv.visitMethodInsn(INVOKEINTERFACE, messageClassDescriptor, "getHeaders", "()L" + messageHeadersClassDescriptor + ";", true); if (TIMESTAMP.equals(propertyName)) { mv.visitMethodInsn(INVOKEVIRTUAL, messageHeadersClassDescriptor, "getTimestamp", "()Ljava/lang/Long;", false); } else { mv.visitLdcInsn(propertyName); mv.visitMethodInsn(INVOKEVIRTUAL, messageHeadersClassDescriptor, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", false); } if (typeDescriptor != null) { CodeFlow.insertCheckCast(mv, typeDescriptor); } }
Label continueLabel = new Label(); mv.visitJumpInsn(IFNONNULL, continueLabel); CodeFlow.insertCheckCast(mv, this.exitTypeDescriptor); mv.visitJumpInsn(GOTO, skipIfNull); mv.visitLabel(continueLabel); CodeFlow.insertCheckCast(mv, "L" + classDesc);
@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); } }