24 */ |
24 */ |
25 |
25 |
26 package java.lang.invoke; |
26 package java.lang.invoke; |
27 |
27 |
28 import java.lang.invoke.MethodHandles.Lookup; |
28 import java.lang.invoke.MethodHandles.Lookup; |
29 import java.lang.reflect.AccessibleObject; |
|
30 import java.lang.reflect.Field; |
29 import java.lang.reflect.Field; |
31 import static java.lang.invoke.MethodHandleNatives.Constants.*; |
30 import static java.lang.invoke.MethodHandleNatives.Constants.*; |
32 import static java.lang.invoke.MethodHandleStatics.*; |
31 import static java.lang.invoke.MethodHandleStatics.*; |
33 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; |
32 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; |
34 |
33 |
35 /** |
34 /** |
36 * The JVM interface for the method handles package is all here. |
35 * The JVM interface for the method handles package is all here. |
37 * This is an interface internal and private to an implemetantion of JSR 292. |
36 * This is an interface internal and private to an implementation of JSR 292. |
38 * <em>This class is not part of the JSR 292 standard.</em> |
37 * <em>This class is not part of the JSR 292 standard.</em> |
39 * @author jrose |
38 * @author jrose |
40 */ |
39 */ |
41 class MethodHandleNatives { |
40 class MethodHandleNatives { |
42 |
41 |
99 static final int |
98 static final int |
100 MN_IS_METHOD = 0x00010000, // method (not constructor) |
99 MN_IS_METHOD = 0x00010000, // method (not constructor) |
101 MN_IS_CONSTRUCTOR = 0x00020000, // constructor |
100 MN_IS_CONSTRUCTOR = 0x00020000, // constructor |
102 MN_IS_FIELD = 0x00040000, // field |
101 MN_IS_FIELD = 0x00040000, // field |
103 MN_IS_TYPE = 0x00080000, // nested type |
102 MN_IS_TYPE = 0x00080000, // nested type |
|
103 MN_CALLER_SENSITIVE = 0x00100000, // @CallerSensitive annotation detected |
104 MN_REFERENCE_KIND_SHIFT = 24, // refKind |
104 MN_REFERENCE_KIND_SHIFT = 24, // refKind |
105 MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT, |
105 MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT, |
106 // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers: |
106 // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers: |
107 MN_SEARCH_SUPERCLASSES = 0x00100000, |
107 MN_SEARCH_SUPERCLASSES = 0x00100000, |
108 MN_SEARCH_INTERFACES = 0x00200000; |
108 MN_SEARCH_INTERFACES = 0x00200000; |
389 /** |
389 /** |
390 * Is this method a caller-sensitive method? |
390 * Is this method a caller-sensitive method? |
391 * I.e., does it call Reflection.getCallerClass or a similer method |
391 * I.e., does it call Reflection.getCallerClass or a similer method |
392 * to ask about the identity of its caller? |
392 * to ask about the identity of its caller? |
393 */ |
393 */ |
394 // FIXME: Replace this pattern match by an annotation @sun.reflect.CallerSensitive. |
|
395 static boolean isCallerSensitive(MemberName mem) { |
394 static boolean isCallerSensitive(MemberName mem) { |
396 if (!mem.isInvocable()) return false; // fields are not caller sensitive |
395 if (!mem.isInvocable()) return false; // fields are not caller sensitive |
|
396 |
|
397 return mem.isCallerSensitive() || canBeCalledVirtual(mem); |
|
398 } |
|
399 |
|
400 static boolean canBeCalledVirtual(MemberName mem) { |
|
401 assert(mem.isInvocable()); |
397 Class<?> defc = mem.getDeclaringClass(); |
402 Class<?> defc = mem.getDeclaringClass(); |
398 switch (mem.getName()) { |
403 switch (mem.getName()) { |
399 case "doPrivileged": |
|
400 case "doPrivilegedWithCombiner": |
|
401 return defc == java.security.AccessController.class; |
|
402 case "checkMemberAccess": |
404 case "checkMemberAccess": |
403 return canBeCalledVirtual(mem, java.lang.SecurityManager.class); |
405 return canBeCalledVirtual(mem, java.lang.SecurityManager.class); |
404 case "getUnsafe": |
|
405 return defc == sun.misc.Unsafe.class; |
|
406 case "lookup": |
|
407 return defc == java.lang.invoke.MethodHandles.class; |
|
408 case "findStatic": |
|
409 case "findVirtual": |
|
410 case "findConstructor": |
|
411 case "findSpecial": |
|
412 case "findGetter": |
|
413 case "findSetter": |
|
414 case "findStaticGetter": |
|
415 case "findStaticSetter": |
|
416 case "bind": |
|
417 case "unreflect": |
|
418 case "unreflectSpecial": |
|
419 case "unreflectConstructor": |
|
420 case "unreflectGetter": |
|
421 case "unreflectSetter": |
|
422 return defc == java.lang.invoke.MethodHandles.Lookup.class; |
|
423 case "invoke": |
|
424 return defc == java.lang.reflect.Method.class; |
|
425 case "get": |
|
426 case "getBoolean": |
|
427 case "getByte": |
|
428 case "getChar": |
|
429 case "getShort": |
|
430 case "getInt": |
|
431 case "getLong": |
|
432 case "getFloat": |
|
433 case "getDouble": |
|
434 case "set": |
|
435 case "setBoolean": |
|
436 case "setByte": |
|
437 case "setChar": |
|
438 case "setShort": |
|
439 case "setInt": |
|
440 case "setLong": |
|
441 case "setFloat": |
|
442 case "setDouble": |
|
443 return defc == java.lang.reflect.Field.class; |
|
444 case "newInstance": |
|
445 if (defc == java.lang.reflect.Constructor.class) return true; |
|
446 if (defc == java.lang.Class.class) return true; |
|
447 break; |
|
448 case "forName": |
|
449 case "getClassLoader": |
|
450 case "getClasses": |
|
451 case "getFields": |
|
452 case "getMethods": |
|
453 case "getConstructors": |
|
454 case "getDeclaredClasses": |
|
455 case "getDeclaredFields": |
|
456 case "getDeclaredMethods": |
|
457 case "getDeclaredConstructors": |
|
458 case "getField": |
|
459 case "getMethod": |
|
460 case "getConstructor": |
|
461 case "getDeclaredField": |
|
462 case "getDeclaredMethod": |
|
463 case "getDeclaredConstructor": |
|
464 return defc == java.lang.Class.class; |
|
465 case "getConnection": |
|
466 case "getDriver": |
|
467 case "getDrivers": |
|
468 case "deregisterDriver": |
|
469 return defc == getClass("java.sql.DriverManager"); |
|
470 case "newUpdater": |
|
471 if (defc == java.util.concurrent.atomic.AtomicIntegerFieldUpdater.class) return true; |
|
472 if (defc == java.util.concurrent.atomic.AtomicLongFieldUpdater.class) return true; |
|
473 if (defc == java.util.concurrent.atomic.AtomicReferenceFieldUpdater.class) return true; |
|
474 break; |
|
475 case "getContextClassLoader": |
406 case "getContextClassLoader": |
476 return canBeCalledVirtual(mem, java.lang.Thread.class); |
407 return canBeCalledVirtual(mem, java.lang.Thread.class); |
477 case "getPackage": |
|
478 case "getPackages": |
|
479 return defc == java.lang.Package.class; |
|
480 case "getParent": |
|
481 case "getSystemClassLoader": |
|
482 return defc == java.lang.ClassLoader.class; |
|
483 case "load": |
|
484 case "loadLibrary": |
|
485 if (defc == java.lang.Runtime.class) return true; |
|
486 if (defc == java.lang.System.class) return true; |
|
487 break; |
|
488 case "getCallerClass": |
|
489 if (defc == sun.reflect.Reflection.class) return true; |
|
490 if (defc == java.lang.System.class) return true; |
|
491 break; |
|
492 case "getCallerClassLoader": |
|
493 return defc == java.lang.ClassLoader.class; |
|
494 case "registerAsParallelCapable": |
|
495 return canBeCalledVirtual(mem, java.lang.ClassLoader.class); |
|
496 case "getProxyClass": |
|
497 case "newProxyInstance": |
|
498 return defc == java.lang.reflect.Proxy.class; |
|
499 case "asInterfaceInstance": |
|
500 return defc == java.lang.invoke.MethodHandleProxies.class; |
|
501 case "getBundle": |
|
502 case "clearCache": |
|
503 return defc == java.util.ResourceBundle.class; |
|
504 } |
408 } |
505 return false; |
409 return false; |
506 } |
410 } |
507 |
411 |
508 // avoid static dependency to a class in other modules |
|
509 private static Class<?> getClass(String cn) { |
|
510 try { |
|
511 return Class.forName(cn, false, |
|
512 MethodHandleNatives.class.getClassLoader()); |
|
513 } catch (ClassNotFoundException e) { |
|
514 throw new InternalError(e); |
|
515 } |
|
516 } |
|
517 static boolean canBeCalledVirtual(MemberName symbolicRef, Class<?> definingClass) { |
412 static boolean canBeCalledVirtual(MemberName symbolicRef, Class<?> definingClass) { |
518 Class<?> symbolicRefClass = symbolicRef.getDeclaringClass(); |
413 Class<?> symbolicRefClass = symbolicRef.getDeclaringClass(); |
519 if (symbolicRefClass == definingClass) return true; |
414 if (symbolicRefClass == definingClass) return true; |
520 if (symbolicRef.isStatic() || symbolicRef.isPrivate()) return false; |
415 if (symbolicRef.isStatic() || symbolicRef.isPrivate()) return false; |
521 return (definingClass.isAssignableFrom(symbolicRefClass) || // Msym overrides Mdef |
416 return (definingClass.isAssignableFrom(symbolicRefClass) || // Msym overrides Mdef |