1 /*
   2  * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  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 sun.corba ;
  27 
  28 import java.io.OptionalDataException;
  29 import java.lang.invoke.MethodHandle;
  30 import java.lang.reflect.Field ;
  31 import java.lang.reflect.Constructor ;
  32 import java.lang.StackWalker;
  33 import java.lang.StackWalker.StackFrame;
  34 import java.util.Optional;
  35 import java.util.stream.Stream;
  36 
  37 import java.security.AccessController;
  38 import java.security.Permission;
  39 import java.security.PrivilegedAction;
  40 
  41 import sun.misc.Unsafe;
  42 import sun.reflect.ReflectionFactory;
  43 
  44 /** This class provides the methods for fundamental JVM operations
  45  * needed in the ORB that are not part of the public Java API.  This includes:
  46  * <ul>
  47  * <li>throwException, which can throw undeclared checked exceptions.
  48  * This is needed to handle throwing arbitrary exceptions across a standardized
  49  * OMG interface that (incorrectly) does not specify appropriate exceptions.</li>
  50  * <li>putXXX/getXXX methods that allow unchecked access to fields of objects.
  51  * This is used for setting uninitialzed non-static final fields (which is
  52  * impossible with reflection) and for speed.</li>
  53  * <li>objectFieldOffset to obtain the field offsets for use in the putXXX/getXXX methods</li>
  54  * <li>newConstructorForSerialization to get the special constructor required for a
  55  * Serializable class</li>
  56  * <li>latestUserDefinedLoader to get the latest user defined class loader from
  57  * the call stack as required by the RMI-IIOP specification (really from the
  58  * JDK 1.1 days)</li>
  59  * </ul>
  60  * The code that calls Bridge.get() must have the following Permissions:
  61  * <ul>
  62  * <li>RuntimePermission "reflectionFactoryAccess"</li>
  63  * <li>BridgePermission "getBridge"</li>
  64  * <li>ReflectPermission "suppressAccessChecks"</li>
  65  * <li>StackFramePermission "retainClassReference"</li>
  66  * </ul>
  67  * <p>
  68  * All of these permissions are required to obtain and correctly initialize
  69  * the instance of Bridge.  No security checks are performed on calls
  70  * made to Bridge instance methods, so access to the Bridge instance
  71  * must be protected.
  72  * <p>
  73  * This class is a singleton (per ClassLoader of course).  Access to the
  74  * instance is obtained through the Bridge.get() method.
  75  */
  76 public final class Bridge
  77 {
  78     private static final Permission getBridgePermission =
  79             new BridgePermission("getBridge");
  80     private static Bridge bridge = null ;
  81 
  82     /** Access to Unsafe to read/write fields. */
  83     private static final Unsafe unsafe = AccessController.doPrivileged(
  84             (PrivilegedAction<Unsafe>)() -> {
  85                 try {
  86                     Field field = Unsafe.class.getDeclaredField("theUnsafe");
  87                     field.setAccessible(true);
  88                     return (Unsafe)field.get(null);
  89 
  90                 } catch (NoSuchFieldException |IllegalAccessException ex) {
  91                     throw new InternalError("Unsafe.theUnsafe field not available", ex);
  92                 }
  93             }
  94     ) ;
  95 
  96     private final ReflectionFactory reflectionFactory ;
  97     private final StackWalker stackWalker;
  98 
  99     private Bridge() {
 100         reflectionFactory = ReflectionFactory.getReflectionFactory();
 101         stackWalker  = StackWalker.getInstance(
 102                             StackWalker.Option.RETAIN_CLASS_REFERENCE);
 103     }
 104 
 105     /** Fetch the Bridge singleton.  This requires the following
 106      * permissions:
 107      * <ul>
 108      * <li>RuntimePermission "reflectionFactoryAccess"</li>
 109      * <li>BridgePermission "getBridge"</li>
 110      * <li>ReflectPermission "suppressAccessChecks"</li>
 111      * <li>StackFramePermission "retainClassReference"</li>
 112      * </ul>
 113      * @return The singleton instance of the Bridge class
 114      * @throws SecurityException if the caller does not have the
 115      * required permissions and the caller has a non-null security manager.
 116      */
 117     public static final synchronized Bridge get()
 118     {
 119         SecurityManager sman = System.getSecurityManager() ;
 120         if (sman != null)
 121             sman.checkPermission( getBridgePermission ) ;
 122 
 123         if (bridge == null) {
 124             bridge = new Bridge() ;
 125         }
 126 
 127         return bridge ;
 128     }
 129 
 130     /** Returns true if the loader that loaded the frame's declaring class
 131      * is a user loader (if it is not the platform class loader or one of
 132      * its ancestor).
 133      */
 134     private boolean isUserLoader(StackFrame sf) {
 135         ClassLoader cl = sf.getDeclaringClass().getClassLoader();
 136         if (cl == null) return false;
 137         ClassLoader p = ClassLoader.getPlatformClassLoader();
 138         while (cl != p && p != null) p = p.getParent();
 139         return cl != p;
 140     }
 141 
 142     private Optional<StackFrame> getLatestUserDefinedLoaderFrame(Stream<StackFrame> stream) {
 143         return stream.filter(this::isUserLoader).findFirst();
 144     }
 145 
 146 
 147     /** Obtain the latest user defined ClassLoader from the call stack.
 148      * This is required by the RMI-IIOP specification.
 149      */
 150     public final ClassLoader getLatestUserDefinedLoader() {
 151         // requires getClassLoader permission => needs doPrivileged.
 152         PrivilegedAction<ClassLoader> pa = () ->
 153             stackWalker.walk(this::getLatestUserDefinedLoaderFrame)
 154                 .map(sf -> sf.getDeclaringClass().getClassLoader())
 155                 .orElseGet(() -> ClassLoader.getPlatformClassLoader());
 156         return AccessController.doPrivileged(pa);
 157     }
 158 
 159     /**
 160      * Fetches a field element within the given
 161      * object <code>o</code> at the given offset.
 162      * The result is undefined unless the offset was obtained from
 163      * {@link #objectFieldOffset} on the {@link java.lang.reflect.Field}
 164      * of some Java field and the object referred to by <code>o</code>
 165      * is of a class compatible with that field's class.
 166      * @param o Java heap object in which the field from which the offset
 167      * was obtained resides
 168      * @param offset indication of where the field resides in a Java heap
 169      *        object
 170      * @return the value fetched from the indicated Java field
 171      * @throws RuntimeException No defined exceptions are thrown, not even
 172      *         {@link NullPointerException}
 173      */
 174     public final int getInt(Object o, long offset)
 175     {
 176         return unsafe.getInt( o, offset ) ;
 177     }
 178 
 179     /**
 180      * Stores a value into a given Java field.
 181      * <p>
 182      * The first two parameters are interpreted exactly as with
 183      * {@link #getInt(Object, long)} to refer to a specific
 184      * Java field.  The given value is stored into that field.
 185      * <p>
 186      * The field must be of the same type as the method
 187      * parameter <code>x</code>.
 188      *
 189      * @param o Java heap object in which the field resides, if any, else
 190      *        null
 191      * @param offset indication of where the field resides in a Java heap
 192      *        object.
 193      * @param x the value to store into the indicated Java field
 194      * @throws RuntimeException No defined exceptions are thrown, not even
 195      *         {@link NullPointerException}
 196      */
 197     public final void putInt(Object o, long offset, int x)
 198     {
 199         unsafe.putInt( o, offset, x ) ;
 200     }
 201 
 202     /**
 203      * @see #getInt(Object, long)
 204      */
 205     public final Object getObject(Object o, long offset)
 206     {
 207         return unsafe.getObject( o, offset ) ;
 208     }
 209 
 210     /**
 211      * @see #putInt(Object, long, int)
 212      */
 213     public final void putObject(Object o, long offset, Object x)
 214     {
 215         unsafe.putObject( o, offset, x ) ;
 216     }
 217 
 218     /** @see #getInt(Object, long) */
 219     public final boolean getBoolean(Object o, long offset)
 220     {
 221         return unsafe.getBoolean( o, offset ) ;
 222     }
 223     /** @see #putInt(Object, long, int) */
 224     public final void    putBoolean(Object o, long offset, boolean x)
 225     {
 226         unsafe.putBoolean( o, offset, x ) ;
 227     }
 228     /** @see #getInt(Object, long) */
 229     public final byte    getByte(Object o, long offset)
 230     {
 231         return unsafe.getByte( o, offset ) ;
 232     }
 233     /** @see #putInt(Object, long, int) */
 234     public final void    putByte(Object o, long offset, byte x)
 235     {
 236         unsafe.putByte( o, offset, x ) ;
 237     }
 238     /** @see #getInt(Object, long) */
 239     public final short   getShort(Object o, long offset)
 240     {
 241         return unsafe.getShort( o, offset ) ;
 242     }
 243     /** @see #putInt(Object, long, int) */
 244     public final void    putShort(Object o, long offset, short x)
 245     {
 246         unsafe.putShort( o, offset, x ) ;
 247     }
 248     /** @see #getInt(Object, long) */
 249     public final char    getChar(Object o, long offset)
 250     {
 251         return unsafe.getChar( o, offset ) ;
 252     }
 253     /** @see #putInt(Object, long, int) */
 254     public final void    putChar(Object o, long offset, char x)
 255     {
 256         unsafe.putChar( o, offset, x ) ;
 257     }
 258     /** @see #getInt(Object, long) */
 259     public final long    getLong(Object o, long offset)
 260     {
 261         return unsafe.getLong( o, offset ) ;
 262     }
 263     /** @see #putInt(Object, long, int) */
 264     public final void    putLong(Object o, long offset, long x)
 265     {
 266         unsafe.putLong( o, offset, x ) ;
 267     }
 268     /** @see #getInt(Object, long) */
 269     public final float   getFloat(Object o, long offset)
 270     {
 271         return unsafe.getFloat( o, offset ) ;
 272     }
 273     /** @see #putInt(Object, long, int) */
 274     public final void    putFloat(Object o, long offset, float x)
 275     {
 276         unsafe.putFloat( o, offset, x ) ;
 277     }
 278     /** @see #getInt(Object, long) */
 279     public final double  getDouble(Object o, long offset)
 280     {
 281         return unsafe.getDouble( o, offset ) ;
 282     }
 283     /** @see #putInt(Object, long, int) */
 284     public final void    putDouble(Object o, long offset, double x)
 285     {
 286         unsafe.putDouble( o, offset, x ) ;
 287     }
 288 
 289     /**
 290      * This constant differs from all results that will ever be returned from
 291      * {@link #objectFieldOffset}.
 292      */
 293     public static final long INVALID_FIELD_OFFSET   = -1;
 294 
 295     /**
 296      * Returns the offset of a non-static field.
 297      */
 298     public final long objectFieldOffset(Field f)
 299     {
 300         return unsafe.objectFieldOffset( f ) ;
 301     }
 302 
 303     /**
 304      * Returns the offset of a static field.
 305      */
 306     public final long staticFieldOffset(Field f)
 307     {
 308         return unsafe.staticFieldOffset( f ) ;
 309     }
 310 
 311     /**
 312      * Ensure that the class has been initalized.
 313      * @param cl the class to ensure is initialized
 314      */
 315     public final void ensureClassInitialized(Class<?> cl) {
 316         unsafe.ensureClassInitialized(cl);
 317     }
 318 
 319 
 320     /** Throw the exception.
 321      * The exception may be an undeclared checked exception.
 322      */
 323     public final void throwException(Throwable ee)
 324     {
 325         unsafe.throwException( ee ) ;
 326     }
 327 
 328     /**
 329      * Obtain a constructor for Class cl.
 330      * This is used to create a constructor for Serializable classes that
 331      * construct an instance of the Serializable class using the
 332      * no args constructor of the first non-Serializable superclass
 333      * of the Serializable class.
 334      */
 335     public final Constructor<?> newConstructorForSerialization( Class<?> cl ) {
 336         return reflectionFactory.newConstructorForSerialization( cl ) ;
 337     }
 338 
 339     public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
 340         return reflectionFactory.newConstructorForExternalization( cl ) ;
 341     }
 342 
 343     /**
 344      * Returns true if the given class defines a static initializer method,
 345      * false otherwise.
 346      */
 347     public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
 348         return reflectionFactory.hasStaticInitializerForSerialization(cl);
 349     }
 350 
 351     public final MethodHandle writeObjectForSerialization(Class<?> cl) {
 352         return reflectionFactory.writeObjectForSerialization(cl);
 353     }
 354 
 355     public final MethodHandle readObjectForSerialization(Class<?> cl) {
 356         return reflectionFactory.readObjectForSerialization(cl);
 357     }
 358 
 359     public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
 360         return reflectionFactory.readObjectNoDataForSerialization(cl);
 361     }
 362 
 363     public final MethodHandle readResolveForSerialization(Class<?> cl) {
 364         return reflectionFactory.readResolveForSerialization(cl);
 365     }
 366 
 367     public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
 368         return reflectionFactory.writeReplaceForSerialization(cl);
 369     }
 370 
 371     /**
 372      * Return a new OptionalDataException instance.
 373      * @return a new OptionalDataException instance
 374      */
 375     public final OptionalDataException newOptionalDataExceptionForSerialization(boolean bool) {
 376         return reflectionFactory.newOptionalDataExceptionForSerialization(bool);
 377     }
 378 
 379 }