1 /*
   2  * Copyright (c) 2004, 2010, 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.lang.reflect.Field ;
  29 import java.lang.reflect.Method ;
  30 import java.lang.reflect.Constructor ;
  31 import java.lang.reflect.InvocationTargetException ;
  32 
  33 import java.io.ObjectInputStream ;
  34 
  35 import java.security.AccessController;
  36 import java.security.Permission;
  37 import java.security.PrivilegedAction;
  38 
  39 import jdk.internal.misc.Unsafe ;
  40 import sun.reflect.ReflectionFactory ;
  41 
  42 /** This class provides the methods for fundamental JVM operations
  43  * needed in the ORB that are not part of the public Java API.  This includes:
  44  * <ul>
  45  * <li>throwException, which can throw undeclared checked exceptions.
  46  * This is needed to handle throwing arbitrary exceptions across a standardized OMG interface that (incorrectly) does not specify appropriate exceptions.</li>
  47  * <li>putXXX/getXXX methods that allow unchecked access to fields of objects.
  48  * This is used for setting uninitialzed non-static final fields (which is
  49  * impossible with reflection) and for speed.</li>
  50  * <li>objectFieldOffset to obtain the field offsets for use in the putXXX/getXXX methods</li>
  51  * <li>newConstructorForSerialization to get the special constructor required for a
  52  * Serializable class</li>
  53  * <li>latestUserDefinedLoader to get the latest user defined class loader from
  54  * the call stack as required by the RMI-IIOP specification (really from the
  55  * JDK 1.1 days)</li>
  56  * </ul>
  57  * The code that calls Bridge.get() must have the following Permissions:
  58  * <ul>
  59  * <li>RuntimePermission "reflectionFactoryAccess"</li>
  60  * <li>BridgePermission "getBridge"</li>
  61  * <li>ReflectPermission "suppressAccessChecks"</li>
  62  * </ul>
  63  * <p>
  64  * All of these permissions are required to obtain and correctly initialize
  65  * the instance of Bridge.  No security checks are performed on calls
  66  * made to Bridge instance methods, so access to the Bridge instance
  67  * must be protected.
  68  * <p>
  69  * This class is a singleton (per ClassLoader of course).  Access to the
  70  * instance is obtained through the Bridge.get() method.
  71  */
  72 public final class Bridge
  73 {
  74     private static final Class[] NO_ARGS = new Class[] {};
  75     private static final Permission getBridgePermission =
  76         new BridgePermission( "getBridge" ) ;
  77     private static Bridge bridge = null ;
  78 
  79     // latestUserDefinedLoader() is a private static method
  80     // in ObjectInputStream in JDK 1.3 through 1.5.
  81     // We use reflection in a doPrivileged block to get a
  82     // Method reference and make it accessible.
  83     private final Method latestUserDefinedLoaderMethod ;
  84     private final Unsafe unsafe ;
  85     private final ReflectionFactory reflectionFactory ;
  86 
  87     private Method getLatestUserDefinedLoaderMethod()
  88     {
  89         return (Method) AccessController.doPrivileged(
  90             new PrivilegedAction()
  91             {
  92                 public Object run()
  93                 {
  94                     Method result = null;
  95 
  96                     try {
  97                         Class io = ObjectInputStream.class;
  98                         result = io.getDeclaredMethod(
  99                             "latestUserDefinedLoader", NO_ARGS);
 100                         result.setAccessible(true);
 101                     } catch (NoSuchMethodException nsme) {
 102                         Error err = new Error( "java.io.ObjectInputStream" +
 103                             " latestUserDefinedLoader " + nsme );
 104                         err.initCause(nsme) ;
 105                         throw err ;
 106                     }
 107 
 108                     return result;
 109                 }
 110             }
 111         );
 112     }
 113 
 114     private Unsafe getUnsafe() {
 115         Field fld = (Field)AccessController.doPrivileged(
 116             new PrivilegedAction()
 117             {
 118                 public Object run()
 119                 {
 120                     Field fld = null ;
 121 
 122                     try {
 123                         Class unsafeClass = jdk.internal.misc.Unsafe.class ;
 124                         fld = unsafeClass.getDeclaredField( "theUnsafe" ) ;
 125                         fld.setAccessible( true ) ;
 126                         return fld ;
 127                     } catch (NoSuchFieldException exc) {
 128                         Error err = new Error( "Could not access Unsafe" ) ;
 129                         err.initCause( exc ) ;
 130                         throw err ;
 131                     }
 132                 }
 133             }
 134         ) ;
 135 
 136         Unsafe unsafe = null;
 137 
 138         try {
 139             unsafe = (Unsafe)(fld.get( null )) ;
 140         } catch (Throwable t) {
 141             Error err = new Error( "Could not access Unsafe" ) ;
 142             err.initCause( t ) ;
 143             throw err ;
 144         }
 145 
 146         return unsafe ;
 147     }
 148 
 149 
 150     private Bridge()
 151     {
 152         latestUserDefinedLoaderMethod = getLatestUserDefinedLoaderMethod();
 153         unsafe = getUnsafe() ;
 154         reflectionFactory = (ReflectionFactory)AccessController.doPrivileged(
 155             new ReflectionFactory.GetReflectionFactoryAction());
 156     }
 157 
 158     /** Fetch the Bridge singleton.  This requires the following
 159      * permissions:
 160      * <ul>
 161      * <li>RuntimePermission "reflectionFactoryAccess"</li>
 162      * <li>BridgePermission "getBridge"</li>
 163      * <li>ReflectPermission "suppressAccessChecks"</li>
 164      * </ul>
 165      * @return The singleton instance of the Bridge class
 166      * @throws SecurityException if the caller does not have the
 167      * required permissions and the caller has a non-null security manager.
 168      */
 169     public static final synchronized Bridge get()
 170     {
 171         SecurityManager sman = System.getSecurityManager() ;
 172         if (sman != null)
 173             sman.checkPermission( getBridgePermission ) ;
 174 
 175         if (bridge == null) {
 176             bridge = new Bridge() ;
 177         }
 178 
 179         return bridge ;
 180     }
 181 
 182     /** Obtain the latest user defined ClassLoader from the call stack.
 183      * This is required by the RMI-IIOP specification.
 184      */
 185     public final ClassLoader getLatestUserDefinedLoader()
 186     {
 187         try {
 188             // Invoke the ObjectInputStream.latestUserDefinedLoader method
 189             return (ClassLoader)latestUserDefinedLoaderMethod.invoke(null,
 190                                                                      (Object[])NO_ARGS);
 191         } catch (InvocationTargetException ite) {
 192             Error err = new Error(
 193                 "sun.corba.Bridge.latestUserDefinedLoader: " + ite ) ;
 194             err.initCause( ite ) ;
 195             throw err ;
 196         } catch (IllegalAccessException iae) {
 197             Error err = new Error(
 198                 "sun.corba.Bridge.latestUserDefinedLoader: " + iae ) ;
 199             err.initCause( iae ) ;
 200             throw err ;
 201         }
 202     }
 203 
 204     /**
 205      * Fetches a field element within the given
 206      * object <code>o</code> at the given offset.
 207      * The result is undefined unless the offset was obtained from
 208      * {@link #objectFieldOffset} on the {@link java.lang.reflect.Field}
 209      * of some Java field and the object referred to by <code>o</code>
 210      * is of a class compatible with that field's class.
 211      * @param o Java heap object in which the field from which the offset
 212      * was obtained resides
 213      * @param offset indication of where the field resides in a Java heap
 214      *        object
 215      * @return the value fetched from the indicated Java field
 216      * @throws RuntimeException No defined exceptions are thrown, not even
 217      *         {@link NullPointerException}
 218      */
 219     public final int getInt(Object o, long offset)
 220     {
 221         return unsafe.getInt( o, offset ) ;
 222     }
 223 
 224     /**
 225      * Stores a value into a given Java field.
 226      * <p>
 227      * The first two parameters are interpreted exactly as with
 228      * {@link #getInt(Object, long)} to refer to a specific
 229      * Java field.  The given value is stored into that field.
 230      * <p>
 231      * The field must be of the same type as the method
 232      * parameter <code>x</code>.
 233      *
 234      * @param o Java heap object in which the field resides, if any, else
 235      *        null
 236      * @param offset indication of where the field resides in a Java heap
 237      *        object.
 238      * @param x the value to store into the indicated Java field
 239      * @throws RuntimeException No defined exceptions are thrown, not even
 240      *         {@link NullPointerException}
 241      */
 242     public final void putInt(Object o, long offset, int x)
 243     {
 244         unsafe.putInt( o, offset, x ) ;
 245     }
 246 
 247     /**
 248      * @see #getInt(Object, long)
 249      */
 250     public final Object getObject(Object o, long offset)
 251     {
 252         return unsafe.getObject( o, offset ) ;
 253     }
 254 
 255     /**
 256      * @see #putInt(Object, long, int)
 257      */
 258     public final void putObject(Object o, long offset, Object x)
 259     {
 260         unsafe.putObject( o, offset, x ) ;
 261     }
 262 
 263     /** @see #getInt(Object, long) */
 264     public final boolean getBoolean(Object o, long offset)
 265     {
 266         return unsafe.getBoolean( o, offset ) ;
 267     }
 268     /** @see #putInt(Object, long, int) */
 269     public final void    putBoolean(Object o, long offset, boolean x)
 270     {
 271         unsafe.putBoolean( o, offset, x ) ;
 272     }
 273     /** @see #getInt(Object, long) */
 274     public final byte    getByte(Object o, long offset)
 275     {
 276         return unsafe.getByte( o, offset ) ;
 277     }
 278     /** @see #putInt(Object, long, int) */
 279     public final void    putByte(Object o, long offset, byte x)
 280     {
 281         unsafe.putByte( o, offset, x ) ;
 282     }
 283     /** @see #getInt(Object, long) */
 284     public final short   getShort(Object o, long offset)
 285     {
 286         return unsafe.getShort( o, offset ) ;
 287     }
 288     /** @see #putInt(Object, long, int) */
 289     public final void    putShort(Object o, long offset, short x)
 290     {
 291         unsafe.putShort( o, offset, x ) ;
 292     }
 293     /** @see #getInt(Object, long) */
 294     public final char    getChar(Object o, long offset)
 295     {
 296         return unsafe.getChar( o, offset ) ;
 297     }
 298     /** @see #putInt(Object, long, int) */
 299     public final void    putChar(Object o, long offset, char x)
 300     {
 301         unsafe.putChar( o, offset, x ) ;
 302     }
 303     /** @see #getInt(Object, long) */
 304     public final long    getLong(Object o, long offset)
 305     {
 306         return unsafe.getLong( o, offset ) ;
 307     }
 308     /** @see #putInt(Object, long, int) */
 309     public final void    putLong(Object o, long offset, long x)
 310     {
 311         unsafe.putLong( o, offset, x ) ;
 312     }
 313     /** @see #getInt(Object, long) */
 314     public final float   getFloat(Object o, long offset)
 315     {
 316         return unsafe.getFloat( o, offset ) ;
 317     }
 318     /** @see #putInt(Object, long, int) */
 319     public final void    putFloat(Object o, long offset, float x)
 320     {
 321         unsafe.putFloat( o, offset, x ) ;
 322     }
 323     /** @see #getInt(Object, long) */
 324     public final double  getDouble(Object o, long offset)
 325     {
 326         return unsafe.getDouble( o, offset ) ;
 327     }
 328     /** @see #putInt(Object, long, int) */
 329     public final void    putDouble(Object o, long offset, double x)
 330     {
 331         unsafe.putDouble( o, offset, x ) ;
 332     }
 333 
 334     /**
 335      * This constant differs from all results that will ever be returned from
 336      * {@link #objectFieldOffset}.
 337      */
 338     public static final long INVALID_FIELD_OFFSET   = -1;
 339 
 340     /**
 341      * Returns the offset of a non-static field.
 342      */
 343     public final long objectFieldOffset(Field f)
 344     {
 345         return unsafe.objectFieldOffset( f ) ;
 346     }
 347 
 348     /** Throw the exception.
 349      * The exception may be an undeclared checked exception.
 350      */
 351     public final void throwException(Throwable ee)
 352     {
 353         unsafe.throwException( ee ) ;
 354     }
 355 
 356     /** Obtain a constructor for Class cl using constructor cons which
 357      * may be the constructor defined in a superclass of cl.  This is
 358      * used to create a constructor for Serializable classes that
 359      * constructs an instance of the Serializable class using the
 360      * no args constructor of the first non-Serializable superclass
 361      * of the Serializable class.
 362      */
 363     public final Constructor newConstructorForSerialization( Class cl,
 364         Constructor cons )
 365     {
 366         return reflectionFactory.newConstructorForSerialization( cl, cons ) ;
 367     }
 368 }