< prev index next >

src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java

Print this page

 848                 mv.visitMethodInsn(INVOKEVIRTUAL,
 849                         prim.wrapperClassName,
 850                         prim.unwrapMethodName, prim.unwrapMethodDesc, false);
 851 
 852                 if (type == int.class ||
 853                         type == boolean.class ||
 854                         type == byte.class ||
 855                         type == char.class ||
 856                         type == short.class) {
 857                     mv.visitInsn(IRETURN);
 858                 } else if (type == long.class) {
 859                     mv.visitInsn(LRETURN);
 860                 } else if (type == float.class) {
 861                     mv.visitInsn(FRETURN);
 862                 } else if (type == double.class) {
 863                     mv.visitInsn(DRETURN);
 864                 } else {
 865                     throw new AssertionError();
 866                 }
 867             } else {
 868                 mv.visitTypeInsn(CHECKCAST, dotToSlash(type.getName()));




 869                 mv.visitInsn(ARETURN);
 870             }
 871         }
 872 
 873         /**
 874          * Generate code for initializing the static field that stores
 875          * the Method object for this proxy method.
 876          */
 877         private void codeFieldInitialization(MethodVisitor mv, String className) {
 878             codeClassForName(mv, fromClass);
 879 
 880             mv.visitLdcInsn(method.getName());
 881 
 882             emitIconstInsn(mv, parameterTypes.length);
 883 
 884             mv.visitTypeInsn(Opcodes.ANEWARRAY, JL_CLASS);
 885 
 886             // Construct an array with the parameter types mapping primitives to Wrapper types
 887             for (int i = 0; i < parameterTypes.length; i++) {
 888                 mv.visitInsn(DUP);

 899                 mv.visitInsn(Opcodes.AASTORE);
 900             }
 901             // lookup the method
 902             mv.visitMethodInsn(INVOKEVIRTUAL,
 903                     JL_CLASS,
 904                     "getMethod",
 905                     "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;",
 906                     false);
 907 
 908             mv.visitFieldInsn(PUTSTATIC,
 909                     dotToSlash(className),
 910                     methodFieldName, LJLR_METHOD);
 911         }
 912 
 913         /*
 914          * =============== Code Generation Utility Methods ===============
 915          */
 916 
 917         /**
 918          * Generate code to invoke the Class.forName with the name of the given
 919          * class to get its Class object at runtime.  The code is written to
 920          * the supplied stream.  Note that the code generated by this method
 921          * may cause the checked ClassNotFoundException to be thrown.


 922          */
 923         private void codeClassForName(MethodVisitor mv, Class<?> cl) {
 924             mv.visitLdcInsn(cl.getName());
 925             mv.visitMethodInsn(INVOKESTATIC,
 926                     JL_CLASS,
 927                     "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false);





 928         }
 929 
 930         /**
 931          * Visit a bytecode for a constant.
 932          *
 933          * @param mv  The MethodVisitor
 934          * @param cst The constant value
 935          */
 936         private void emitIconstInsn(MethodVisitor mv, final int cst) {
 937             if (cst >= -1 && cst <= 5) {
 938                 mv.visitInsn(Opcodes.ICONST_0 + cst);
 939             } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) {
 940                 mv.visitIntInsn(Opcodes.BIPUSH, cst);
 941             } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) {
 942                 mv.visitIntInsn(Opcodes.SIPUSH, cst);
 943             } else {
 944                 mv.visitLdcInsn(cst);
 945             }
 946         }
 947 

 848                 mv.visitMethodInsn(INVOKEVIRTUAL,
 849                         prim.wrapperClassName,
 850                         prim.unwrapMethodName, prim.unwrapMethodDesc, false);
 851 
 852                 if (type == int.class ||
 853                         type == boolean.class ||
 854                         type == byte.class ||
 855                         type == char.class ||
 856                         type == short.class) {
 857                     mv.visitInsn(IRETURN);
 858                 } else if (type == long.class) {
 859                     mv.visitInsn(LRETURN);
 860                 } else if (type == float.class) {
 861                     mv.visitInsn(FRETURN);
 862                 } else if (type == double.class) {
 863                     mv.visitInsn(DRETURN);
 864                 } else {
 865                     throw new AssertionError();
 866                 }
 867             } else {
 868                 String internalName = dotToSlash(type.getName());
 869                 if (type.isValueType()) {
 870                     internalName = 'Q' + internalName + ";";
 871                 }
 872                 mv.visitTypeInsn(CHECKCAST, internalName);
 873                 mv.visitInsn(ARETURN);
 874             }
 875         }
 876 
 877         /**
 878          * Generate code for initializing the static field that stores
 879          * the Method object for this proxy method.
 880          */
 881         private void codeFieldInitialization(MethodVisitor mv, String className) {
 882             codeClassForName(mv, fromClass);
 883 
 884             mv.visitLdcInsn(method.getName());
 885 
 886             emitIconstInsn(mv, parameterTypes.length);
 887 
 888             mv.visitTypeInsn(Opcodes.ANEWARRAY, JL_CLASS);
 889 
 890             // Construct an array with the parameter types mapping primitives to Wrapper types
 891             for (int i = 0; i < parameterTypes.length; i++) {
 892                 mv.visitInsn(DUP);

 903                 mv.visitInsn(Opcodes.AASTORE);
 904             }
 905             // lookup the method
 906             mv.visitMethodInsn(INVOKEVIRTUAL,
 907                     JL_CLASS,
 908                     "getMethod",
 909                     "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;",
 910                     false);
 911 
 912             mv.visitFieldInsn(PUTSTATIC,
 913                     dotToSlash(className),
 914                     methodFieldName, LJLR_METHOD);
 915         }
 916 
 917         /*
 918          * =============== Code Generation Utility Methods ===============
 919          */
 920 
 921         /**
 922          * Generate code to invoke the Class.forName with the name of the given
 923          * class to get its Class object at runtime.  And also generate code
 924          * to invoke Class::asValueType if the class is a primitive value type.
 925          *
 926          * The code is written to the supplied stream.  Note that the code generated
 927          * by this method may caused the checked ClassNotFoundException to be thrown.
 928          */
 929         private void codeClassForName(MethodVisitor mv, Class<?> cl) {
 930             mv.visitLdcInsn(cl.getName());
 931             mv.visitMethodInsn(INVOKESTATIC,
 932                     JL_CLASS,
 933                     "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false);
 934             if (cl.isValueType()) {
 935               mv.visitMethodInsn(INVOKEVIRTUAL,
 936                                  JL_CLASS,
 937                                  "asValueType", "()Ljava/lang/Class;", false);
 938             }
 939         }
 940 
 941         /**
 942          * Visit a bytecode for a constant.
 943          *
 944          * @param mv  The MethodVisitor
 945          * @param cst The constant value
 946          */
 947         private void emitIconstInsn(MethodVisitor mv, final int cst) {
 948             if (cst >= -1 && cst <= 5) {
 949                 mv.visitInsn(Opcodes.ICONST_0 + cst);
 950             } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) {
 951                 mv.visitIntInsn(Opcodes.BIPUSH, cst);
 952             } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) {
 953                 mv.visitIntInsn(Opcodes.SIPUSH, cst);
 954             } else {
 955                 mv.visitLdcInsn(cst);
 956             }
 957         }
 958 
< prev index next >