cf.enterCompilationScope(); this.children[0].generateCode(mv, cf); String lastDesc = cf.lastDescriptor(); Assert.state(lastDesc != null, "No last descriptor"); CodeFlow.insertBoxIfNecessary(mv, lastDesc.charAt(0)); cf.exitCompilationScope(); Label elseTarget = new Label(); Label endOfIf = new Label(); mv.visitInsn(DUP); mv.visitJumpInsn(IFNULL, elseTarget); mv.visitInsn(DUP); mv.visitLdcInsn(""); mv.visitInsn(SWAP); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z",false); mv.visitJumpInsn(IFEQ, endOfIf); // if not empty, drop through to elseTarget mv.visitLabel(elseTarget); mv.visitInsn(POP); cf.enterCompilationScope(); this.children[1].generateCode(mv, cf); cf.exitCompilationScope(); mv.visitLabel(endOfIf); cf.pushDescriptor(this.exitTypeDescriptor);
@Override public void generateCode(String propertyName, MethodVisitor mv, CodeFlow cf) { boolean isStatic = Modifier.isStatic(this.member.getModifiers()); String descriptor = cf.lastDescriptor(); String classDesc = this.member.getDeclaringClass().getName().replace('.', '/'); if (!isStatic) { if (descriptor == null) { cf.loadTarget(mv); } if (descriptor == null || !classDesc.equals(descriptor.substring(1))) { mv.visitTypeInsn(CHECKCAST, classDesc); } } else { if (descriptor != null) { // A static field/method call will not consume what is on the stack, // it needs to be popped off. mv.visitInsn(POP); } } if (this.member instanceof Method) { mv.visitMethodInsn((isStatic ? INVOKESTATIC : INVOKEVIRTUAL), classDesc, this.member.getName(), CodeFlow.createSignatureDescriptor((Method) this.member), false); } else { mv.visitFieldInsn((isStatic ? GETSTATIC : GETFIELD), classDesc, this.member.getName(), CodeFlow.toJvmDescriptor(((Field) this.member).getType())); } } }
/** * 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 class representing the compiled expression. */ public void finish() { if (this.fieldAdders != null) { for (FieldAdder fieldAdder : this.fieldAdders) { fieldAdder.generateField(this.classWriter, this); } } if (this.clinitAdders != null) { MethodVisitor mv = this.classWriter.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", "()V", null, null); mv.visitCode(); this.nextFreeVariableId = 0; // to 0 because there is no 'this' in a clinit for (ClinitAdder clinitAdder : this.clinitAdders) { clinitAdder.generateCode(mv, this); } mv.visitInsn(RETURN); mv.visitMaxs(0,0); // not supplied due to COMPUTE_MAXS mv.visitEnd(); } }
/** * 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); } }
@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) { 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); }
String catchType = readUTF8(cpInfoOffsets[readUnsignedShort(currentOffset + 6)], charBuffer); currentOffset += 8; methodVisitor.visitTryCatchBlock(start, end, handler, catchType); methodVisitor.visitFrame(Opcodes.F_NEW, maxLocals, null, 0, null); methodVisitor.visitFrame( Opcodes.F_NEW, context.currentFrameLocalCount, context.currentFrameStackTypes); } else { methodVisitor.visitFrame( context.currentFrameType, context.currentFrameLocalCountDelta, methodVisitor.visitFrame(Constants.F_INSERT, 0, null, 0, null); case Constants.MONITORENTER: case Constants.MONITOREXIT: methodVisitor.visitInsn(opcode); currentOffset += 1; break; case Constants.ALOAD_3: opcode -= Constants.ILOAD_0; methodVisitor.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), opcode & 0x3); currentOffset += 1; break;
private static void visitBeanGetter(PersistentEntity<?, ?> entity, String internalClassName, ClassWriter cw) { // public Object getBean() MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "getBean", String.format("()%s", referenceName(JAVA_LANG_OBJECT)), null, null); mv.visitCode(); Label l0 = new Label(); // return this.bean mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, internalClassName, BEAN_FIELD, getAccessibleTypeReferenceName(entity)); mv.visitInsn(ARETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable(THIS_REF, referenceName(internalClassName), null, l0, l1, 0); mv.visitMaxs(1, 1); mv.visitEnd(); }
mv.visitVarInsn(ALOAD, classVariableIndex5(entityClasses, getter.getDeclaringClass())); mv.visitLdcInsn(getter.getName()); mv.visitInsn(ICONST_0); mv.visitTypeInsn(ANEWARRAY, JAVA_LANG_CLASS); mv.visitMethodInsn(INVOKEVIRTUAL, JAVA_LANG_CLASS, "getDeclaredMethod", String.format("(%s[%s)%s", referenceName(JAVA_LANG_STRING), referenceName(JAVA_LANG_CLASS), referenceName(JAVA_LANG_REFLECT_METHOD)), false); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 3); mv.visitInsn(ICONST_1); mv.visitMethodInsn(INVOKEVIRTUAL, JAVA_LANG_REFLECT_METHOD, SET_ACCESSIBLE, "(Z)V", false); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKEVIRTUAL, JAVA_LANG_INVOKE_METHOD_HANDLES_LOOKUP, "unreflect", String.format("(%s)%s", referenceName(JAVA_LANG_REFLECT_METHOD), referenceName(JAVA_LANG_INVOKE_METHOD_HANDLE)), false); mv.visitInsn(ACONST_NULL); mv.visitFieldInsn(PUTSTATIC, internalClassName, getterName(property), referenceName(JAVA_LANG_INVOKE_METHOD_HANDLE));
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(); "(Ljava/lang/Object;Lorg/springframework/expression/EvaluationContext;)Ljava/lang/Object;", null, new String[ ]{"org/springframework/expression/EvaluationException"}); mv.visitCode(); CodeFlow cf = new CodeFlow(className, cw); 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();
int insn; if ("D".equals(this.exitTypeDescriptor)) { mv.visitTypeInsn(CHECKCAST, "[D"); insn = DALOAD; mv.visitTypeInsn(CHECKCAST, "[F"); insn = FALOAD; mv.visitTypeInsn(CHECKCAST, "[J"); insn = LALOAD; mv.visitTypeInsn(CHECKCAST, "[I"); insn = IALOAD; mv.visitTypeInsn(CHECKCAST, "[S"); insn = SALOAD; mv.visitTypeInsn(CHECKCAST, "[B"); insn = BALOAD; mv.visitTypeInsn(CHECKCAST, "[C"); insn = CALOAD; mv.visitTypeInsn(CHECKCAST, "["+ this.exitTypeDescriptor + (CodeFlow.isPrimitiveArray(this.exitTypeDescriptor) ? "" : ";")); mv.visitInsn(insn); mv.visitTypeInsn(CHECKCAST, "java/util/List");
mv = cw.visitMethod(ACC_PUBLIC, INIT, String.format("(%s)V", getAccessibleTypeReferenceName(entity)), null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, JAVA_LANG_OBJECT, INIT, "()V", false); mv.visitVarInsn(ALOAD, 1); mv.visitLdcInsn("Bean must not be null!"); mv.visitMethodInsn(INVOKESTATIC, "org/springframework/util/Assert", "notNull", String.format("(%s%s)V", referenceName(JAVA_LANG_OBJECT), referenceName(JAVA_LANG_STRING)), false); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, internalClassName, BEAN_FIELD, getAccessibleTypeReferenceName(entity)); mv.visitInsn(RETURN); Label l3 = new Label(); mv.visitLabel(l3); mv.visitLocalVariable(THIS_REF, referenceName(internalClassName), null, l0, l3, 0); mv.visitLocalVariable(BEAN_FIELD, getAccessibleTypeReferenceName(entity), null, l0, l3, 1); mv.visitMaxs(2, 2);
Method method = methodExecutor.getMethod(); boolean isStaticMethod = Modifier.isStatic(method.getModifiers()); String descriptor = cf.lastDescriptor(); cf.loadTarget(mv); 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); mv.visitInsn(POP); mv.visitMethodInsn((isStaticMethod ? INVOKESTATIC : INVOKEVIRTUAL), classDesc, method.getName(), CodeFlow.createSignatureDescriptor(method), method.getDeclaringClass().isInterface()); cf.pushDescriptor(this.exitTypeDescriptor); mv.visitLabel(skipIfNull);
private void visitDefaultConstructor(ClassWriter cw) { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, INIT, "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, JAVA_LANG_OBJECT, INIT, "()V", false); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); // (0, 0) = computed via ClassWriter.COMPUTE_MAXS mv.visitEnd(); }
@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); }
@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); }
void generateClinitCode(String clazzname, String constantFieldName, MethodVisitor mv, CodeFlow codeflow, boolean nested) { mv.visitTypeInsn(NEW, "java/util/ArrayList"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V", false); if (!nested) { mv.visitFieldInsn(PUTSTATIC, clazzname, constantFieldName, "Ljava/util/List;"); mv.visitFieldInsn(GETSTATIC, clazzname, constantFieldName, "Ljava/util/List;"); mv.visitInsn(DUP); String lastDesc = codeflow.lastDescriptor(); if (CodeFlow.isPrimitive(lastDesc)) { CodeFlow.insertBoxIfNecessary(mv, lastDesc.charAt(0)); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z", true); mv.visitInsn(POP);
@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(); mv.visitMethodInsn(INVOKESTATIC, operatorClassName, "equalityCheck", "(L" + evaluationContextClassName + ";Ljava/lang/Object;Ljava/lang/Object;)Z", false); Label notZero = new Label(); Label end = new Label(); mv.visitJumpInsn(IFNE, notZero); mv.visitInsn(ICONST_1); mv.visitJumpInsn(GOTO, end); mv.visitLabel(notZero); mv.visitInsn(ICONST_0); mv.visitLabel(end); cf.pushDescriptor("Z");
Label dfltLabel = new Label(); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEINTERFACE, PERSISTENT_PROPERTY, "getName", String.format("()%s", referenceName(JAVA_LANG_STRING)), true); mv.visitMethodInsn(INVOKEVIRTUAL, JAVA_LANG_STRING, "hashCode", "()I", false); mv.visitLookupSwitchInsn(dfltLabel, hashes, switchJumpLabels); mv.visitLabel(propertyStackMap.get(property.getName()).label); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); visitSetProperty0(entity, property, mv, internalClassName); } else { mv.visitJumpInsn(GOTO, dfltLabel); mv.visitLabel(dfltLabel); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
@Override public void generateCode(String propertyName, MethodVisitor mv, CodeFlow cf) { if (method == null) { try { method = Payload2.class.getDeclaredMethod("getField", String.class); } catch (Exception ex) { } } String descriptor = cf.lastDescriptor(); String memberDeclaringClassSlashedDescriptor = method.getDeclaringClass().getName().replace('.','/'); if (descriptor == null) { cf.loadTarget(mv); } if (descriptor == null || !memberDeclaringClassSlashedDescriptor.equals(descriptor.substring(1))) { mv.visitTypeInsn(CHECKCAST, memberDeclaringClassSlashedDescriptor); } mv.visitLdcInsn(propertyName); mv.visitMethodInsn(INVOKEVIRTUAL, memberDeclaringClassSlashedDescriptor, method.getName(), CodeFlow.createSignatureDescriptor(method), false); } }