18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.invoke;
27
28 import java.io.*;
29 import java.util.*;
30 import java.lang.reflect.Modifier;
31
32 import jdk.internal.org.objectweb.asm.*;
33
34 import static java.lang.invoke.LambdaForm.*;
35 import static java.lang.invoke.LambdaForm.BasicType.*;
36 import static java.lang.invoke.MethodHandleStatics.*;
37 import static java.lang.invoke.MethodHandleNatives.Constants.*;
38 import sun.invoke.util.ValueConversions;
39 import sun.invoke.util.VerifyType;
40 import sun.invoke.util.VerifyAccess;
41 import sun.invoke.util.Wrapper;
42
43 /**
44 * Code generation backend for LambdaForm.
45 * <p>
46 * @author John Rose, JSR 292 EG
47 */
48 class InvokerBytecodeGenerator {
49 /** Define class names for convenience. */
50 private static final String MH = "java/lang/invoke/MethodHandle";
51 private static final String MHI = "java/lang/invoke/MethodHandleImpl";
52 private static final String LF = "java/lang/invoke/LambdaForm";
53 private static final String LFN = "java/lang/invoke/LambdaForm$Name";
54 private static final String CLS = "java/lang/Class";
55 private static final String OBJ = "java/lang/Object";
56 private static final String OBJARY = "[Ljava/lang/Object;";
57
769 String mtype;
770 byte refKind = member.getReferenceKind();
771 if (refKind == REF_invokeSpecial) {
772 // in order to pass the verifier, we need to convert this to invokevirtual in all cases
773 assert(member.canBeStaticallyBound()) : member;
774 refKind = REF_invokeVirtual;
775 }
776
777 if (member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual) {
778 // Methods from Object declared in an interface can be resolved by JVM to invokevirtual kind.
779 // Need to convert it back to invokeinterface to pass verification and make the invocation works as expected.
780 refKind = REF_invokeInterface;
781 }
782
783 // push arguments
784 for (int i = 0; i < name.arguments.length; i++) {
785 emitPushArgument(name, i);
786 }
787
788 // invocation
789 if (member.isMethod()) {
790 mtype = member.getMethodType().toMethodDescriptorString();
791 mv.visitMethodInsn(refKindOpcode(refKind), cname, mname, mtype,
792 member.getDeclaringClass().isInterface());
793 } else {
794 mtype = MethodType.toFieldDescriptorString(member.getFieldType());
795 mv.visitFieldInsn(refKindOpcode(refKind), cname, mname, mtype);
796 }
797 // Issue a type assertion for the result, so we can avoid casts later.
798 if (name.type == L_TYPE) {
799 Class<?> rtype = member.getInvocationType().returnType();
800 assert(!rtype.isPrimitive());
801 if (rtype != Object.class && !rtype.isInterface()) {
802 assertStaticType(rtype, name);
803 }
804 }
805 }
806
807 boolean isNewArray(Class<?> rtype, Name name) {
808 return rtype.isArray() &&
809 isStaticallyNameable(rtype) &&
|
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.invoke;
27
28 import java.io.*;
29 import java.util.*;
30 import java.lang.reflect.Modifier;
31
32 import jdk.internal.org.objectweb.asm.*;
33
34 import static java.lang.invoke.LambdaForm.*;
35 import static java.lang.invoke.LambdaForm.BasicType.*;
36 import static java.lang.invoke.MethodHandleStatics.*;
37 import static java.lang.invoke.MethodHandleNatives.Constants.*;
38 import java.lang.invoke.MethodHandleImpl.ArrayAccessor;
39 import sun.invoke.util.ValueConversions;
40 import sun.invoke.util.VerifyType;
41 import sun.invoke.util.VerifyAccess;
42 import sun.invoke.util.Wrapper;
43
44 /**
45 * Code generation backend for LambdaForm.
46 * <p>
47 * @author John Rose, JSR 292 EG
48 */
49 class InvokerBytecodeGenerator {
50 /** Define class names for convenience. */
51 private static final String MH = "java/lang/invoke/MethodHandle";
52 private static final String MHI = "java/lang/invoke/MethodHandleImpl";
53 private static final String LF = "java/lang/invoke/LambdaForm";
54 private static final String LFN = "java/lang/invoke/LambdaForm$Name";
55 private static final String CLS = "java/lang/Class";
56 private static final String OBJ = "java/lang/Object";
57 private static final String OBJARY = "[Ljava/lang/Object;";
58
770 String mtype;
771 byte refKind = member.getReferenceKind();
772 if (refKind == REF_invokeSpecial) {
773 // in order to pass the verifier, we need to convert this to invokevirtual in all cases
774 assert(member.canBeStaticallyBound()) : member;
775 refKind = REF_invokeVirtual;
776 }
777
778 if (member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual) {
779 // Methods from Object declared in an interface can be resolved by JVM to invokevirtual kind.
780 // Need to convert it back to invokeinterface to pass verification and make the invocation works as expected.
781 refKind = REF_invokeInterface;
782 }
783
784 // push arguments
785 for (int i = 0; i < name.arguments.length; i++) {
786 emitPushArgument(name, i);
787 }
788
789 // invocation
790 if (defc == ArrayAccessor.class &&
791 match(member, ArrayAccessor.OBJECT_ARRAY_GETTER)) {
792 mv.visitInsn(Opcodes.AALOAD);
793 } else if (defc == ArrayAccessor.class &&
794 match(member, ArrayAccessor.OBJECT_ARRAY_SETTER)) {
795 mv.visitInsn(Opcodes.AASTORE);
796 } else if (member.isMethod()) {
797 mtype = member.getMethodType().toMethodDescriptorString();
798 mv.visitMethodInsn(refKindOpcode(refKind), cname, mname, mtype,
799 member.getDeclaringClass().isInterface());
800 } else {
801 mtype = MethodType.toFieldDescriptorString(member.getFieldType());
802 mv.visitFieldInsn(refKindOpcode(refKind), cname, mname, mtype);
803 }
804 // Issue a type assertion for the result, so we can avoid casts later.
805 if (name.type == L_TYPE) {
806 Class<?> rtype = member.getInvocationType().returnType();
807 assert(!rtype.isPrimitive());
808 if (rtype != Object.class && !rtype.isInterface()) {
809 assertStaticType(rtype, name);
810 }
811 }
812 }
813
814 boolean isNewArray(Class<?> rtype, Name name) {
815 return rtype.isArray() &&
816 isStaticallyNameable(rtype) &&
|