src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File jdk Sdiff src/share/classes/java/lang/invoke

src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java

Print this page
rev 10086 : 8046903: VM anonymous class members can't be statically invocable
Reviewed-by: ?


  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 import sun.invoke.util.VerifyAccess;
  29 import static java.lang.invoke.LambdaForm.*;
  30 
  31 import sun.invoke.util.Wrapper;
  32 
  33 import java.io.*;
  34 import java.util.*;
  35 
  36 import jdk.internal.org.objectweb.asm.*;
  37 
  38 import java.lang.reflect.*;
  39 import static java.lang.invoke.MethodHandleStatics.*;
  40 import static java.lang.invoke.MethodHandleNatives.Constants.*;
  41 import static java.lang.invoke.LambdaForm.BasicType.*;
  42 import sun.invoke.util.VerifyType;

  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 
  59     private static final String LF_SIG  = "L" + LF + ";";
  60     private static final String LFN_SIG = "L" + LFN + ";";
  61     private static final String LL_SIG  = "(L" + OBJ + ";)L" + OBJ + ";";
  62     private static final String CLL_SIG = "(L" + CLS + ";L" + OBJ + ";)L" + OBJ + ";";


 577     }
 578 
 579     static private Class<?>[] STATICALLY_INVOCABLE_PACKAGES = {
 580         // Sample classes from each package we are willing to bind to statically:
 581         java.lang.Object.class,
 582         java.util.Arrays.class,
 583         sun.misc.Unsafe.class
 584         //MethodHandle.class already covered
 585     };
 586 
 587     static boolean isStaticallyInvocable(MemberName member) {
 588         if (member == null)  return false;
 589         if (member.isConstructor())  return false;
 590         Class<?> cls = member.getDeclaringClass();
 591         if (cls.isArray() || cls.isPrimitive())
 592             return false;  // FIXME
 593         if (cls.isAnonymousClass() || cls.isLocalClass())
 594             return false;  // inner class of some sort
 595         if (cls.getClassLoader() != MethodHandle.class.getClassLoader())
 596             return false;  // not on BCP


 597         MethodType mtype = member.getMethodOrFieldType();
 598         if (!isStaticallyNameable(mtype.returnType()))
 599             return false;
 600         for (Class<?> ptype : mtype.parameterArray())
 601             if (!isStaticallyNameable(ptype))
 602                 return false;
 603         if (!member.isPrivate() && VerifyAccess.isSamePackage(MethodHandle.class, cls))
 604             return true;   // in java.lang.invoke package
 605         if (member.isPublic() && isStaticallyNameable(cls))
 606             return true;
 607         return false;
 608     }
 609 
 610     static boolean isStaticallyNameable(Class<?> cls) {
 611         while (cls.isArray())
 612             cls = cls.getComponentType();
 613         if (cls.isPrimitive())
 614             return true;  // int[].class, for example


 615         // could use VerifyAccess.isClassAccessible but the following is a safe approximation
 616         if (cls.getClassLoader() != Object.class.getClassLoader())
 617             return false;
 618         if (VerifyAccess.isSamePackage(MethodHandle.class, cls))
 619             return true;
 620         if (!Modifier.isPublic(cls.getModifiers()))
 621             return false;
 622         for (Class<?> pkgcls : STATICALLY_INVOCABLE_PACKAGES) {
 623             if (VerifyAccess.isSamePackage(pkgcls, cls))
 624                 return true;
 625         }
 626         return false;
 627     }
 628 
 629     /**
 630      * Emit an invoke for the given name, using the MemberName directly.
 631      */
 632     void emitStaticInvoke(MemberName member, Name name) {
 633         assert(member.equals(name.function.member()));
 634         String cname = getInternalName(member.getDeclaringClass());




  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 import sun.invoke.util.VerifyAccess;
  29 import static java.lang.invoke.LambdaForm.*;
  30 
  31 import sun.invoke.util.Wrapper;
  32 
  33 import java.io.*;
  34 import java.util.*;
  35 
  36 import jdk.internal.org.objectweb.asm.*;
  37 
  38 import java.lang.reflect.*;
  39 import static java.lang.invoke.MethodHandleStatics.*;
  40 import static java.lang.invoke.MethodHandleNatives.Constants.*;
  41 import static java.lang.invoke.LambdaForm.BasicType.*;
  42 import sun.invoke.util.VerifyType;
  43 import sun.reflect.misc.ReflectUtil;
  44 
  45 /**
  46  * Code generation backend for LambdaForm.
  47  * <p>
  48  * @author John Rose, JSR 292 EG
  49  */
  50 class InvokerBytecodeGenerator {
  51     /** Define class names for convenience. */
  52     private static final String MH      = "java/lang/invoke/MethodHandle";
  53     private static final String MHI     = "java/lang/invoke/MethodHandleImpl";
  54     private static final String LF      = "java/lang/invoke/LambdaForm";
  55     private static final String LFN     = "java/lang/invoke/LambdaForm$Name";
  56     private static final String CLS     = "java/lang/Class";
  57     private static final String OBJ     = "java/lang/Object";
  58     private static final String OBJARY  = "[Ljava/lang/Object;";
  59 
  60     private static final String LF_SIG  = "L" + LF + ";";
  61     private static final String LFN_SIG = "L" + LFN + ";";
  62     private static final String LL_SIG  = "(L" + OBJ + ";)L" + OBJ + ";";
  63     private static final String CLL_SIG = "(L" + CLS + ";L" + OBJ + ";)L" + OBJ + ";";


 578     }
 579 
 580     static private Class<?>[] STATICALLY_INVOCABLE_PACKAGES = {
 581         // Sample classes from each package we are willing to bind to statically:
 582         java.lang.Object.class,
 583         java.util.Arrays.class,
 584         sun.misc.Unsafe.class
 585         //MethodHandle.class already covered
 586     };
 587 
 588     static boolean isStaticallyInvocable(MemberName member) {
 589         if (member == null)  return false;
 590         if (member.isConstructor())  return false;
 591         Class<?> cls = member.getDeclaringClass();
 592         if (cls.isArray() || cls.isPrimitive())
 593             return false;  // FIXME
 594         if (cls.isAnonymousClass() || cls.isLocalClass())
 595             return false;  // inner class of some sort
 596         if (cls.getClassLoader() != MethodHandle.class.getClassLoader())
 597             return false;  // not on BCP
 598         if (ReflectUtil.isVMAnonymousClass(cls)) // FIXME: switch to supported API once it is added
 599             return false;
 600         MethodType mtype = member.getMethodOrFieldType();
 601         if (!isStaticallyNameable(mtype.returnType()))
 602             return false;
 603         for (Class<?> ptype : mtype.parameterArray())
 604             if (!isStaticallyNameable(ptype))
 605                 return false;
 606         if (!member.isPrivate() && VerifyAccess.isSamePackage(MethodHandle.class, cls))
 607             return true;   // in java.lang.invoke package
 608         if (member.isPublic() && isStaticallyNameable(cls))
 609             return true;
 610         return false;
 611     }
 612 
 613     static boolean isStaticallyNameable(Class<?> cls) {
 614         while (cls.isArray())
 615             cls = cls.getComponentType();
 616         if (cls.isPrimitive())
 617             return true;  // int[].class, for example
 618         if (ReflectUtil.isVMAnonymousClass(cls)) // FIXME: switch to supported API once it is added
 619             return false;
 620         // could use VerifyAccess.isClassAccessible but the following is a safe approximation
 621         if (cls.getClassLoader() != Object.class.getClassLoader())
 622             return false;
 623         if (VerifyAccess.isSamePackage(MethodHandle.class, cls))
 624             return true;
 625         if (!Modifier.isPublic(cls.getModifiers()))
 626             return false;
 627         for (Class<?> pkgcls : STATICALLY_INVOCABLE_PACKAGES) {
 628             if (VerifyAccess.isSamePackage(pkgcls, cls))
 629                 return true;
 630         }
 631         return false;
 632     }
 633 
 634     /**
 635      * Emit an invoke for the given name, using the MemberName directly.
 636      */
 637     void emitStaticInvoke(MemberName member, Name name) {
 638         assert(member.equals(name.function.member()));
 639         String cname = getInternalName(member.getDeclaringClass());


src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File