Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'openjdk/java/lang')
-rw-r--r--openjdk/java/lang/Class.java3601
-rw-r--r--openjdk/java/lang/ClassLoader.java2261
-rw-r--r--openjdk/java/lang/ClassLoaderHelper.java51
-rw-r--r--openjdk/java/lang/Enum.java293
-rw-r--r--openjdk/java/lang/LangHelper.java88
-rw-r--r--openjdk/java/lang/Package.java615
-rw-r--r--openjdk/java/lang/ProcessImpl.java834
-rw-r--r--openjdk/java/lang/PropertyConstants.java.in33
-rw-r--r--openjdk/java/lang/Shutdown.java284
-rw-r--r--openjdk/java/lang/StringHelper.java2592
-rw-r--r--openjdk/java/lang/System.java1168
-rw-r--r--openjdk/java/lang/Thread.java2598
-rw-r--r--openjdk/java/lang/ThrowableHelper.java345
-rw-r--r--openjdk/java/lang/VMSystemProperties.java421
-rw-r--r--openjdk/java/lang/invoke/AdapterMethodHandle.java477
-rw-r--r--openjdk/java/lang/invoke/BoundMethodHandle.java162
-rw-r--r--openjdk/java/lang/invoke/CallSite.java264
-rw-r--r--openjdk/java/lang/invoke/ConstantCallSite.java120
-rw-r--r--openjdk/java/lang/invoke/DirectMethodHandle.java51
-rw-r--r--openjdk/java/lang/invoke/MethodHandleImpl.java740
-rw-r--r--openjdk/java/lang/invoke/MethodHandleNatives.java226
-rw-r--r--openjdk/java/lang/invoke/MethodHandles.java2273
-rw-r--r--openjdk/java/lang/invoke/MutableCallSite.java283
-rw-r--r--openjdk/java/lang/invoke/VolatileCallSite.java109
-rw-r--r--openjdk/java/lang/management/PlatformComponent.java407
-rw-r--r--openjdk/java/lang/ref/Reference.java178
-rw-r--r--openjdk/java/lang/ref/SoftReference.java117
-rw-r--r--openjdk/java/lang/reflect/Constructor.java674
-rw-r--r--openjdk/java/lang/reflect/Field.java1134
-rw-r--r--openjdk/java/lang/reflect/Method.java749
-rw-r--r--openjdk/java/lang/reflect/Proxy.java815
-rw-r--r--openjdk/java/lang/reflect/ReflectHelper.java47
32 files changed, 0 insertions, 24010 deletions
diff --git a/openjdk/java/lang/Class.java b/openjdk/java/lang/Class.java
deleted file mode 100644
index 07fd7bd5..00000000
--- a/openjdk/java/lang/Class.java
+++ /dev/null
@@ -1,3601 +0,0 @@
-/*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang;
-
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Array;
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.GenericDeclaration;
-import java.lang.reflect.Member;
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-import java.lang.reflect.Method;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.AnnotatedType;
-import java.lang.ref.SoftReference;
-import java.io.InputStream;
-import java.io.ObjectStreamField;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Set;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Objects;
-import sun.misc.Unsafe;
-import sun.reflect.CallerSensitive;
-import sun.reflect.ConstantPool;
-import sun.reflect.Reflection;
-import sun.reflect.ReflectionFactory;
-import sun.reflect.generics.factory.CoreReflectionFactory;
-import sun.reflect.generics.factory.GenericsFactory;
-import sun.reflect.generics.repository.ClassRepository;
-import sun.reflect.generics.repository.MethodRepository;
-import sun.reflect.generics.repository.ConstructorRepository;
-import sun.reflect.generics.scope.ClassScope;
-import sun.security.util.SecurityConstants;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Proxy;
-import sun.reflect.annotation.*;
-import sun.reflect.misc.ReflectUtil;
-import cli.System.Runtime.Serialization.IObjectReference;
-import cli.System.Runtime.Serialization.SerializationException;
-import cli.System.Runtime.Serialization.SerializationInfo;
-import cli.System.Runtime.Serialization.StreamingContext;
-
-@cli.System.SerializableAttribute.Annotation
-final class ClassSerializationProxy implements IObjectReference
-{
- private cli.System.Type type;
- private String sig;
-
- @cli.System.Security.SecurityCriticalAttribute.Annotation
- public Object GetRealObject(StreamingContext context)
- {
- if (sig != null)
- {
- if (sig.length() == 1)
- {
- switch (sig.charAt(0))
- {
- case 'B':
- return Byte.TYPE;
- case 'C':
- return Character.TYPE;
- case 'D':
- return Double.TYPE;
- case 'F':
- return Float.TYPE;
- case 'I':
- return Integer.TYPE;
- case 'J':
- return Long.TYPE;
- case 'S':
- return Short.TYPE;
- case 'Z':
- return Boolean.TYPE;
- case 'V':
- return Void.TYPE;
- }
- }
- String className;
- if (sig.charAt(0) == 'L')
- {
- className = sig.substring(1, sig.length() - 1);
- }
- else
- {
- className = sig;
- }
- try
- {
- return Class.forName(className, false, Thread.currentThread().getContextClassLoader());
- }
- catch (ClassNotFoundException x)
- {
- ikvm.runtime.Util.throwException(new SerializationException(x.getMessage(), x));
- }
- }
- return ikvm.runtime.Util.getClassFromTypeHandle(type.get_TypeHandle());
- }
-}
-
-/**
- * Instances of the class {@code Class} represent classes and
- * interfaces in a running Java application. An enum is a kind of
- * class and an annotation is a kind of interface. Every array also
- * belongs to a class that is reflected as a {@code Class} object
- * that is shared by all arrays with the same element type and number
- * of dimensions. The primitive Java types ({@code boolean},
- * {@code byte}, {@code char}, {@code short},
- * {@code int}, {@code long}, {@code float}, and
- * {@code double}), and the keyword {@code void} are also
- * represented as {@code Class} objects.
- *
- * <p> {@code Class} has no public constructor. Instead {@code Class}
- * objects are constructed automatically by the Java Virtual Machine as classes
- * are loaded and by calls to the {@code defineClass} method in the class
- * loader.
- *
- * <p> The following example uses a {@code Class} object to print the
- * class name of an object:
- *
- * <blockquote><pre>
- * void printClassName(Object obj) {
- * System.out.println("The class of " + obj +
- * " is " + obj.getClass().getName());
- * }
- * </pre></blockquote>
- *
- * <p> It is also possible to get the {@code Class} object for a named
- * type (or for void) using a class literal. See Section 15.8.2 of
- * <cite>The Java&trade; Language Specification</cite>.
- * For example:
- *
- * <blockquote>
- * {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}
- * </blockquote>
- *
- * @param <T> the type of the class modeled by this {@code Class}
- * object. For example, the type of {@code String.class} is {@code
- * Class<String>}. Use {@code Class<?>} if the class being modeled is
- * unknown.
- *
- * @author unascribed
- * @see java.lang.ClassLoader#defineClass(byte[], int, int)
- * @since JDK1.0
- */
-@cli.System.SerializableAttribute.Annotation
-public final class Class<T> implements java.io.Serializable,
- GenericDeclaration,
- Type,
- AnnotatedElement {
- private static final int ANNOTATION= 0x00002000;
- private static final int ENUM = 0x00004000;
- private static final int SYNTHETIC = 0x00001000;
-
- // [IKVM] additional fields
- java.security.ProtectionDomain pd;
- Object[] signers;
-
- // For types that live in a static .NET assembly (i.e. ikvmc compiled or .NET types)
- // this field contains the type (used for .NET serialization of Class objects).
- // This field is also used by fast class literals to remember the type that can then
- // lazily be resolved to the corresponding TypeWrapper.
- // For dynamically loaded classes and primitives it is null.
- final cli.System.Type type;
-
- /*
- * Constructor. Only the Java Virtual Machine creates Class
- * objects.
- */
- private Class()
- {
- // this constructor is not used, but exists for compatibility
- // (otherwise it would look as if this class doesn't have a constructor, which might break some code)
- throw new InternalError();
- }
-
- @cli.IKVM.Attributes.HideFromJavaAttribute.Annotation
- Class(cli.System.Type type)
- {
- this.type = type;
- }
-
- // We use custom serialization, because we want to deserialize a via proxy that properly resolves the Class singletons.
- // Note that we don't implement ISerializable in this source, but in map.xml to avoid it being visible to Java code.
- // We don't have a security demand, because the information exposed is harmless.
- @cli.IKVM.Attributes.HideFromJavaAttribute.Annotation
- @cli.System.Security.SecurityCriticalAttribute.Annotation
- public void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- info.AddValue("type", type);
- info.AddValue("sig", type == null ? getSigName() : null);
- info.SetType(ikvm.runtime.Util.getInstanceTypeFromClass(ClassSerializationProxy.class));
- }
-
- private native String getSigName();
-
- // [IKVM] this provides an implicit conversion operator from System.Type to java.lang.Class
- @cli.System.Runtime.CompilerServices.SpecialNameAttribute.Annotation
- @cli.IKVM.Attributes.HideFromJavaAttribute.Annotation
- public static Class op_Implicit(cli.System.Type type)
- {
- return ikvm.runtime.Util.getFriendlyClassFromType(type);
- }
-
- /**
- * Converts the object to a string. The string representation is the
- * string "class" or "interface", followed by a space, and then by the
- * fully qualified name of the class in the format returned by
- * {@code getName}. If this {@code Class} object represents a
- * primitive type, this method returns the name of the primitive type. If
- * this {@code Class} object represents void this method returns
- * "void".
- *
- * @return a string representation of this class object.
- */
- public String toString() {
- return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
- + getName();
- }
-
- /**
- * Returns a string describing this {@code Class}, including
- * information about modifiers and type parameters.
- *
- * The string is formatted as a list of type modifiers, if any,
- * followed by the kind of type (empty string for primitive types
- * and {@code class}, {@code enum}, {@code interface}, or
- * <code>&#64;</code>{@code interface}, as appropriate), followed
- * by the type's name, followed by an angle-bracketed
- * comma-separated list of the type's type parameters, if any.
- *
- * A space is used to separate modifiers from one another and to
- * separate any modifiers from the kind of type. The modifiers
- * occur in canonical order. If there are no type parameters, the
- * type parameter list is elided.
- *
- * <p>Note that since information about the runtime representation
- * of a type is being generated, modifiers not present on the
- * originating source code or illegal on the originating source
- * code may be present.
- *
- * @return a string describing this {@code Class}, including
- * information about modifiers and type parameters
- *
- * @since 1.8
- */
- public String toGenericString() {
- if (isPrimitive()) {
- return toString();
- } else {
- StringBuilder sb = new StringBuilder();
-
- // Class modifiers are a superset of interface modifiers
- int modifiers = getModifiers() & Modifier.classModifiers();
- if (modifiers != 0) {
- sb.append(Modifier.toString(modifiers));
- sb.append(' ');
- }
-
- if (isAnnotation()) {
- sb.append('@');
- }
- if (isInterface()) { // Note: all annotation types are interfaces
- sb.append("interface");
- } else {
- if (isEnum())
- sb.append("enum");
- else
- sb.append("class");
- }
- sb.append(' ');
- sb.append(getName());
-
- TypeVariable<?>[] typeparms = getTypeParameters();
- if (typeparms.length > 0) {
- boolean first = true;
- sb.append('<');
- for(TypeVariable<?> typeparm: typeparms) {
- if (!first)
- sb.append(',');
- sb.append(typeparm.getTypeName());
- first = false;
- }
- sb.append('>');
- }
-
- return sb.toString();
- }
- }
-
- /**
- * Returns the {@code Class} object associated with the class or
- * interface with the given string name. Invoking this method is
- * equivalent to:
- *
- * <blockquote>
- * {@code Class.forName(className, true, currentLoader)}
- * </blockquote>
- *
- * where {@code currentLoader} denotes the defining class loader of
- * the current class.
- *
- * <p> For example, the following code fragment returns the
- * runtime {@code Class} descriptor for the class named
- * {@code java.lang.Thread}:
- *
- * <blockquote>
- * {@code Class t = Class.forName("java.lang.Thread")}
- * </blockquote>
- * <p>
- * A call to {@code forName("X")} causes the class named
- * {@code X} to be initialized.
- *
- * @param className the fully qualified name of the desired class.
- * @return the {@code Class} object for the class with the
- * specified name.
- * @exception LinkageError if the linkage fails
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails
- * @exception ClassNotFoundException if the class cannot be located
- */
- @CallerSensitive
- public static Class<?> forName(String className)
- throws ClassNotFoundException {
- return forName0(className, true,
- ClassLoader.getClassLoader(Reflection.getCallerClass()));
- }
-
-
- /**
- * Returns the {@code Class} object associated with the class or
- * interface with the given string name, using the given class loader.
- * Given the fully qualified name for a class or interface (in the same
- * format returned by {@code getName}) this method attempts to
- * locate, load, and link the class or interface. The specified class
- * loader is used to load the class or interface. If the parameter
- * {@code loader} is null, the class is loaded through the bootstrap
- * class loader. The class is initialized only if the
- * {@code initialize} parameter is {@code true} and if it has
- * not been initialized earlier.
- *
- * <p> If {@code name} denotes a primitive type or void, an attempt
- * will be made to locate a user-defined class in the unnamed package whose
- * name is {@code name}. Therefore, this method cannot be used to
- * obtain any of the {@code Class} objects representing primitive
- * types or void.
- *
- * <p> If {@code name} denotes an array class, the component type of
- * the array class is loaded but not initialized.
- *
- * <p> For example, in an instance method the expression:
- *
- * <blockquote>
- * {@code Class.forName("Foo")}
- * </blockquote>
- *
- * is equivalent to:
- *
- * <blockquote>
- * {@code Class.forName("Foo", true, this.getClass().getClassLoader())}
- * </blockquote>
- *
- * Note that this method throws errors related to loading, linking or
- * initializing as specified in Sections 12.2, 12.3 and 12.4 of <em>The
- * Java Language Specification</em>.
- * Note that this method does not check whether the requested class
- * is accessible to its caller.
- *
- * <p> If the {@code loader} is {@code null}, and a security
- * manager is present, and the caller's class loader is not null, then this
- * method calls the security manager's {@code checkPermission} method
- * with a {@code RuntimePermission("getClassLoader")} permission to
- * ensure it's ok to access the bootstrap class loader.
- *
- * @param name fully qualified name of the desired class
- * @param initialize if {@code true} the class will be initialized.
- * See Section 12.4 of <em>The Java Language Specification</em>.
- * @param loader class loader from which the class must be loaded
- * @return class object representing the desired class
- *
- * @exception LinkageError if the linkage fails
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails
- * @exception ClassNotFoundException if the class cannot be located by
- * the specified class loader
- *
- * @see java.lang.Class#forName(String)
- * @see java.lang.ClassLoader
- * @since 1.2
- */
- @CallerSensitive
- public static Class<?> forName(String name, boolean initialize,
- ClassLoader loader)
- throws ClassNotFoundException
- {
- if (sun.misc.VM.isSystemDomainLoader(loader)) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- ClassLoader ccl = ClassLoader.getClassLoader(Reflection.getCallerClass());
- if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
- sm.checkPermission(
- SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
- }
- }
- return forName0(name, initialize, loader);
- }
-
- /** Called after security checks have been made. */
- private static native Class<?> forName0(String name, boolean initialize,
- ClassLoader loader)
- throws ClassNotFoundException;
-
- /**
- * Creates a new instance of the class represented by this {@code Class}
- * object. The class is instantiated as if by a {@code new}
- * expression with an empty argument list. The class is initialized if it
- * has not already been initialized.
- *
- * <p>Note that this method propagates any exception thrown by the
- * nullary constructor, including a checked exception. Use of
- * this method effectively bypasses the compile-time exception
- * checking that would otherwise be performed by the compiler.
- * The {@link
- * java.lang.reflect.Constructor#newInstance(java.lang.Object...)
- * Constructor.newInstance} method avoids this problem by wrapping
- * any exception thrown by the constructor in a (checked) {@link
- * java.lang.reflect.InvocationTargetException}.
- *
- * @return a newly allocated instance of the class represented by this
- * object.
- * @throws IllegalAccessException if the class or its nullary
- * constructor is not accessible.
- * @throws InstantiationException
- * if this {@code Class} represents an abstract class,
- * an interface, an array class, a primitive type, or void;
- * or if the class has no nullary constructor;
- * or if the instantiation fails for some other reason.
- * @throws ExceptionInInitializerError if the initialization
- * provoked by this method fails.
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and
- * the caller's class loader is not the same as or an
- * ancestor of the class loader for the current class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of this class.
- */
- @CallerSensitive
- public T newInstance()
- throws InstantiationException, IllegalAccessException
- {
- if (System.getSecurityManager() != null) {
- checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
- }
-
- // NOTE: the following code may not be strictly correct under
- // the current Java memory model.
-
- // Constructor lookup
- if (cachedConstructor == null) {
- if (this == Class.class) {
- throw new IllegalAccessException(
- "Can not call newInstance() on the Class for java.lang.Class"
- );
- }
- try {
- Class<?>[] empty = {};
- final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
- // Disable accessibility checks on the constructor
- // since we have to do the security check here anyway
- // (the stack depth is wrong for the Constructor's
- // security check to work)
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- c.setAccessible(true);
- return null;
- }
- });
- cachedConstructor = c;
- } catch (NoSuchMethodException e) {
- throw (InstantiationException)
- new InstantiationException(getName()).initCause(e);
- }
- }
- Constructor<T> tmpConstructor = cachedConstructor;
- // Security check (same as in java.lang.reflect.Constructor)
- int modifiers = tmpConstructor.getModifiers();
- if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
- Class<?> caller = Reflection.getCallerClass();
- if (newInstanceCallerCache != caller) {
- Reflection.ensureMemberAccess(caller, this, null, modifiers);
- newInstanceCallerCache = caller;
- }
- }
- // Run constructor
- try {
- return tmpConstructor.newInstance((Object[])null);
- } catch (InvocationTargetException e) {
- Unsafe.getUnsafe().throwException(e.getTargetException());
- // Not reached
- return null;
- }
- }
- private volatile transient Constructor<T> cachedConstructor;
- private volatile transient Class<?> newInstanceCallerCache;
-
-
- /**
- * Determines if the specified {@code Object} is assignment-compatible
- * with the object represented by this {@code Class}. This method is
- * the dynamic equivalent of the Java language {@code instanceof}
- * operator. The method returns {@code true} if the specified
- * {@code Object} argument is non-null and can be cast to the
- * reference type represented by this {@code Class} object without
- * raising a {@code ClassCastException.} It returns {@code false}
- * otherwise.
- *
- * <p> Specifically, if this {@code Class} object represents a
- * declared class, this method returns {@code true} if the specified
- * {@code Object} argument is an instance of the represented class (or
- * of any of its subclasses); it returns {@code false} otherwise. If
- * this {@code Class} object represents an array class, this method
- * returns {@code true} if the specified {@code Object} argument
- * can be converted to an object of the array class by an identity
- * conversion or by a widening reference conversion; it returns
- * {@code false} otherwise. If this {@code Class} object
- * represents an interface, this method returns {@code true} if the
- * class or any superclass of the specified {@code Object} argument
- * implements this interface; it returns {@code false} otherwise. If
- * this {@code Class} object represents a primitive type, this method
- * returns {@code false}.
- *
- * @param obj the object to check
- * @return true if {@code obj} is an instance of this class
- *
- * @since JDK1.1
- */
- public native boolean isInstance(Object obj);
-
-
- /**
- * Determines if the class or interface represented by this
- * {@code Class} object is either the same as, or is a superclass or
- * superinterface of, the class or interface represented by the specified
- * {@code Class} parameter. It returns {@code true} if so;
- * otherwise it returns {@code false}. If this {@code Class}
- * object represents a primitive type, this method returns
- * {@code true} if the specified {@code Class} parameter is
- * exactly this {@code Class} object; otherwise it returns
- * {@code false}.
- *
- * <p> Specifically, this method tests whether the type represented by the
- * specified {@code Class} parameter can be converted to the type
- * represented by this {@code Class} object via an identity conversion
- * or via a widening reference conversion. See <em>The Java Language
- * Specification</em>, sections 5.1.1 and 5.1.4 , for details.
- *
- * @param cls the {@code Class} object to be checked
- * @return the {@code boolean} value indicating whether objects of the
- * type {@code cls} can be assigned to objects of this class
- * @exception NullPointerException if the specified Class parameter is
- * null.
- * @since JDK1.1
- */
- public native boolean isAssignableFrom(Class<?> cls);
-
-
- /**
- * Determines if the specified {@code Class} object represents an
- * interface type.
- *
- * @return {@code true} if this object represents an interface;
- * {@code false} otherwise.
- */
- public native boolean isInterface();
-
-
- /**
- * Determines if this {@code Class} object represents an array class.
- *
- * @return {@code true} if this object represents an array class;
- * {@code false} otherwise.
- * @since JDK1.1
- */
- public native boolean isArray();
-
-
- /**
- * Determines if the specified {@code Class} object represents a
- * primitive type.
- *
- * <p> There are nine predefined {@code Class} objects to represent
- * the eight primitive types and void. These are created by the Java
- * Virtual Machine, and have the same names as the primitive types that
- * they represent, namely {@code boolean}, {@code byte},
- * {@code char}, {@code short}, {@code int},
- * {@code long}, {@code float}, and {@code double}.
- *
- * <p> These objects may only be accessed via the following public static
- * final variables, and are the only {@code Class} objects for which
- * this method returns {@code true}.
- *
- * @return true if and only if this class represents a primitive type
- *
- * @see java.lang.Boolean#TYPE
- * @see java.lang.Character#TYPE
- * @see java.lang.Byte#TYPE
- * @see java.lang.Short#TYPE
- * @see java.lang.Integer#TYPE
- * @see java.lang.Long#TYPE
- * @see java.lang.Float#TYPE
- * @see java.lang.Double#TYPE
- * @see java.lang.Void#TYPE
- * @since JDK1.1
- */
- public native boolean isPrimitive();
-
- /**
- * Returns true if this {@code Class} object represents an annotation
- * type. Note that if this method returns true, {@link #isInterface()}
- * would also return true, as all annotation types are also interfaces.
- *
- * @return {@code true} if this class object represents an annotation
- * type; {@code false} otherwise
- * @since 1.5
- */
- public boolean isAnnotation() {
- return (getModifiers() & ANNOTATION) != 0;
- }
-
- /**
- * Returns {@code true} if this class is a synthetic class;
- * returns {@code false} otherwise.
- * @return {@code true} if and only if this class is a synthetic class as
- * defined by the Java Language Specification.
- * @jls 13.1 The Form of a Binary
- * @since 1.5
- */
- public boolean isSynthetic() {
- return (getModifiers() & SYNTHETIC) != 0;
- }
-
- /**
- * Returns the name of the entity (class, interface, array class,
- * primitive type, or void) represented by this {@code Class} object,
- * as a {@code String}.
- *
- * <p> If this class object represents a reference type that is not an
- * array type then the binary name of the class is returned, as specified
- * by
- * <cite>The Java&trade; Language Specification</cite>.
- *
- * <p> If this class object represents a primitive type or void, then the
- * name returned is a {@code String} equal to the Java language
- * keyword corresponding to the primitive type or void.
- *
- * <p> If this class object represents a class of arrays, then the internal
- * form of the name consists of the name of the element type preceded by
- * one or more '{@code [}' characters representing the depth of the array
- * nesting. The encoding of element type names is as follows:
- *
- * <blockquote><table summary="Element types and encodings">
- * <tr><th> Element Type <th> &nbsp;&nbsp;&nbsp; <th> Encoding
- * <tr><td> boolean <td> &nbsp;&nbsp;&nbsp; <td align=center> Z
- * <tr><td> byte <td> &nbsp;&nbsp;&nbsp; <td align=center> B
- * <tr><td> char <td> &nbsp;&nbsp;&nbsp; <td align=center> C
- * <tr><td> class or interface
- * <td> &nbsp;&nbsp;&nbsp; <td align=center> L<i>classname</i>;
- * <tr><td> double <td> &nbsp;&nbsp;&nbsp; <td align=center> D
- * <tr><td> float <td> &nbsp;&nbsp;&nbsp; <td align=center> F
- * <tr><td> int <td> &nbsp;&nbsp;&nbsp; <td align=center> I
- * <tr><td> long <td> &nbsp;&nbsp;&nbsp; <td align=center> J
- * <tr><td> short <td> &nbsp;&nbsp;&nbsp; <td align=center> S
- * </table></blockquote>
- *
- * <p> The class or interface name <i>classname</i> is the binary name of
- * the class specified above.
- *
- * <p> Examples:
- * <blockquote><pre>
- * String.class.getName()
- * returns "java.lang.String"
- * byte.class.getName()
- * returns "byte"
- * (new Object[3]).getClass().getName()
- * returns "[Ljava.lang.Object;"
- * (new int[3][4][5][6][7][8][9]).getClass().getName()
- * returns "[[[[[[[I"
- * </pre></blockquote>
- *
- * @return the name of the class or interface
- * represented by this object.
- */
- public String getName() {
- String name = this.name;
- if (name == null)
- this.name = name = getName0();
- return name;
- }
-
- // cache the name to reduce the number of calls into the VM
- private transient String name;
- private native String getName0();
-
- /**
- * Returns the class loader for the class. Some implementations may use
- * null to represent the bootstrap class loader. This method will return
- * null in such implementations if this class was loaded by the bootstrap
- * class loader.
- *
- * <p> If a security manager is present, and the caller's class loader is
- * not null and the caller's class loader is not the same as or an ancestor of
- * the class loader for the class whose class loader is requested, then
- * this method calls the security manager's {@code checkPermission}
- * method with a {@code RuntimePermission("getClassLoader")}
- * permission to ensure it's ok to access the class loader for the class.
- *
- * <p>If this object
- * represents a primitive type or void, null is returned.
- *
- * @return the class loader that loaded the class or interface
- * represented by this object.
- * @throws SecurityException
- * if a security manager exists and its
- * {@code checkPermission} method denies
- * access to the class loader for the class.
- * @see java.lang.ClassLoader
- * @see SecurityManager#checkPermission
- * @see java.lang.RuntimePermission
- */
- @CallerSensitive
- public ClassLoader getClassLoader() {
- ClassLoader cl = getClassLoader0();
- if (cl == null)
- return null;
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
- }
- return cl;
- }
-
- // Package-private to allow ClassLoader access
- native ClassLoader getClassLoader0();
-
-
- /**
- * Returns an array of {@code TypeVariable} objects that represent the
- * type variables declared by the generic declaration represented by this
- * {@code GenericDeclaration} object, in declaration order. Returns an
- * array of length 0 if the underlying generic declaration declares no type
- * variables.
- *
- * @return an array of {@code TypeVariable} objects that represent
- * the type variables declared by this generic declaration
- * @throws java.lang.reflect.GenericSignatureFormatError if the generic
- * signature of this generic declaration does not conform to
- * the format specified in
- * <cite>The Java&trade; Virtual Machine Specification</cite>
- * @since 1.5
- */
- @SuppressWarnings("unchecked")
- public TypeVariable<Class<T>>[] getTypeParameters() {
- ClassRepository info = getGenericInfo();
- if (info != null)
- return (TypeVariable<Class<T>>[])info.getTypeParameters();
- else
- return (TypeVariable<Class<T>>[])new TypeVariable<?>[0];
- }
-
-
- /**
- * Returns the {@code Class} representing the superclass of the entity
- * (class, interface, primitive type or void) represented by this
- * {@code Class}. If this {@code Class} represents either the
- * {@code Object} class, an interface, a primitive type, or void, then
- * null is returned. If this object represents an array class then the
- * {@code Class} object representing the {@code Object} class is
- * returned.
- *
- * @return the superclass of the class represented by this object.
- */
- public native Class<? super T> getSuperclass();
-
-
- /**
- * Returns the {@code Type} representing the direct superclass of
- * the entity (class, interface, primitive type or void) represented by
- * this {@code Class}.
- *
- * <p>If the superclass is a parameterized type, the {@code Type}
- * object returned must accurately reflect the actual type
- * parameters used in the source code. The parameterized type
- * representing the superclass is created if it had not been
- * created before. See the declaration of {@link
- * java.lang.reflect.ParameterizedType ParameterizedType} for the
- * semantics of the creation process for parameterized types. If
- * this {@code Class} represents either the {@code Object}
- * class, an interface, a primitive type, or void, then null is
- * returned. If this object represents an array class then the
- * {@code Class} object representing the {@code Object} class is
- * returned.
- *
- * @throws java.lang.reflect.GenericSignatureFormatError if the generic
- * class signature does not conform to the format specified in
- * <cite>The Java&trade; Virtual Machine Specification</cite>
- * @throws TypeNotPresentException if the generic superclass
- * refers to a non-existent type declaration
- * @throws java.lang.reflect.MalformedParameterizedTypeException if the
- * generic superclass refers to a parameterized type that cannot be
- * instantiated for any reason
- * @return the superclass of the class represented by this object
- * @since 1.5
- */
- public Type getGenericSuperclass() {
- ClassRepository info = getGenericInfo();
- if (info == null) {
- return getSuperclass();
- }
-
- // Historical irregularity:
- // Generic signature marks interfaces with superclass = Object
- // but this API returns null for interfaces
- if (isInterface()) {
- return null;
- }
-
- return info.getSuperclass();
- }
-
- /**
- * Gets the package for this class. The class loader of this class is used
- * to find the package. If the class was loaded by the bootstrap class
- * loader the set of packages loaded from CLASSPATH is searched to find the
- * package of the class. Null is returned if no package object was created
- * by the class loader of this class.
- *
- * <p> Packages have attributes for versions and specifications only if the
- * information was defined in the manifests that accompany the classes, and
- * if the class loader created the package instance with the attributes
- * from the manifest.
- *
- * @return the package of the class, or null if no package
- * information is available from the archive or codebase.
- */
- public Package getPackage() {
- return Package.getPackage(this);
- }
-
-
- /**
- * Determines the interfaces implemented by the class or interface
- * represented by this object.
- *
- * <p> If this object represents a class, the return value is an array
- * containing objects representing all interfaces implemented by the
- * class. The order of the interface objects in the array corresponds to
- * the order of the interface names in the {@code implements} clause
- * of the declaration of the class represented by this object. For
- * example, given the declaration:
- * <blockquote>
- * {@code class Shimmer implements FloorWax, DessertTopping { ... }}
- * </blockquote>
- * suppose the value of {@code s} is an instance of
- * {@code Shimmer}; the value of the expression:
- * <blockquote>
- * {@code s.getClass().getInterfaces()[0]}
- * </blockquote>
- * is the {@code Class} object that represents interface
- * {@code FloorWax}; and the value of:
- * <blockquote>
- * {@code s.getClass().getInterfaces()[1]}
- * </blockquote>
- * is the {@code Class} object that represents interface
- * {@code DessertTopping}.
- *
- * <p> If this object represents an interface, the array contains objects
- * representing all interfaces extended by the interface. The order of the
- * interface objects in the array corresponds to the order of the interface
- * names in the {@code extends} clause of the declaration of the
- * interface represented by this object.
- *
- * <p> If this object represents a class or interface that implements no
- * interfaces, the method returns an array of length 0.
- *
- * <p> If this object represents a primitive type or void, the method
- * returns an array of length 0.
- *
- * <p> If this {@code Class} object represents an array type, the
- * interfaces {@code Cloneable} and {@code java.io.Serializable} are
- * returned in that order.
- *
- * @return an array of interfaces implemented by this class.
- */
- public Class<?>[] getInterfaces() {
- ReflectionData<T> rd = reflectionData();
- if (rd == null) {
- // no cloning required
- return getInterfaces0();
- } else {
- Class<?>[] interfaces = rd.interfaces;
- if (interfaces == null) {
- interfaces = getInterfaces0();
- rd.interfaces = interfaces;
- }
- // defensively copy before handing over to user code
- return interfaces.clone();
- }
- }
-
- private native Class<?>[] getInterfaces0();
-
- /**
- * Returns the {@code Type}s representing the interfaces
- * directly implemented by the class or interface represented by
- * this object.
- *
- * <p>If a superinterface is a parameterized type, the
- * {@code Type} object returned for it must accurately reflect
- * the actual type parameters used in the source code. The
- * parameterized type representing each superinterface is created
- * if it had not been created before. See the declaration of
- * {@link java.lang.reflect.ParameterizedType ParameterizedType}
- * for the semantics of the creation process for parameterized
- * types.
- *
- * <p> If this object represents a class, the return value is an
- * array containing objects representing all interfaces
- * implemented by the class. The order of the interface objects in
- * the array corresponds to the order of the interface names in
- * the {@code implements} clause of the declaration of the class
- * represented by this object. In the case of an array class, the
- * interfaces {@code Cloneable} and {@code Serializable} are
- * returned in that order.
- *
- * <p>If this object represents an interface, the array contains
- * objects representing all interfaces directly extended by the
- * interface. The order of the interface objects in the array
- * corresponds to the order of the interface names in the
- * {@code extends} clause of the declaration of the interface
- * represented by this object.
- *
- * <p>If this object represents a class or interface that
- * implements no interfaces, the method returns an array of length
- * 0.
- *
- * <p>If this object represents a primitive type or void, the
- * method returns an array of length 0.
- *
- * @throws java.lang.reflect.GenericSignatureFormatError
- * if the generic class signature does not conform to the format
- * specified in
- * <cite>The Java&trade; Virtual Machine Specification</cite>
- * @throws TypeNotPresentException if any of the generic
- * superinterfaces refers to a non-existent type declaration
- * @throws java.lang.reflect.MalformedParameterizedTypeException
- * if any of the generic superinterfaces refer to a parameterized
- * type that cannot be instantiated for any reason
- * @return an array of interfaces implemented by this class
- * @since 1.5
- */
- public Type[] getGenericInterfaces() {
- ClassRepository info = getGenericInfo();
- return (info == null) ? getInterfaces() : info.getSuperInterfaces();
- }
-
-
- /**
- * Returns the {@code Class} representing the component type of an
- * array. If this class does not represent an array class this method
- * returns null.
- *
- * @return the {@code Class} representing the component type of this
- * class if this class is an array
- * @see java.lang.reflect.Array
- * @since JDK1.1
- */
- public native Class<?> getComponentType();
-
-
- /**
- * Returns the Java language modifiers for this class or interface, encoded
- * in an integer. The modifiers consist of the Java Virtual Machine's
- * constants for {@code public}, {@code protected},
- * {@code private}, {@code final}, {@code static},
- * {@code abstract} and {@code interface}; they should be decoded
- * using the methods of class {@code Modifier}.
- *
- * <p> If the underlying class is an array class, then its
- * {@code public}, {@code private} and {@code protected}
- * modifiers are the same as those of its component type. If this
- * {@code Class} represents a primitive type or void, its
- * {@code public} modifier is always {@code true}, and its
- * {@code protected} and {@code private} modifiers are always
- * {@code false}. If this object represents an array class, a
- * primitive type or void, then its {@code final} modifier is always
- * {@code true} and its interface modifier is always
- * {@code false}. The values of its other modifiers are not determined
- * by this specification.
- *
- * <p> The modifier encodings are defined in <em>The Java Virtual Machine
- * Specification</em>, table 4.1.
- *
- * @return the {@code int} representing the modifiers for this class
- * @see java.lang.reflect.Modifier
- * @since JDK1.1
- */
- public native int getModifiers();
-
-
- /**
- * Gets the signers of this class.
- *
- * @return the signers of this class, or null if there are no signers. In
- * particular, this method returns null if this object represents
- * a primitive type or void.
- * @since JDK1.1
- */
- public native Object[] getSigners();
-
-
- /**
- * Set the signers of this class.
- */
- native void setSigners(Object[] signers);
-
-
- /**
- * If this {@code Class} object represents a local or anonymous
- * class within a method, returns a {@link
- * java.lang.reflect.Method Method} object representing the
- * immediately enclosing method of the underlying class. Returns
- * {@code null} otherwise.
- *
- * In particular, this method returns {@code null} if the underlying
- * class is a local or anonymous class immediately enclosed by a type
- * declaration, instance initializer or static initializer.
- *
- * @return the immediately enclosing method of the underlying class, if
- * that class is a local or anonymous class; otherwise {@code null}.
- *
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and any of the
- * following conditions is met:
- *
- * <ul>
- *
- * <li> the caller's class loader is not the same as the
- * class loader of the enclosing class and invocation of
- * {@link SecurityManager#checkPermission
- * s.checkPermission} method with
- * {@code RuntimePermission("accessDeclaredMembers")}
- * denies access to the methods within the enclosing class
- *
- * <li> the caller's class loader is not the same as or an
- * ancestor of the class loader for the enclosing class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of the enclosing class
- *
- * </ul>
- * @since 1.5
- */
- @CallerSensitive
- public Method getEnclosingMethod() throws SecurityException {
- EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
-
- if (enclosingInfo == null)
- return null;
- else {
- if (!enclosingInfo.isMethod())
- return null;
-
- MethodRepository typeInfo = MethodRepository.make(enclosingInfo.getDescriptor(),
- getFactory());
- Class<?> returnType = toClass(typeInfo.getReturnType());
- Type [] parameterTypes = typeInfo.getParameterTypes();
- Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
-
- // Convert Types to Classes; returned types *should*
- // be class objects since the methodDescriptor's used
- // don't have generics information
- for(int i = 0; i < parameterClasses.length; i++)
- parameterClasses[i] = toClass(parameterTypes[i]);
-
- // Perform access check
- Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
- enclosingCandidate.checkMemberAccess(Member.DECLARED,
- Reflection.getCallerClass(), true);
- /*
- * Loop over all declared methods; match method name,
- * number of and type of parameters, *and* return
- * type. Matching return type is also necessary
- * because of covariant returns, etc.
- */
- for(Method m: enclosingCandidate.getDeclaredMethods()) {
- if (m.getName().equals(enclosingInfo.getName()) ) {
- Class<?>[] candidateParamClasses = m.getParameterTypes();
- if (candidateParamClasses.length == parameterClasses.length) {
- boolean matches = true;
- for(int i = 0; i < candidateParamClasses.length; i++) {
- if (!candidateParamClasses[i].equals(parameterClasses[i])) {
- matches = false;
- break;
- }
- }
-
- if (matches) { // finally, check return type
- if (m.getReturnType().equals(returnType) )
- return m;
- }
- }
- }
- }
-
- throw new InternalError("Enclosing method not found");
- }
- }
-
- private native Object[] getEnclosingMethod0();
-
- private EnclosingMethodInfo getEnclosingMethodInfo() {
- Object[] enclosingInfo = getEnclosingMethod0();
- if (enclosingInfo == null)
- return null;
- else {
- return new EnclosingMethodInfo(enclosingInfo);
- }
- }
-
- private final static class EnclosingMethodInfo {
- private Class<?> enclosingClass;
- private String name;
- private String descriptor;
-
- private EnclosingMethodInfo(Object[] enclosingInfo) {
- if (enclosingInfo.length != 3)
- throw new InternalError("Malformed enclosing method information");
- try {
- // The array is expected to have three elements:
-
- // the immediately enclosing class
- enclosingClass = (Class<?>) enclosingInfo[0];
- assert(enclosingClass != null);
-
- // the immediately enclosing method or constructor's
- // name (can be null).
- name = (String) enclosingInfo[1];
-
- // the immediately enclosing method or constructor's
- // descriptor (null iff name is).
- descriptor = (String) enclosingInfo[2];
- assert((name != null && descriptor != null) || name == descriptor);
- } catch (ClassCastException cce) {
- throw new InternalError("Invalid type in enclosing method information", cce);
- }
- }
-
- boolean isPartial() {
- return enclosingClass == null || name == null || descriptor == null;
- }
-
- boolean isConstructor() { return !isPartial() && "<init>".equals(name); }
-
- boolean isMethod() { return !isPartial() && !isConstructor() && !"<clinit>".equals(name); }
-
- Class<?> getEnclosingClass() { return enclosingClass; }
-
- String getName() { return name; }
-
- String getDescriptor() { return descriptor; }
-
- }
-
- private static Class<?> toClass(Type o) {
- if (o instanceof GenericArrayType)
- return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),
- 0)
- .getClass();
- return (Class<?>)o;
- }
-
- /**
- * If this {@code Class} object represents a local or anonymous
- * class within a constructor, returns a {@link
- * java.lang.reflect.Constructor Constructor} object representing
- * the immediately enclosing constructor of the underlying
- * class. Returns {@code null} otherwise. In particular, this
- * method returns {@code null} if the underlying class is a local
- * or anonymous class immediately enclosed by a type declaration,
- * instance initializer or static initializer.
- *
- * @return the immediately enclosing constructor of the underlying class, if
- * that class is a local or anonymous class; otherwise {@code null}.
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and any of the
- * following conditions is met:
- *
- * <ul>
- *
- * <li> the caller's class loader is not the same as the
- * class loader of the enclosing class and invocation of
- * {@link SecurityManager#checkPermission
- * s.checkPermission} method with
- * {@code RuntimePermission("accessDeclaredMembers")}
- * denies access to the constructors within the enclosing class
- *
- * <li> the caller's class loader is not the same as or an
- * ancestor of the class loader for the enclosing class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of the enclosing class
- *
- * </ul>
- * @since 1.5
- */
- @CallerSensitive
- public Constructor<?> getEnclosingConstructor() throws SecurityException {
- EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
-
- if (enclosingInfo == null)
- return null;
- else {
- if (!enclosingInfo.isConstructor())
- return null;
-
- ConstructorRepository typeInfo = ConstructorRepository.make(enclosingInfo.getDescriptor(),
- getFactory());
- Type [] parameterTypes = typeInfo.getParameterTypes();
- Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
-
- // Convert Types to Classes; returned types *should*
- // be class objects since the methodDescriptor's used
- // don't have generics information
- for(int i = 0; i < parameterClasses.length; i++)
- parameterClasses[i] = toClass(parameterTypes[i]);
-
- // Perform access check
- Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
- enclosingCandidate.checkMemberAccess(Member.DECLARED,
- Reflection.getCallerClass(), true);
- /*
- * Loop over all declared constructors; match number
- * of and type of parameters.
- */
- for(Constructor<?> c: enclosingCandidate.getDeclaredConstructors()) {
- Class<?>[] candidateParamClasses = c.getParameterTypes();
- if (candidateParamClasses.length == parameterClasses.length) {
- boolean matches = true;
- for(int i = 0; i < candidateParamClasses.length; i++) {
- if (!candidateParamClasses[i].equals(parameterClasses[i])) {
- matches = false;
- break;
- }
- }
-
- if (matches)
- return c;
- }
- }
-
- throw new InternalError("Enclosing constructor not found");
- }
- }
-
-
- /**
- * If the class or interface represented by this {@code Class} object
- * is a member of another class, returns the {@code Class} object
- * representing the class in which it was declared. This method returns
- * null if this class or interface is not a member of any other class. If
- * this {@code Class} object represents an array class, a primitive
- * type, or void,then this method returns null.
- *
- * @return the declaring class for this class
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and the caller's
- * class loader is not the same as or an ancestor of the class
- * loader for the declaring class and invocation of {@link
- * SecurityManager#checkPackageAccess s.checkPackageAccess()}
- * denies access to the package of the declaring class
- * @since JDK1.1
- */
- @CallerSensitive
- public Class<?> getDeclaringClass() throws SecurityException {
- final Class<?> candidate = getDeclaringClass0();
-
- if (candidate != null)
- candidate.checkPackageAccess(
- ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
- return candidate;
- }
-
- private native Class<?> getDeclaringClass0();
-
-
- /**
- * Returns the immediately enclosing class of the underlying
- * class. If the underlying class is a top level class this
- * method returns {@code null}.
- * @return the immediately enclosing class of the underlying class
- * @exception SecurityException
- * If a security manager, <i>s</i>, is present and the caller's
- * class loader is not the same as or an ancestor of the class
- * loader for the enclosing class and invocation of {@link
- * SecurityManager#checkPackageAccess s.checkPackageAccess()}
- * denies access to the package of the enclosing class
- * @since 1.5
- */
- @CallerSensitive
- public Class<?> getEnclosingClass() throws SecurityException {
- // There are five kinds of classes (or interfaces):
- // a) Top level classes
- // b) Nested classes (static member classes)
- // c) Inner classes (non-static member classes)
- // d) Local classes (named classes declared within a method)
- // e) Anonymous classes
-
-
- // JVM Spec 4.8.6: A class must have an EnclosingMethod
- // attribute if and only if it is a local class or an
- // anonymous class.
- EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
- Class<?> enclosingCandidate;
-
- if (enclosingInfo == null) {
- // This is a top level or a nested class or an inner class (a, b, or c)
- enclosingCandidate = getDeclaringClass();
- } else {
- Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
- // This is a local class or an anonymous class (d or e)
- if (enclosingClass == this || enclosingClass == null)
- throw new InternalError("Malformed enclosing method information");
- else
- enclosingCandidate = enclosingClass;
- }
-
- if (enclosingCandidate != null)
- enclosingCandidate.checkPackageAccess(
- ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
- return enclosingCandidate;
- }
-
- /**
- * Returns the simple name of the underlying class as given in the
- * source code. Returns an empty string if the underlying class is
- * anonymous.
- *
- * <p>The simple name of an array is the simple name of the
- * component type with "[]" appended. In particular the simple
- * name of an array whose component type is anonymous is "[]".
- *
- * @return the simple name of the underlying class
- * @since 1.5
- */
- public String getSimpleName() {
- if (isArray())
- return getComponentType().getSimpleName()+"[]";
-
- String simpleName = getSimpleBinaryName();
- if (simpleName == null) { // top level class
- simpleName = getName();
- return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name
- }
- // According to JLS3 "Binary Compatibility" (13.1) the binary
- // name of non-package classes (not top level) is the binary
- // name of the immediately enclosing class followed by a '$' followed by:
- // (for nested and inner classes): the simple name.
- // (for local classes): 1 or more digits followed by the simple name.
- // (for anonymous classes): 1 or more digits.
-
- // Since getSimpleBinaryName() will strip the binary name of
- // the immediatly enclosing class, we are now looking at a
- // string that matches the regular expression "\$[0-9]*"
- // followed by a simple name (considering the simple of an
- // anonymous class to be the empty string).
-
- // Remove leading "\$[0-9]*" from the name
- int length = simpleName.length();
- if (length < 1 || simpleName.charAt(0) != '$')
- throw new InternalError("Malformed class name");
- int index = 1;
- while (index < length && isAsciiDigit(simpleName.charAt(index)))
- index++;
- // Eventually, this is the empty string iff this is an anonymous class
- return simpleName.substring(index);
- }
-
- /**
- * Return an informative string for the name of this type.
- *
- * @return an informative string for the name of this type
- * @since 1.8
- */
- public String getTypeName() {
- if (isArray()) {
- try {
- Class<?> cl = this;
- int dimensions = 0;
- while (cl.isArray()) {
- dimensions++;
- cl = cl.getComponentType();
- }
- StringBuilder sb = new StringBuilder();
- sb.append(cl.getName());
- for (int i = 0; i < dimensions; i++) {
- sb.append("[]");
- }
- return sb.toString();
- } catch (Throwable e) { /*FALLTHRU*/ }
- }
- return getName();
- }
-
- /**
- * Character.isDigit answers {@code true} to some non-ascii
- * digits. This one does not.
- */
- private static boolean isAsciiDigit(char c) {
- return '0' <= c && c <= '9';
- }
-
- /**
- * Returns the canonical name of the underlying class as
- * defined by the Java Language Specification. Returns null if
- * the underlying class does not have a canonical name (i.e., if
- * it is a local or anonymous class or an array whose component
- * type does not have a canonical name).
- * @return the canonical name of the underlying class if it exists, and
- * {@code null} otherwise.
- * @since 1.5
- */
- public String getCanonicalName() {
- if (isArray()) {
- String canonicalName = getComponentType().getCanonicalName();
- if (canonicalName != null)
- return canonicalName + "[]";
- else
- return null;
- }
- if (isLocalOrAnonymousClass())
- return null;
- Class<?> enclosingClass = getEnclosingClass();
- if (enclosingClass == null) { // top level class
- return getName();
- } else {
- String enclosingName = enclosingClass.getCanonicalName();
- if (enclosingName == null)
- return null;
- return enclosingName + "." + getSimpleName();
- }
- }
-
- /**
- * Returns {@code true} if and only if the underlying class
- * is an anonymous class.
- *
- * @return {@code true} if and only if this class is an anonymous class.
- * @since 1.5
- */
- public boolean isAnonymousClass() {
- return "".equals(getSimpleName());
- }
-
- /**
- * Returns {@code true} if and only if the underlying class
- * is a local class.
- *
- * @return {@code true} if and only if this class is a local class.
- * @since 1.5
- */
- public boolean isLocalClass() {
- return isLocalOrAnonymousClass() && !isAnonymousClass();
- }
-
- /**
- * Returns {@code true} if and only if the underlying class
- * is a member class.
- *
- * @return {@code true} if and only if this class is a member class.
- * @since 1.5
- */
- public boolean isMemberClass() {
- return getSimpleBinaryName() != null && !isLocalOrAnonymousClass();
- }
-
- /**
- * Returns the "simple binary name" of the underlying class, i.e.,
- * the binary name without the leading enclosing class name.
- * Returns {@code null} if the underlying class is a top level
- * class.
- */
- private String getSimpleBinaryName() {
- Class<?> enclosingClass = getEnclosingClass();
- if (enclosingClass == null) // top level class
- return null;
- // Otherwise, strip the enclosing class' name
- try {
- return getName().substring(enclosingClass.getName().length());
- } catch (IndexOutOfBoundsException ex) {
- throw new InternalError("Malformed class name", ex);
- }
- }
-
- /**
- * Returns {@code true} if this is a local class or an anonymous
- * class. Returns {@code false} otherwise.
- */
- private boolean isLocalOrAnonymousClass() {
- // JVM Spec 4.8.6: A class must have an EnclosingMethod
- // attribute if and only if it is a local class or an
- // anonymous class.
- return getEnclosingMethodInfo() != null;
- }
-
- /**
- * Returns an array containing {@code Class} objects representing all
- * the public classes and interfaces that are members of the class
- * represented by this {@code Class} object. This includes public
- * class and interface members inherited from superclasses and public class
- * and interface members declared by the class. This method returns an
- * array of length 0 if this {@code Class} object has no public member
- * classes or interfaces. This method also returns an array of length 0 if
- * this {@code Class} object represents a primitive type, an array
- * class, or void.
- *
- * @return the array of {@code Class} objects representing the public
- * members of this class
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and
- * the caller's class loader is not the same as or an
- * ancestor of the class loader for the current class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of this class.
- *
- * @since JDK1.1
- */
- @CallerSensitive
- public Class<?>[] getClasses() {
- checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
-
- // Privileged so this implementation can look at DECLARED classes,
- // something the caller might not have privilege to do. The code here
- // is allowed to look at DECLARED classes because (1) it does not hand
- // out anything other than public members and (2) public member access
- // has already been ok'd by the SecurityManager.
-
- return java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Class<?>[]>() {
- public Class<?>[] run() {
- List<Class<?>> list = new ArrayList<>();
- Class<?> currentClass = Class.this;
- while (currentClass != null) {
- Class<?>[] members = currentClass.getDeclaredClasses();
- for (int i = 0; i < members.length; i++) {
- if (Modifier.isPublic(members[i].getModifiers())) {
- list.add(members[i]);
- }
- }
- currentClass = currentClass.getSuperclass();
- }
- return list.toArray(new Class<?>[0]);
- }
- });
- }
-
-
- /**
- * Returns an array containing {@code Field} objects reflecting all
- * the accessible public fields of the class or interface represented by
- * this {@code Class} object.
- *
- * <p> If this {@code Class} object represents a class or interface with no
- * no accessible public fields, then this method returns an array of length
- * 0.
- *
- * <p> If this {@code Class} object represents a class, then this method
- * returns the public fields of the class and of all its superclasses.
- *
- * <p> If this {@code Class} object represents an interface, then this
- * method returns the fields of the interface and of all its
- * superinterfaces.
- *
- * <p> If this {@code Class} object represents an array type, a primitive
- * type, or void, then this method returns an array of length 0.
- *
- * <p> The elements in the returned array are not sorted and are not in any
- * particular order.
- *
- * @return the array of {@code Field} objects representing the
- * public fields
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and
- * the caller's class loader is not the same as or an
- * ancestor of the class loader for the current class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of this class.
- *
- * @since JDK1.1
- * @jls 8.2 Class Members
- * @jls 8.3 Field Declarations
- */
- @CallerSensitive
- public Field[] getFields() throws SecurityException {
- checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
- return copyFields(privateGetPublicFields(null));
- }
-
-
- /**
- * Returns an array containing {@code Method} objects reflecting all the
- * public methods of the class or interface represented by this {@code
- * Class} object, including those declared by the class or interface and
- * those inherited from superclasses and superinterfaces.
- *
- * <p> If this {@code Class} object represents a type that has multiple
- * public methods with the same name and parameter types, but different
- * return types, then the returned array has a {@code Method} object for
- * each such method.
- *
- * <p> If this {@code Class} object represents a type with a class
- * initialization method {@code <clinit>}, then the returned array does
- * <em>not</em> have a corresponding {@code Method} object.
- *
- * <p> If this {@code Class} object represents an array type, then the
- * returned array has a {@code Method} object for each of the public
- * methods inherited by the array type from {@code Object}. It does not
- * contain a {@code Method} object for {@code clone()}.
- *
- * <p> If this {@code Class} object represents an interface then the
- * returned array does not contain any implicitly declared methods from
- * {@code Object}. Therefore, if no methods are explicitly declared in
- * this interface or any of its superinterfaces then the returned array
- * has length 0. (Note that a {@code Class} object which represents a class
- * always has public methods, inherited from {@code Object}.)
- *
- * <p> If this {@code Class} object represents a primitive type or void,
- * then the returned array has length 0.
- *
- * <p> Static methods declared in superinterfaces of the class or interface
- * represented by this {@code Class} object are not considered members of
- * the class or interface.
- *
- * <p> The elements in the returned array are not sorted and are not in any
- * particular order.
- *
- * @return the array of {@code Method} objects representing the
- * public methods of this class
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and
- * the caller's class loader is not the same as or an
- * ancestor of the class loader for the current class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of this class.
- *
- * @jls 8.2 Class Members
- * @jls 8.4 Method Declarations
- * @since JDK1.1
- */
- @CallerSensitive
- public Method[] getMethods() throws SecurityException {
- checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
- return copyMethods(privateGetPublicMethods());
- }
-
-
- /**
- * Returns an array containing {@code Constructor} objects reflecting
- * all the public constructors of the class represented by this
- * {@code Class} object. An array of length 0 is returned if the
- * class has no public constructors, or if the class is an array class, or
- * if the class reflects a primitive type or void.
- *
- * Note that while this method returns an array of {@code
- * Constructor<T>} objects (that is an array of constructors from
- * this class), the return type of this method is {@code
- * Constructor<?>[]} and <em>not</em> {@code Constructor<T>[]} as
- * might be expected. This less informative return type is
- * necessary since after being returned from this method, the
- * array could be modified to hold {@code Constructor} objects for
- * different classes, which would violate the type guarantees of
- * {@code Constructor<T>[]}.
- *
- * @return the array of {@code Constructor} objects representing the
- * public constructors of this class
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and
- * the caller's class loader is not the same as or an
- * ancestor of the class loader for the current class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of this class.
- *
- * @since JDK1.1
- */
- @CallerSensitive
- public Constructor<?>[] getConstructors() throws SecurityException {
- checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
- return copyConstructors(privateGetDeclaredConstructors(true));
- }
-
-
- /**
- * Returns a {@code Field} object that reflects the specified public member
- * field of the class or interface represented by this {@code Class}
- * object. The {@code name} parameter is a {@code String} specifying the
- * simple name of the desired field.
- *
- * <p> The field to be reflected is determined by the algorithm that
- * follows. Let C be the class or interface represented by this object:
- *
- * <OL>
- * <LI> If C declares a public field with the name specified, that is the
- * field to be reflected.</LI>
- * <LI> If no field was found in step 1 above, this algorithm is applied
- * recursively to each direct superinterface of C. The direct
- * superinterfaces are searched in the order they were declared.</LI>
- * <LI> If no field was found in steps 1 and 2 above, and C has a
- * superclass S, then this algorithm is invoked recursively upon S.
- * If C has no superclass, then a {@code NoSuchFieldException}
- * is thrown.</LI>
- * </OL>
- *
- * <p> If this {@code Class} object represents an array type, then this
- * method does not find the {@code length} field of the array type.
- *
- * @param name the field name
- * @return the {@code Field} object of this class specified by
- * {@code name}
- * @throws NoSuchFieldException if a field with the specified name is
- * not found.
- * @throws NullPointerException if {@code name} is {@code null}
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and
- * the caller's class loader is not the same as or an
- * ancestor of the class loader for the current class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of this class.
- *
- * @since JDK1.1
- * @jls 8.2 Class Members
- * @jls 8.3 Field Declarations
- */
- @CallerSensitive
- public Field getField(String name)
- throws NoSuchFieldException, SecurityException {
- checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
- Field field = getField0(name);
- if (field == null) {
- throw new NoSuchFieldException(name);
- }
- return field;
- }
-
-
- /**
- * Returns a {@code Method} object that reflects the specified public
- * member method of the class or interface represented by this
- * {@code Class} object. The {@code name} parameter is a
- * {@code String} specifying the simple name of the desired method. The
- * {@code parameterTypes} parameter is an array of {@code Class}
- * objects that identify the method's formal parameter types, in declared
- * order. If {@code parameterTypes} is {@code null}, it is
- * treated as if it were an empty array.
- *
- * <p> If the {@code name} is "{@code <init>}" or "{@code <clinit>}" a
- * {@code NoSuchMethodException} is raised. Otherwise, the method to
- * be reflected is determined by the algorithm that follows. Let C be the
- * class or interface represented by this object:
- * <OL>
- * <LI> C is searched for a <I>matching method</I>, as defined below. If a
- * matching method is found, it is reflected.</LI>
- * <LI> If no matching method is found by step 1 then:
- * <OL TYPE="a">
- * <LI> If C is a class other than {@code Object}, then this algorithm is
- * invoked recursively on the superclass of C.</LI>
- * <LI> If C is the class {@code Object}, or if C is an interface, then
- * the superinterfaces of C (if any) are searched for a matching
- * method. If any such method is found, it is reflected.</LI>
- * </OL></LI>
- * </OL>
- *
- * <p> To find a matching method in a class or interface C:&nbsp; If C
- * declares exactly one public method with the specified name and exactly
- * the same formal parameter types, that is the method reflected. If more
- * than one such method is found in C, and one of these methods has a
- * return type that is more specific than any of the others, that method is
- * reflected; otherwise one of the methods is chosen arbitrarily.
- *
- * <p>Note that there may be more than one matching method in a
- * class because while the Java language forbids a class to
- * declare multiple methods with the same signature but different
- * return types, the Java virtual machine does not. This
- * increased flexibility in the virtual machine can be used to
- * implement various language features. For example, covariant
- * returns can be implemented with {@linkplain
- * java.lang.reflect.Method#isBridge bridge methods}; the bridge
- * method and the method being overridden would have the same
- * signature but different return types.
- *
- * <p> If this {@code Class} object represents an array type, then this
- * method does not find the {@code clone()} method.
- *
- * <p> Static methods declared in superinterfaces of the class or interface
- * represented by this {@code Class} object are not considered members of
- * the class or interface.
- *
- * @param name the name of the method
- * @param parameterTypes the list of parameters
- * @return the {@code Method} object that matches the specified
- * {@code name} and {@code parameterTypes}
- * @throws NoSuchMethodException if a matching method is not found
- * or if the name is "&lt;init&gt;"or "&lt;clinit&gt;".
- * @throws NullPointerException if {@code name} is {@code null}
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and
- * the caller's class loader is not the same as or an
- * ancestor of the class loader for the current class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of this class.
- *
- * @jls 8.2 Class Members
- * @jls 8.4 Method Declarations
- * @since JDK1.1
- */
- @CallerSensitive
- public Method getMethod(String name, Class<?>... parameterTypes)
- throws NoSuchMethodException, SecurityException {
- checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
- Method method = getMethod0(name, parameterTypes, true);
- if (method == null) {
- throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
- }
- return method;
- }
-
-
- /**
- * Returns a {@code Constructor} object that reflects the specified
- * public constructor of the class represented by this {@code Class}
- * object. The {@code parameterTypes} parameter is an array of
- * {@code Class} objects that identify the constructor's formal
- * parameter types, in declared order.
- *
- * If this {@code Class} object represents an inner class
- * declared in a non-static context, the formal parameter types
- * include the explicit enclosing instance as the first parameter.
- *
- * <p> The constructor to reflect is the public constructor of the class
- * represented by this {@code Class} object whose formal parameter
- * types match those specified by {@code parameterTypes}.
- *
- * @param parameterTypes the parameter array
- * @return the {@code Constructor} object of the public constructor that
- * matches the specified {@code parameterTypes}
- * @throws NoSuchMethodException if a matching method is not found.
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and
- * the caller's class loader is not the same as or an
- * ancestor of the class loader for the current class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of this class.
- *
- * @since JDK1.1
- */
- @CallerSensitive
- public Constructor<T> getConstructor(Class<?>... parameterTypes)
- throws NoSuchMethodException, SecurityException {
- checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
- return getConstructor0(parameterTypes, Member.PUBLIC);
- }
-
-
- /**
- * Returns an array of {@code Class} objects reflecting all the
- * classes and interfaces declared as members of the class represented by
- * this {@code Class} object. This includes public, protected, default
- * (package) access, and private classes and interfaces declared by the
- * class, but excludes inherited classes and interfaces. This method
- * returns an array of length 0 if the class declares no classes or
- * interfaces as members, or if this {@code Class} object represents a
- * primitive type, an array class, or void.
- *
- * @return the array of {@code Class} objects representing all the
- * declared members of this class
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and any of the
- * following conditions is met:
- *
- * <ul>
- *
- * <li> the caller's class loader is not the same as the
- * class loader of this class and invocation of
- * {@link SecurityManager#checkPermission
- * s.checkPermission} method with
- * {@code RuntimePermission("accessDeclaredMembers")}
- * denies access to the declared classes within this class
- *
- * <li> the caller's class loader is not the same as or an
- * ancestor of the class loader for the current class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of this class
- *
- * </ul>
- *
- * @since JDK1.1
- */
- @CallerSensitive
- public Class<?>[] getDeclaredClasses() throws SecurityException {
- checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), false);
- return getDeclaredClasses0();
- }
-
-
- /**
- * Returns an array of {@code Field} objects reflecting all the fields
- * declared by the class or interface represented by this
- * {@code Class} object. This includes public, protected, default
- * (package) access, and private fields, but excludes inherited fields.
- *
- * <p> If this {@code Class} object represents a class or interface with no
- * declared fields, then this method returns an array of length 0.
- *
- * <p> If this {@code Class} object represents an array type, a primitive
- * type, or void, then this method returns an array of length 0.
- *
- * <p> The elements in the returned array are not sorted and are not in any
- * particular order.
- *
- * @return the array of {@code Field} objects representing all the
- * declared fields of this class
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and any of the
- * following conditions is met:
- *
- * <ul>
- *
- * <li> the caller's class loader is not the same as the
- * class loader of this class and invocation of
- * {@link SecurityManager#checkPermission
- * s.checkPermission} method with
- * {@code RuntimePermission("accessDeclaredMembers")}
- * denies access to the declared fields within this class
- *
- * <li> the caller's class loader is not the same as or an
- * ancestor of the class loader for the current class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of this class
- *
- * </ul>
- *
- * @since JDK1.1
- * @jls 8.2 Class Members
- * @jls 8.3 Field Declarations
- */
- @CallerSensitive
- public Field[] getDeclaredFields() throws SecurityException {
- checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
- return copyFields(privateGetDeclaredFields(false));
- }
-
-
- /**
- *
- * Returns an array containing {@code Method} objects reflecting all the
- * declared methods of the class or interface represented by this {@code
- * Class} object, including public, protected, default (package)
- * access, and private methods, but excluding inherited methods.
- *
- * <p> If this {@code Class} object represents a type that has multiple
- * declared methods with the same name and parameter types, but different
- * return types, then the returned array has a {@code Method} object for
- * each such method.
- *
- * <p> If this {@code Class} object represents a type that has a class
- * initialization method {@code <clinit>}, then the returned array does
- * <em>not</em> have a corresponding {@code Method} object.
- *
- * <p> If this {@code Class} object represents a class or interface with no
- * declared methods, then the returned array has length 0.
- *
- * <p> If this {@code Class} object represents an array type, a primitive
- * type, or void, then the returned array has length 0.
- *
- * <p> The elements in the returned array are not sorted and are not in any
- * particular order.
- *
- * @return the array of {@code Method} objects representing all the
- * declared methods of this class
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and any of the
- * following conditions is met:
- *
- * <ul>
- *
- * <li> the caller's class loader is not the same as the
- * class loader of this class and invocation of
- * {@link SecurityManager#checkPermission
- * s.checkPermission} method with
- * {@code RuntimePermission("accessDeclaredMembers")}
- * denies access to the declared methods within this class
- *
- * <li> the caller's class loader is not the same as or an
- * ancestor of the class loader for the current class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of this class
- *
- * </ul>
- *
- * @jls 8.2 Class Members
- * @jls 8.4 Method Declarations
- * @since JDK1.1
- */
- @CallerSensitive
- public Method[] getDeclaredMethods() throws SecurityException {
- checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
- return copyMethods(privateGetDeclaredMethods(false));
- }
-
-
- /**
- * Returns an array of {@code Constructor} objects reflecting all the
- * constructors declared by the class represented by this
- * {@code Class} object. These are public, protected, default
- * (package) access, and private constructors. The elements in the array
- * returned are not sorted and are not in any particular order. If the
- * class has a default constructor, it is included in the returned array.
- * This method returns an array of length 0 if this {@code Class}
- * object represents an interface, a primitive type, an array class, or
- * void.
- *
- * <p> See <em>The Java Language Specification</em>, section 8.2.
- *
- * @return the array of {@code Constructor} objects representing all the
- * declared constructors of this class
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and any of the
- * following conditions is met:
- *
- * <ul>
- *
- * <li> the caller's class loader is not the same as the
- * class loader of this class and invocation of
- * {@link SecurityManager#checkPermission
- * s.checkPermission} method with
- * {@code RuntimePermission("accessDeclaredMembers")}
- * denies access to the declared constructors within this class
- *
- * <li> the caller's class loader is not the same as or an
- * ancestor of the class loader for the current class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of this class
- *
- * </ul>
- *
- * @since JDK1.1
- */
- @CallerSensitive
- public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
- checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
- return copyConstructors(privateGetDeclaredConstructors(false));
- }
-
-
- /**
- * Returns a {@code Field} object that reflects the specified declared
- * field of the class or interface represented by this {@code Class}
- * object. The {@code name} parameter is a {@code String} that specifies
- * the simple name of the desired field.
- *
- * <p> If this {@code Class} object represents an array type, then this
- * method does not find the {@code length} field of the array type.
- *
- * @param name the name of the field
- * @return the {@code Field} object for the specified field in this
- * class
- * @throws NoSuchFieldException if a field with the specified name is
- * not found.
- * @throws NullPointerException if {@code name} is {@code null}
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and any of the
- * following conditions is met:
- *
- * <ul>
- *
- * <li> the caller's class loader is not the same as the
- * class loader of this class and invocation of
- * {@link SecurityManager#checkPermission
- * s.checkPermission} method with
- * {@code RuntimePermission("accessDeclaredMembers")}
- * denies access to the declared field
- *
- * <li> the caller's class loader is not the same as or an
- * ancestor of the class loader for the current class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of this class
- *
- * </ul>
- *
- * @since JDK1.1
- * @jls 8.2 Class Members
- * @jls 8.3 Field Declarations
- */
- @CallerSensitive
- public Field getDeclaredField(String name)
- throws NoSuchFieldException, SecurityException {
- checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
- Field field = searchFields(privateGetDeclaredFields(false), name);
- if (field == null) {
- throw new NoSuchFieldException(name);
- }
- return field;
- }
-
-
- /**
- * Returns a {@code Method} object that reflects the specified
- * declared method of the class or interface represented by this
- * {@code Class} object. The {@code name} parameter is a
- * {@code String} that specifies the simple name of the desired
- * method, and the {@code parameterTypes} parameter is an array of
- * {@code Class} objects that identify the method's formal parameter
- * types, in declared order. If more than one method with the same
- * parameter types is declared in a class, and one of these methods has a
- * return type that is more specific than any of the others, that method is
- * returned; otherwise one of the methods is chosen arbitrarily. If the
- * name is "&lt;init&gt;"or "&lt;clinit&gt;" a {@code NoSuchMethodException}
- * is raised.
- *
- * <p> If this {@code Class} object represents an array type, then this
- * method does not find the {@code clone()} method.
- *
- * @param name the name of the method
- * @param parameterTypes the parameter array
- * @return the {@code Method} object for the method of this class
- * matching the specified name and parameters
- * @throws NoSuchMethodException if a matching method is not found.
- * @throws NullPointerException if {@code name} is {@code null}
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and any of the
- * following conditions is met:
- *
- * <ul>
- *
- * <li> the caller's class loader is not the same as the
- * class loader of this class and invocation of
- * {@link SecurityManager#checkPermission
- * s.checkPermission} method with
- * {@code RuntimePermission("accessDeclaredMembers")}
- * denies access to the declared method
- *
- * <li> the caller's class loader is not the same as or an
- * ancestor of the class loader for the current class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of this class
- *
- * </ul>
- *
- * @jls 8.2 Class Members
- * @jls 8.4 Method Declarations
- * @since JDK1.1
- */
- @CallerSensitive
- public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
- throws NoSuchMethodException, SecurityException {
- checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
- Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
- if (method == null) {
- throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
- }
- return method;
- }
-
-
- /**
- * Returns a {@code Constructor} object that reflects the specified
- * constructor of the class or interface represented by this
- * {@code Class} object. The {@code parameterTypes} parameter is
- * an array of {@code Class} objects that identify the constructor's
- * formal parameter types, in declared order.
- *
- * If this {@code Class} object represents an inner class
- * declared in a non-static context, the formal parameter types
- * include the explicit enclosing instance as the first parameter.
- *
- * @param parameterTypes the parameter array
- * @return The {@code Constructor} object for the constructor with the
- * specified parameter list
- * @throws NoSuchMethodException if a matching method is not found.
- * @throws SecurityException
- * If a security manager, <i>s</i>, is present and any of the
- * following conditions is met:
- *
- * <ul>
- *
- * <li> the caller's class loader is not the same as the
- * class loader of this class and invocation of
- * {@link SecurityManager#checkPermission
- * s.checkPermission} method with
- * {@code RuntimePermission("accessDeclaredMembers")}
- * denies access to the declared constructor
- *
- * <li> the caller's class loader is not the same as or an
- * ancestor of the class loader for the current class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of this class
- *
- * </ul>
- *
- * @since JDK1.1
- */
- @CallerSensitive
- public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
- throws NoSuchMethodException, SecurityException {
- checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
- return getConstructor0(parameterTypes, Member.DECLARED);
- }
-
- /**
- * Finds a resource with a given name. The rules for searching resources
- * associated with a given class are implemented by the defining
- * {@linkplain ClassLoader class loader} of the class. This method
- * delegates to this object's class loader. If this object was loaded by
- * the bootstrap class loader, the method delegates to {@link
- * ClassLoader#getSystemResourceAsStream}.
- *
- * <p> Before delegation, an absolute resource name is constructed from the
- * given resource name using this algorithm:
- *
- * <ul>
- *
- * <li> If the {@code name} begins with a {@code '/'}
- * (<tt>'&#92;u002f'</tt>), then the absolute name of the resource is the
- * portion of the {@code name} following the {@code '/'}.
- *
- * <li> Otherwise, the absolute name is of the following form:
- *
- * <blockquote>
- * {@code modified_package_name/name}
- * </blockquote>
- *
- * <p> Where the {@code modified_package_name} is the package name of this
- * object with {@code '/'} substituted for {@code '.'}
- * (<tt>'&#92;u002e'</tt>).
- *
- * </ul>
- *
- * @param name name of the desired resource
- * @return A {@link java.io.InputStream} object or {@code null} if
- * no resource with this name is found
- * @throws NullPointerException If {@code name} is {@code null}
- * @since JDK1.1
- */
- public InputStream getResourceAsStream(String name) {
- name = resolveName(name);
- ClassLoader cl = getClassLoader0();
- if (cl==null) {
- // A system class.
- return ClassLoader.getSystemResourceAsStream(name);
- }
- return cl.getResourceAsStream(name);
- }
-
- /**
- * Finds a resource with a given name. The rules for searching resources
- * associated with a given class are implemented by the defining
- * {@linkplain ClassLoader class loader} of the class. This method
- * delegates to this object's class loader. If this object was loaded by
- * the bootstrap class loader, the method delegates to {@link
- * ClassLoader#getSystemResource}.
- *
- * <p> Before delegation, an absolute resource name is constructed from the
- * given resource name using this algorithm:
- *
- * <ul>
- *
- * <li> If the {@code name} begins with a {@code '/'}
- * (<tt>'&#92;u002f'</tt>), then the absolute name of the resource is the
- * portion of the {@code name} following the {@code '/'}.
- *
- * <li> Otherwise, the absolute name is of the following form:
- *
- * <blockquote>
- * {@code modified_package_name/name}
- * </blockquote>
- *
- * <p> Where the {@code modified_package_name} is the package name of this
- * object with {@code '/'} substituted for {@code '.'}
- * (<tt>'&#92;u002e'</tt>).
- *
- * </ul>
- *
- * @param name name of the desired resource
- * @return A {@link java.net.URL} object or {@code null} if no
- * resource with this name is found
- * @since JDK1.1
- */
- public java.net.URL getResource(String name) {
- name = resolveName(name);
- ClassLoader cl = getClassLoader0();
- if (cl==null) {
- // A system class.
- return ClassLoader.getSystemResource(name);
- }
- return cl.getResource(name);
- }
-
-
-
- /** protection domain returned when the internal domain is null */
- private static java.security.ProtectionDomain allPermDomain;
-
-
- /**
- * Returns the {@code ProtectionDomain} of this class. If there is a
- * security manager installed, this method first calls the security
- * manager's {@code checkPermission} method with a
- * {@code RuntimePermission("getProtectionDomain")} permission to
- * ensure it's ok to get the
- * {@code ProtectionDomain}.
- *
- * @return the ProtectionDomain of this class
- *
- * @throws SecurityException
- * if a security manager exists and its
- * {@code checkPermission} method doesn't allow
- * getting the ProtectionDomain.
- *
- * @see java.security.ProtectionDomain
- * @see SecurityManager#checkPermission
- * @see java.lang.RuntimePermission
- * @since 1.2
- */
- public java.security.ProtectionDomain getProtectionDomain() {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(SecurityConstants.GET_PD_PERMISSION);
- }
- java.security.ProtectionDomain pd = getProtectionDomain0();
- if (pd == null) {
- if (allPermDomain == null) {
- java.security.Permissions perms =
- new java.security.Permissions();
- perms.add(SecurityConstants.ALL_PERMISSION);
- allPermDomain =
- new java.security.ProtectionDomain(null, perms);
- }
- pd = allPermDomain;
- }
- return pd;
- }
-
-
- /**
- * Returns the ProtectionDomain of this class.
- */
- private native java.security.ProtectionDomain getProtectionDomain0();
-
- /*
- * Return the Virtual Machine's Class object for the named
- * primitive type.
- */
- static native Class<?> getPrimitiveClass(String name);
-
- /*
- * Check if client is allowed to access members. If access is denied,
- * throw a SecurityException.
- *
- * This method also enforces package access.
- *
- * <p> Default policy: allow all clients access with normal Java access
- * control.
- */
- private void checkMemberAccess(int which, Class<?> caller, boolean checkProxyInterfaces) {
- final SecurityManager s = System.getSecurityManager();
- if (s != null) {
- /* Default policy allows access to all {@link Member#PUBLIC} members,
- * as well as access to classes that have the same class loader as the caller.
- * In all other cases, it requires RuntimePermission("accessDeclaredMembers")
- * permission.
- */
- final ClassLoader ccl = ClassLoader.getClassLoader(caller);
- final ClassLoader cl = getClassLoader0();
- if (which != Member.PUBLIC) {
- if (ccl != cl) {
- s.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
- }
- }
- this.checkPackageAccess(ccl, checkProxyInterfaces);
- }
- }
-
- /*
- * Checks if a client loaded in ClassLoader ccl is allowed to access this
- * class under the current package access policy. If access is denied,
- * throw a SecurityException.
- */
- private void checkPackageAccess(final ClassLoader ccl, boolean checkProxyInterfaces) {
- final SecurityManager s = System.getSecurityManager();
- if (s != null) {
- final ClassLoader cl = getClassLoader0();
-
- if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
- String name = this.getName();
- int i = name.lastIndexOf('.');
- if (i != -1) {
- // skip the package access check on a proxy class in default proxy package
- String pkg = name.substring(0, i);
- if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) {
- s.checkPackageAccess(pkg);
- }
- }
- }
- // check package access on the proxy interfaces
- if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
- ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
- }
- }
- }
-
- /**
- * Add a package name prefix if the name is not absolute Remove leading "/"
- * if name is absolute
- */
- private String resolveName(String name) {
- if (name == null) {
- return name;
- }
- if (!name.startsWith("/")) {
- Class<?> c = this;
- while (c.isArray()) {
- c = c.getComponentType();
- }
- String baseName = c.getName();
- int index = baseName.lastIndexOf('.');
- if (index != -1) {
- name = baseName.substring(0, index).replace('.', '/')
- +"/"+name;
- }
- } else {
- name = name.substring(1);
- }
- return name;
- }
-
- /**
- * Atomic operations support.
- */
- private static class Atomic {
- @ikvm.internal.InterlockedCompareAndSet("reflectionData")
- static native <T> boolean casReflectionData(Class<?> clazz,
- SoftReference<ReflectionData<T>> oldData,
- SoftReference<ReflectionData<T>> newData);
-
- @ikvm.internal.InterlockedCompareAndSet("annotationType")
- static native <T> boolean casAnnotationType(Class<?> clazz,
- AnnotationType oldType,
- AnnotationType newType);
-
- @ikvm.internal.InterlockedCompareAndSet("annotationData")
- static native <T> boolean casAnnotationData(Class<?> clazz,
- AnnotationData oldData,
- AnnotationData newData);
- }
-
- /**
- * Reflection support.
- */
-
- // Caches for certain reflective results
- private static boolean useCaches;
-
- // reflection data that might get invalidated when JVM TI RedefineClasses() is called
- private static class ReflectionData<T> {
- volatile Field[] declaredFields;
- volatile Field[] publicFields;
- volatile Method[] declaredMethods;
- volatile Method[] publicMethods;
- volatile Constructor<T>[] declaredConstructors;
- volatile Constructor<T>[] publicConstructors;
- // Intermediate results for getFields and getMethods
- volatile Field[] declaredPublicFields;
- volatile Method[] declaredPublicMethods;
- volatile Class<?>[] interfaces;
-
- // Value of classRedefinedCount when we created this ReflectionData instance
- final int redefinedCount;
-
- ReflectionData(int redefinedCount) {
- this.redefinedCount = redefinedCount;
- }
- }
-
- private volatile transient SoftReference<ReflectionData<T>> reflectionData;
-
- // Incremented by the VM on each call to JVM TI RedefineClasses()
- // that redefines this class or a superclass.
- private volatile transient int classRedefinedCount;
-
- // Lazily create and cache ReflectionData
- private ReflectionData<T> reflectionData() {
- SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
- int classRedefinedCount = this.classRedefinedCount;
- ReflectionData<T> rd;
- if (useCaches &&
- reflectionData != null &&
- (rd = reflectionData.get()) != null &&
- rd.redefinedCount == classRedefinedCount) {
- return rd;
- }
- // else no SoftReference or cleared SoftReference or stale ReflectionData
- // -> create and replace new instance
- return newReflectionData(reflectionData, classRedefinedCount);
- }
-
- private ReflectionData<T> newReflectionData(SoftReference<ReflectionData<T>> oldReflectionData,
- int classRedefinedCount) {
- if (!useCaches) return null;
-
- while (true) {
- ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
- // try to CAS it...
- if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference<>(rd))) {
- return rd;
- }
- // else retry
- oldReflectionData = this.reflectionData;
- classRedefinedCount = this.classRedefinedCount;
- if (oldReflectionData != null &&
- (rd = oldReflectionData.get()) != null &&
- rd.redefinedCount == classRedefinedCount) {
- return rd;
- }
- }
- }
-
- // Generic signature handling
- private native String getGenericSignature0();
-
- // Generic info repository; lazily initialized
- private volatile transient ClassRepository genericInfo;
-
- // accessor for factory
- private GenericsFactory getFactory() {
- // create scope and factory
- return CoreReflectionFactory.make(this, ClassScope.make(this));
- }
-
- // accessor for generic info repository;
- // generic info is lazily initialized
- private ClassRepository getGenericInfo() {
- ClassRepository genericInfo = this.genericInfo;
- if (genericInfo == null) {
- String signature = getGenericSignature0();
- if (signature == null) {
- genericInfo = ClassRepository.NONE;
- } else {
- genericInfo = ClassRepository.make(signature, getFactory());
- }
- this.genericInfo = genericInfo;
- }
- return (genericInfo != ClassRepository.NONE) ? genericInfo : null;
- }
-
- // Annotations handling
- private native Map<Class<? extends Annotation>, Annotation> getDeclaredAnnotationsImpl();
- // Since 1.8
- native byte[] getRawTypeAnnotations();
- static byte[] getExecutableTypeAnnotationBytes(Executable ex) {
- return getReflectionFactory().getExecutableTypeAnnotationBytes(ex);
- }
-
- native ConstantPool getConstantPool();
-
- //
- //
- // java.lang.reflect.Field handling
- //
- //
-
- // Returns an array of "root" fields. These Field objects must NOT
- // be propagated to the outside world, but must instead be copied
- // via ReflectionFactory.copyField.
- private Field[] privateGetDeclaredFields(boolean publicOnly) {
- checkInitted();
- Field[] res;
- ReflectionData<T> rd = reflectionData();
- if (rd != null) {
- res = publicOnly ? rd.declaredPublicFields : rd.declaredFields;
- if (res != null) return res;
- }
- // No cached value available; request value from VM
- res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
- if (rd != null) {
- if (publicOnly) {
- rd.declaredPublicFields = res;
- } else {
- rd.declaredFields = res;
- }
- }
- return res;
- }
-
- // Returns an array of "root" fields. These Field objects must NOT
- // be propagated to the outside world, but must instead be copied
- // via ReflectionFactory.copyField.
- private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) {
- checkInitted();
- Field[] res;
- ReflectionData<T> rd = reflectionData();
- if (rd != null) {
- res = rd.publicFields;
- if (res != null) return res;
- }
-
- // No cached value available; compute value recursively.
- // Traverse in correct order for getField().
- List<Field> fields = new ArrayList<>();
- if (traversedInterfaces == null) {
- traversedInterfaces = new HashSet<>();
- }
-
- // Local fields
- Field[] tmp = privateGetDeclaredFields(true);
- addAll(fields, tmp);
-
- // Direct superinterfaces, recursively
- for (Class<?> c : getInterfaces()) {
- if (!traversedInterfaces.contains(c)) {
- traversedInterfaces.add(c);
- addAll(fields, c.privateGetPublicFields(traversedInterfaces));
- }
- }
-
- // Direct superclass, recursively
- if (!isInterface()) {
- Class<?> c = getSuperclass();
- if (c != null) {
- addAll(fields, c.privateGetPublicFields(traversedInterfaces));
- }
- }
-
- res = new Field[fields.size()];
- fields.toArray(res);
- if (rd != null) {
- rd.publicFields = res;
- }
- return res;
- }
-
- private static void addAll(Collection<Field> c, Field[] o) {
- for (int i = 0; i < o.length; i++) {
- c.add(o[i]);
- }
- }
-
-
- //
- //
- // java.lang.reflect.Constructor handling
- //
- //
-
- // Returns an array of "root" constructors. These Constructor
- // objects must NOT be propagated to the outside world, but must
- // instead be copied via ReflectionFactory.copyConstructor.
- private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) {
- checkInitted();
- Constructor<T>[] res;
- ReflectionData<T> rd = reflectionData();
- if (rd != null) {
- res = publicOnly ? rd.publicConstructors : rd.declaredConstructors;
- if (res != null) return res;
- }
- // No cached value available; request value from VM
- if (isInterface()) {
- @SuppressWarnings("unchecked")
- Constructor<T>[] temporaryRes = (Constructor<T>[]) new Constructor<?>[0];
- res = temporaryRes;
- } else {
- res = getDeclaredConstructors0(publicOnly);
- }
- if (rd != null) {
- if (publicOnly) {
- rd.publicConstructors = res;
- } else {
- rd.declaredConstructors = res;
- }
- }
- return res;
- }
-
- //
- //
- // java.lang.reflect.Method handling
- //
- //
-
- // Returns an array of "root" methods. These Method objects must NOT
- // be propagated to the outside world, but must instead be copied
- // via ReflectionFactory.copyMethod.
- private Method[] privateGetDeclaredMethods(boolean publicOnly) {
- checkInitted();
- Method[] res;
- ReflectionData<T> rd = reflectionData();
- if (rd != null) {
- res = publicOnly ? rd.declaredPublicMethods : rd.declaredMethods;
- if (res != null) return res;
- }
- // No cached value available; request value from VM
- res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
- if (rd != null) {
- if (publicOnly) {
- rd.declaredPublicMethods = res;
- } else {
- rd.declaredMethods = res;
- }
- }
- return res;
- }
-
- static class MethodArray {
- private Method[] methods;
- private int length;
-
- MethodArray() {
- methods = new Method[20];
- length = 0;
- }
-
- void add(Method m) {
- if (length == methods.length) {
- methods = Arrays.copyOf(methods, 2 * methods.length);
- }
- methods[length++] = m;
- }
-
- void addAll(Method[] ma) {
- for (int i = 0; i < ma.length; i++) {
- add(ma[i]);
- }
- }
-
- void addAll(MethodArray ma) {
- for (int i = 0; i < ma.length(); i++) {
- add(ma.get(i));
- }
- }
-
- void addIfNotPresent(Method newMethod) {
- for (int i = 0; i < length; i++) {
- Method m = methods[i];
- if (m == newMethod || (m != null && m.equals(newMethod))) {
- return;
- }
- }
- add(newMethod);
- }
-
- void addAllIfNotPresent(MethodArray newMethods) {
- for (int i = 0; i < newMethods.length(); i++) {
- Method m = newMethods.get(i);
- if (m != null) {
- addIfNotPresent(m);
- }
- }
- }
-
- void addAllNonStatic(Method[] methods) {
- for (Method candidate : methods) {
- if (!Modifier.isStatic(candidate.getModifiers())) {
- add(candidate);
- }
- }
- }
-
- int length() {
- return length;
- }
-
- Method get(int i) {
- return methods[i];
- }
-
- void removeByNameAndSignature(Method toRemove) {
- for (int i = 0; i < length; i++) {
- Method m = methods[i];
- if (m != null &&
- m.getReturnType() == toRemove.getReturnType() &&
- m.getName() == toRemove.getName() &&
- arrayContentsEq(m.getParameterTypes(),
- toRemove.getParameterTypes())) {
- methods[i] = null;
- }
- }
- }
-
- void compactAndTrim() {
- int newPos = 0;
- // Get rid of null slots
- for (int pos = 0; pos < length; pos++) {
- Method m = methods[pos];
- if (m != null) {
- if (pos != newPos) {
- methods[newPos] = m;
- }
- newPos++;
- }
- }
- if (newPos != methods.length) {
- methods = Arrays.copyOf(methods, newPos);
- }
- }
-
- Method[] getArray() {
- return methods;
- }
- }
-
-
- // Returns an array of "root" methods. These Method objects must NOT
- // be propagated to the outside world, but must instead be copied
- // via ReflectionFactory.copyMethod.
- private Method[] privateGetPublicMethods() {
- checkInitted();
- Method[] res;
- ReflectionData<T> rd = reflectionData();
- if (rd != null) {
- res = rd.publicMethods;
- if (res != null) return res;
- }
-
- // No cached value available; compute value recursively.
- // Start by fetching public declared methods
- MethodArray methods = new MethodArray();
- {
- Method[] tmp = privateGetDeclaredMethods(true);
- methods.addAll(tmp);
- }
- // Now recur over superclass and direct superinterfaces.
- // Go over superinterfaces first so we can more easily filter
- // out concrete implementations inherited from superclasses at
- // the end.
- MethodArray inheritedMethods = new MethodArray();
- Class<?>[] interfaces = getInterfaces();
- for (int i = 0; i < interfaces.length; i++) {
- inheritedMethods.addAllNonStatic(interfaces[i].privateGetPublicMethods());
- }
- if (!isInterface()) {
- Class<?> c = getSuperclass();
- if (c != null) {
- MethodArray supers = new MethodArray();
- supers.addAll(c.privateGetPublicMethods());
- // Filter out concrete implementations of any
- // interface methods
- for (int i = 0; i < supers.length(); i++) {
- Method m = supers.get(i);
- if (m != null && !Modifier.isAbstract(m.getModifiers())) {
- inheritedMethods.removeByNameAndSignature(m);
- }
- }
- // Insert superclass's inherited methods before
- // superinterfaces' to satisfy getMethod's search
- // order
- supers.addAll(inheritedMethods);
- inheritedMethods = supers;
- }
- }
- // Filter out all local methods from inherited ones
- for (int i = 0; i < methods.length(); i++) {
- Method m = methods.get(i);
- inheritedMethods.removeByNameAndSignature(m);
- }
- methods.addAllIfNotPresent(inheritedMethods);
- methods.compactAndTrim();
- res = methods.getArray();
- if (rd != null) {
- rd.publicMethods = res;
- }
- return res;
- }
-
-
- //
- // Helpers for fetchers of one field, method, or constructor
- //
-
- private static Field searchFields(Field[] fields, String name) {
- String internedName = name.intern();
- for (int i = 0; i < fields.length; i++) {
- if (fields[i].getName() == internedName) {
- return getReflectionFactory().copyField(fields[i]);
- }
- }
- return null;
- }
-
- private Field getField0(String name) throws NoSuchFieldException {
- // Note: the intent is that the search algorithm this routine
- // uses be equivalent to the ordering imposed by
- // privateGetPublicFields(). It fetches only the declared
- // public fields for each class, however, to reduce the number
- // of Field objects which have to be created for the common
- // case where the field being requested is declared in the
- // class which is being queried.
- Field res;
- // Search declared public fields
- if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {
- return res;
- }
- // Direct superinterfaces, recursively
- Class<?>[] interfaces = getInterfaces();
- for (int i = 0; i < interfaces.length; i++) {
- Class<?> c = interfaces[i];
- if ((res = c.getField0(name)) != null) {
- return res;
- }
- }
- // Direct superclass, recursively
- if (!isInterface()) {
- Class<?> c = getSuperclass();
- if (c != null) {
- if ((res = c.getField0(name)) != null) {
- return res;
- }
- }
- }
- return null;
- }
-
- private static Method searchMethods(Method[] methods,
- String name,
- Class<?>[] parameterTypes)
- {
- Method res = null;
- String internedName = name.intern();
- for (int i = 0; i < methods.length; i++) {
- Method m = methods[i];
- if (m.getName() == internedName
- && arrayContentsEq(parameterTypes, m.getParameterTypes())
- && (res == null
- || res.getReturnType().isAssignableFrom(m.getReturnType())))
- res = m;
- }
-
- return (res == null ? res : getReflectionFactory().copyMethod(res));
- }
-
-
- private Method getMethod0(String name, Class<?>[] parameterTypes, boolean includeStaticMethods) {
- // Note: the intent is that the search algorithm this routine
- // uses be equivalent to the ordering imposed by
- // privateGetPublicMethods(). It fetches only the declared
- // public methods for each class, however, to reduce the
- // number of Method objects which have to be created for the
- // common case where the method being requested is declared in
- // the class which is being queried.
- Method res;
- // Search declared public methods
- if ((res = searchMethods(privateGetDeclaredMethods(true),
- name,
- parameterTypes)) != null) {
- if (includeStaticMethods || !Modifier.isStatic(res.getModifiers()))
- return res;
- }
- // Search superclass's methods
- if (!isInterface()) {
- Class<? super T> c = getSuperclass();
- if (c != null) {
- if ((res = c.getMethod0(name, parameterTypes, true)) != null) {
- return res;
- }
- }
- }
- // Search superinterfaces' methods
- Class<?>[] interfaces = getInterfaces();
- for (Class<?> c : interfaces)
- if ((res = c.getMethod0(name, parameterTypes, false)) != null)
- return res;
- // Not found
- return null;
- }
-
- private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
- int which) throws NoSuchMethodException
- {
- Constructor<T>[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
- for (Constructor<T> constructor : constructors) {
- if (arrayContentsEq(parameterTypes,
- constructor.getParameterTypes())) {
- return getReflectionFactory().copyConstructor(constructor);
- }
- }
- throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
- }
-
- //
- // Other helpers and base implementation
- //
-
- private static boolean arrayContentsEq(Object[] a1, Object[] a2) {
- if (a1 == null) {
- return a2 == null || a2.length == 0;
- }
-
- if (a2 == null) {
- return a1.length == 0;
- }
-
- if (a1.length != a2.length) {
- return false;
- }
-
- for (int i = 0; i < a1.length; i++) {
- if (a1[i] != a2[i]) {
- return false;
- }
- }
-
- return true;
- }
-
- private static Field[] copyFields(Field[] arg) {
- Field[] out = new Field[arg.length];
- ReflectionFactory fact = getReflectionFactory();
- for (int i = 0; i < arg.length; i++) {
- out[i] = fact.copyField(arg[i]);
- }
- return out;
- }
-
- private static Method[] copyMethods(Method[] arg) {
- Method[] out = new Method[arg.length];
- ReflectionFactory fact = getReflectionFactory();
- for (int i = 0; i < arg.length; i++) {
- out[i] = fact.copyMethod(arg[i]);
- }
- return out;
- }
-
- private static <U> Constructor<U>[] copyConstructors(Constructor<U>[] arg) {
- Constructor<U>[] out = arg.clone();
- ReflectionFactory fact = getReflectionFactory();
- for (int i = 0; i < out.length; i++) {
- out[i] = fact.copyConstructor(out[i]);
- }
- return out;
- }
-
- private native Field[] getDeclaredFields0(boolean publicOnly);
- private native Method[] getDeclaredMethods0(boolean publicOnly);
- private native Constructor<T>[] getDeclaredConstructors0(boolean publicOnly);
- private native Class<?>[] getDeclaredClasses0();
-
- private static String argumentTypesToString(Class<?>[] argTypes) {
- StringBuilder buf = new StringBuilder();
- buf.append("(");
- if (argTypes != null) {
- for (int i = 0; i < argTypes.length; i++) {
- if (i > 0) {
- buf.append(", ");
- }
- Class<?> c = argTypes[i];
- buf.append((c == null) ? "null" : c.getName());
- }
- }
- buf.append(")");
- return buf.toString();
- }
-
- /** use serialVersionUID from JDK 1.1 for interoperability */
- private static final long serialVersionUID = 3206093459760846163L;
-
-
- /**
- * Class Class is special cased within the Serialization Stream Protocol.
- *
- * A Class instance is written initially into an ObjectOutputStream in the
- * following format:
- * <pre>
- * {@code TC_CLASS} ClassDescriptor
- * A ClassDescriptor is a special cased serialization of
- * a {@code java.io.ObjectStreamClass} instance.
- * </pre>
- * A new handle is generated for the initial time the class descriptor
- * is written into the stream. Future references to the class descriptor
- * are written as references to the initial class descriptor instance.
- *
- * @see java.io.ObjectStreamClass
- */
-
- @ikvm.lang.Property(get="get_spf")
- private static final ObjectStreamField[] serialPersistentFields = null;
-
- private static ObjectStreamField[] get_spf() {
- return java.io.ObjectStreamClass.NO_FIELDS;
- }
-
-
- /**
- * Returns the assertion status that would be assigned to this
- * class if it were to be initialized at the time this method is invoked.
- * If this class has had its assertion status set, the most recent
- * setting will be returned; otherwise, if any package default assertion
- * status pertains to this class, the most recent setting for the most
- * specific pertinent package default assertion status is returned;
- * otherwise, if this class is not a system class (i.e., it has a
- * class loader) its class loader's default assertion status is returned;
- * otherwise, the system class default assertion status is returned.
- * <p>
- * Few programmers will have any need for this method; it is provided
- * for the benefit of the JRE itself. (It allows a class to determine at
- * the time that it is initialized whether assertions should be enabled.)
- * Note that this method is not guaranteed to return the actual
- * assertion status that was (or will be) associated with the specified
- * class when it was (or will be) initialized.
- *
- * @return the desired assertion status of the specified class.
- * @see java.lang.ClassLoader#setClassAssertionStatus
- * @see java.lang.ClassLoader#setPackageAssertionStatus
- * @see java.lang.ClassLoader#setDefaultAssertionStatus
- * @since 1.4
- */
- public boolean desiredAssertionStatus() {
- ClassLoader loader = getClassLoader();
- // If the loader is null this is a system class, so ask the VM
- if (loader == null)
- return desiredAssertionStatus0(this);
-
- // If the classloader has been initialized with the assertion
- // directives, ask it. Otherwise, ask the VM.
- synchronized(loader.assertionLock) {
- if (loader.classAssertionStatus != null) {
- return loader.desiredAssertionStatus(getName());
- }
- }
- return desiredAssertionStatus0(this);
- }
-
- // Retrieves the desired assertion status of this class from the VM
- private static native boolean desiredAssertionStatus0(Class<?> clazz);
-
- /**
- * Returns true if and only if this class was declared as an enum in the
- * source code.
- *
- * @return true if and only if this class was declared as an enum in the
- * source code
- * @since 1.5
- */
- public boolean isEnum() {
- // An enum must both directly extend java.lang.Enum and have
- // the ENUM bit set; classes for specialized enum constants
- // don't do the former.
- return (this.getModifiers() & ENUM) != 0 &&
- this.getSuperclass() == java.lang.Enum.class;
- }
-
- // Fetches the factory for reflective objects
- private static ReflectionFactory getReflectionFactory() {
- if (reflectionFactory == null) {
- reflectionFactory =
- java.security.AccessController.doPrivileged
- (new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());
- }
- return reflectionFactory;
- }
- private static ReflectionFactory reflectionFactory;
-
- // To be able to query system properties as soon as they're available
- private static boolean initted;
- private static void checkInitted() {
- if (initted) return;
- useCaches = true;
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- // Tests to ensure the system properties table is fully
- // initialized. This is needed because reflection code is
- // called very early in the initialization process (before
- // command-line arguments have been parsed and therefore
- // these user-settable properties installed.)
-
- if (!sun.misc.VM.isBooted()) {
- return null;
- }
-
- // Doesn't use Boolean.getBoolean to avoid class init.
- String val =
- System.getProperty("sun.reflect.noCaches");
- if (val != null && val.equals("true")) {
- useCaches = false;
- }
-
- initted = true;
- return null;
- }
- });
- }
-
- /**
- * Returns the elements of this enum class or null if this
- * Class object does not represent an enum type.
- *
- * @return an array containing the values comprising the enum class
- * represented by this Class object in the order they're
- * declared, or null if this Class object does not
- * represent an enum type
- * @since 1.5
- */
- public T[] getEnumConstants() {
- T[] values = getEnumConstantsShared();
- return (values != null) ? values.clone() : null;
- }
-
- /**
- * Returns the elements of this enum class or null if this
- * Class object does not represent an enum type;
- * identical to getEnumConstants except that the result is
- * uncloned, cached, and shared by all callers.
- */
- T[] getEnumConstantsShared() {
- if (enumConstants == null) {
- if (!isEnum()) return null;
- try {
- final Method values = getMethod("values");
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- values.setAccessible(true);
- return null;
- }
- });
- @SuppressWarnings("unchecked")
- T[] temporaryConstants = (T[])values.invoke(null);
- enumConstants = temporaryConstants;
- }
- // These can happen when users concoct enum-like classes
- // that don't comply with the enum spec.
- catch (InvocationTargetException | NoSuchMethodException |
- IllegalAccessException ex) { return null; }
- }
- return enumConstants;
- }
- private volatile transient T[] enumConstants;
-
- /**
- * Returns a map from simple name to enum constant. This package-private
- * method is used internally by Enum to implement
- * {@code public static <T extends Enum<T>> T valueOf(Class<T>, String)}
- * efficiently. Note that the map is returned by this method is
- * created lazily on first use. Typically it won't ever get created.
- */
- Map<String, T> enumConstantDirectory() {
- if (enumConstantDirectory == null) {
- T[] universe = getEnumConstantsShared();
- if (universe == null)
- throw new IllegalArgumentException(
- getName() + " is not an enum type");
- Map<String, T> m = new HashMap<>(2 * universe.length);
- for (T constant : universe)
- m.put(((Enum<?>)constant).name(), constant);
- enumConstantDirectory = m;
- }
- return enumConstantDirectory;
- }
- private volatile transient Map<String, T> enumConstantDirectory;
-
- /**
- * Casts an object to the class or interface represented
- * by this {@code Class} object.
- *
- * @param obj the object to be cast
- * @return the object after casting, or null if obj is null
- *
- * @throws ClassCastException if the object is not
- * null and is not assignable to the type T.
- *
- * @since 1.5
- */
- @SuppressWarnings("unchecked")
- public T cast(Object obj) {
- if (obj != null && !isInstance(obj))
- throw new ClassCastException(cannotCastMsg(obj));
- return (T) obj;
- }
-
- private String cannotCastMsg(Object obj) {
- return "Cannot cast " + obj.getClass().getName() + " to " + getName();
- }
-
- /**
- * Casts this {@code Class} object to represent a subclass of the class
- * represented by the specified class object. Checks that the cast
- * is valid, and throws a {@code ClassCastException} if it is not. If
- * this method succeeds, it always returns a reference to this class object.
- *
- * <p>This method is useful when a client needs to "narrow" the type of
- * a {@code Class} object to pass it to an API that restricts the
- * {@code Class} objects that it is willing to accept. A cast would
- * generate a compile-time warning, as the correctness of the cast
- * could not be checked at runtime (because generic types are implemented
- * by erasure).
- *
- * @param <U> the type to cast this class object to
- * @param clazz the class of the type to cast this class object to
- * @return this {@code Class} object, cast to represent a subclass of
- * the specified class object.
- * @throws ClassCastException if this {@code Class} object does not
- * represent a subclass of the specified class (here "subclass" includes
- * the class itself).
- * @since 1.5
- */
- @SuppressWarnings("unchecked")
- public <U> Class<? extends U> asSubclass(Class<U> clazz) {
- if (clazz.isAssignableFrom(this))
- return (Class<? extends U>) this;
- else
- throw new ClassCastException(this.toString());
- }
-
- /**
- * @throws NullPointerException {@inheritDoc}
- * @since 1.5
- */
- @SuppressWarnings("unchecked")
- public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
- Objects.requireNonNull(annotationClass);
-
- return (A) annotationData().annotations.get(annotationClass);
- }
-
- /**
- * {@inheritDoc}
- * @throws NullPointerException {@inheritDoc}
- * @since 1.5
- */
- @Override
- public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
- return GenericDeclaration.super.isAnnotationPresent(annotationClass);
- }
-
- /**
- * @throws NullPointerException {@inheritDoc}
- * @since 1.8
- */
- @Override
- public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
- Objects.requireNonNull(annotationClass);
-
- AnnotationData annotationData = annotationData();
- return AnnotationSupport.getAssociatedAnnotations(annotationData.declaredAnnotations,
- this,
- annotationClass);
- }
-
- /**
- * @since 1.5
- */
- public Annotation[] getAnnotations() {
- return AnnotationParser.toArray(annotationData().annotations);
- }
-
- /**
- * @throws NullPointerException {@inheritDoc}
- * @since 1.8
- */
- @Override
- @SuppressWarnings("unchecked")
- public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) {
- Objects.requireNonNull(annotationClass);
-
- return (A) annotationData().declaredAnnotations.get(annotationClass);
- }
-
- /**
- * @throws NullPointerException {@inheritDoc}
- * @since 1.8
- */
- @Override
- public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationClass) {
- Objects.requireNonNull(annotationClass);
-
- return AnnotationSupport.getDirectlyAndIndirectlyPresent(annotationData().declaredAnnotations,
- annotationClass);
- }
-
- /**
- * @since 1.5
- */
- public Annotation[] getDeclaredAnnotations() {
- return AnnotationParser.toArray(annotationData().declaredAnnotations);
- }
-
- // annotation data that might get invalidated when JVM TI RedefineClasses() is called
- private static class AnnotationData {
- final Map<Class<? extends Annotation>, Annotation> annotations;
- final Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
-
- // Value of classRedefinedCount when we created this AnnotationData instance
- final int redefinedCount;
-
- AnnotationData(Map<Class<? extends Annotation>, Annotation> annotations,
- Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
- int redefinedCount) {
- this.annotations = annotations;
- this.declaredAnnotations = declaredAnnotations;
- this.redefinedCount = redefinedCount;
- }
- }
-
- // Annotations cache
- @SuppressWarnings("UnusedDeclaration")
- private volatile transient AnnotationData annotationData;
-
- private AnnotationData annotationData() {
- while (true) { // retry loop
- AnnotationData annotationData = this.annotationData;
- int classRedefinedCount = this.classRedefinedCount;
- if (annotationData != null &&
- annotationData.redefinedCount == classRedefinedCount) {
- return annotationData;
- }
- // null or stale annotationData -> optimistically create new instance
- AnnotationData newAnnotationData = createAnnotationData(classRedefinedCount);
- // try to install it
- if (Atomic.casAnnotationData(this, annotationData, newAnnotationData)) {
- // successfully installed new AnnotationData
- return newAnnotationData;
- }
- }
- }
-
- private AnnotationData createAnnotationData(int classRedefinedCount) {
- Map<Class<? extends Annotation>, Annotation> declaredAnnotations =
- getDeclaredAnnotationsImpl();
- Class<?> superClass = getSuperclass();
- Map<Class<? extends Annotation>, Annotation> annotations = null;
- if (superClass != null) {
- Map<Class<? extends Annotation>, Annotation> superAnnotations =
- superClass.annotationData().annotations;
- for (Map.Entry<Class<? extends Annotation>, Annotation> e : superAnnotations.entrySet()) {
- Class<? extends Annotation> annotationClass = e.getKey();
- if (AnnotationType.getInstance(annotationClass).isInherited()) {
- if (annotations == null) { // lazy construction
- annotations = new LinkedHashMap<>((Math.max(
- declaredAnnotations.size(),
- Math.min(12, declaredAnnotations.size() + superAnnotations.size())
- ) * 4 + 2) / 3
- );
- }
- annotations.put(annotationClass, e.getValue());
- }
- }
- }
- if (annotations == null) {
- // no inherited annotations -> share the Map with declaredAnnotations
- annotations = declaredAnnotations;
- } else {
- // at least one inherited annotation -> declared may override inherited
- annotations.putAll(declaredAnnotations);
- }
- return new AnnotationData(annotations, declaredAnnotations, classRedefinedCount);
- }
-
- // Annotation types cache their internal (AnnotationType) form
-
- @SuppressWarnings("UnusedDeclaration")
- private volatile transient AnnotationType annotationType;
-
- boolean casAnnotationType(AnnotationType oldType, AnnotationType newType) {
- return Atomic.casAnnotationType(this, oldType, newType);
- }
-
- AnnotationType getAnnotationType() {
- return annotationType;
- }
-
- Map<Class<? extends Annotation>, Annotation> getDeclaredAnnotationMap() {
- return annotationData().declaredAnnotations;
- }
-
- /* Backing store of user-defined values pertaining to this class.
- * Maintained by the ClassValue class.
- */
- transient ClassValue.ClassValueMap classValueMap;
-
- /**
- * Returns an {@code AnnotatedType} object that represents the use of a
- * type to specify the superclass of the entity represented by this {@code
- * Class} object. (The <em>use</em> of type Foo to specify the superclass
- * in '... extends Foo' is distinct from the <em>declaration</em> of type
- * Foo.)
- *
- * <p> If this {@code Class} object represents a type whose declaration
- * does not explicitly indicate an annotated superclass, then the return
- * value is an {@code AnnotatedType} object representing an element with no
- * annotations.
- *
- * <p> If this {@code Class} represents either the {@code Object} class, an
- * interface type, an array type, a primitive type, or void, the return
- * value is {@code null}.
- *
- * @return an object representing the superclass
- * @since 1.8
- */
- public AnnotatedType getAnnotatedSuperclass() {
- if (this == Object.class ||
- isInterface() ||
- isArray() ||
- isPrimitive() ||
- this == Void.TYPE) {
- return null;
- }
-
- return TypeAnnotationParser.buildAnnotatedSuperclass(getRawTypeAnnotations(), getConstantPool(), this);
- }
-
- /**
- * Returns an array of {@code AnnotatedType} objects that represent the use
- * of types to specify superinterfaces of the entity represented by this
- * {@code Class} object. (The <em>use</em> of type Foo to specify a
- * superinterface in '... implements Foo' is distinct from the
- * <em>declaration</em> of type Foo.)
- *
- * <p> If this {@code Class} object represents a class, the return value is
- * an array containing objects representing the uses of interface types to
- * specify interfaces implemented by the class. The order of the objects in
- * the array corresponds to the order of the interface types used in the
- * 'implements' clause of the declaration of this {@code Class} object.
- *
- * <p> If this {@code Class} object represents an interface, the return
- * value is an array containing objects representing the uses of interface
- * types to specify interfaces directly extended by the interface. The
- * order of the objects in the array corresponds to the order of the
- * interface types used in the 'extends' clause of the declaration of this
- * {@code Class} object.
- *
- * <p> If this {@code Class} object represents a class or interface whose
- * declaration does not explicitly indicate any annotated superinterfaces,
- * the return value is an array of length 0.
- *
- * <p> If this {@code Class} object represents either the {@code Object}
- * class, an array type, a primitive type, or void, the return value is an
- * array of length 0.
- *
- * @return an array representing the superinterfaces
- * @since 1.8
- */
- public AnnotatedType[] getAnnotatedInterfaces() {
- return TypeAnnotationParser.buildAnnotatedInterfaces(getRawTypeAnnotations(), getConstantPool(), this);
- }
-}
diff --git a/openjdk/java/lang/ClassLoader.java b/openjdk/java/lang/ClassLoader.java
deleted file mode 100644
index 57c1ee3e..00000000
--- a/openjdk/java/lang/ClassLoader.java
+++ /dev/null
@@ -1,2261 +0,0 @@
-/*
- * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.lang;
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.File;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.security.AccessController;
-import java.security.AccessControlContext;
-import java.security.CodeSource;
-import java.security.Policy;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.security.ProtectionDomain;
-import java.security.cert.Certificate;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Stack;
-import java.util.Map;
-import java.util.Vector;
-import java.util.Hashtable;
-import java.util.WeakHashMap;
-import java.util.concurrent.ConcurrentHashMap;
-import sun.misc.ClassFileTransformer;
-import sun.misc.CompoundEnumeration;
-import sun.misc.Resource;
-import sun.misc.URLClassPath;
-import sun.misc.VM;
-import sun.reflect.CallerSensitive;
-import sun.reflect.Reflection;
-import sun.security.util.SecurityConstants;
-
-/**
- * A class loader is an object that is responsible for loading classes. The
- * class <tt>ClassLoader</tt> is an abstract class. Given the <a
- * href="#name">binary name</a> of a class, a class loader should attempt to
- * locate or generate data that constitutes a definition for the class. A
- * typical strategy is to transform the name into a file name and then read a
- * "class file" of that name from a file system.
- *
- * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
- * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
- * it.
- *
- * <p> <tt>Class</tt> objects for array classes are not created by class
- * loaders, but are created automatically as required by the Java runtime.
- * The class loader for an array class, as returned by {@link
- * Class#getClassLoader()} is the same as the class loader for its element
- * type; if the element type is a primitive type, then the array class has no
- * class loader.
- *
- * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to
- * extend the manner in which the Java virtual machine dynamically loads
- * classes.
- *
- * <p> Class loaders may typically be used by security managers to indicate
- * security domains.
- *
- * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for
- * classes and resources. Each instance of <tt>ClassLoader</tt> has an
- * associated parent class loader. When requested to find a class or
- * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
- * class or resource to its parent class loader before attempting to find the
- * class or resource itself. The virtual machine's built-in class loader,
- * called the "bootstrap class loader", does not itself have a parent but may
- * serve as the parent of a <tt>ClassLoader</tt> instance.
- *
- * <p> Class loaders that support concurrent loading of classes are known as
- * <em>parallel capable</em> class loaders and are required to register
- * themselves at their class initialization time by invoking the
- * {@link
- * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>}
- * method. Note that the <tt>ClassLoader</tt> class is registered as parallel
- * capable by default. However, its subclasses still need to register themselves
- * if they are parallel capable. <br>
- * In environments in which the delegation model is not strictly
- * hierarchical, class loaders need to be parallel capable, otherwise class
- * loading can lead to deadlocks because the loader lock is held for the
- * duration of the class loading process (see {@link #loadClass
- * <tt>loadClass</tt>} methods).
- *
- * <p> Normally, the Java virtual machine loads classes from the local file
- * system in a platform-dependent manner. For example, on UNIX systems, the
- * virtual machine loads classes from the directory defined by the
- * <tt>CLASSPATH</tt> environment variable.
- *
- * <p> However, some classes may not originate from a file; they may originate
- * from other sources, such as the network, or they could be constructed by an
- * application. The method {@link #defineClass(String, byte[], int, int)
- * <tt>defineClass</tt>} converts an array of bytes into an instance of class
- * <tt>Class</tt>. Instances of this newly defined class can be created using
- * {@link Class#newInstance <tt>Class.newInstance</tt>}.
- *
- * <p> The methods and constructors of objects created by a class loader may
- * reference other classes. To determine the class(es) referred to, the Java
- * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
- * the class loader that originally created the class.
- *
- * <p> For example, an application could create a network class loader to
- * download class files from a server. Sample code might look like:
- *
- * <blockquote><pre>
- * ClassLoader loader&nbsp;= new NetworkClassLoader(host,&nbsp;port);
- * Object main&nbsp;= loader.loadClass("Main", true).newInstance();
- * &nbsp;.&nbsp;.&nbsp;.
- * </pre></blockquote>
- *
- * <p> The network class loader subclass must define the methods {@link
- * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class
- * from the network. Once it has downloaded the bytes that make up the class,
- * it should use the method {@link #defineClass <tt>defineClass</tt>} to
- * create a class instance. A sample implementation is:
- *
- * <blockquote><pre>
- * class NetworkClassLoader extends ClassLoader {
- * String host;
- * int port;
- *
- * public Class findClass(String name) {
- * byte[] b = loadClassData(name);
- * return defineClass(name, b, 0, b.length);
- * }
- *
- * private byte[] loadClassData(String name) {
- * // load the class data from the connection
- * &nbsp;.&nbsp;.&nbsp;.
- * }
- * }
- * </pre></blockquote>
- *
- * <h4> <a name="name">Binary names</a> </h4>
- *
- * <p> Any class name provided as a {@link String} parameter to methods in
- * <tt>ClassLoader</tt> must be a binary name as defined by
- * <cite>The Java&trade; Language Specification</cite>.
- *
- * <p> Examples of valid class names include:
- * <blockquote><pre>
- * "java.lang.String"
- * "javax.swing.JSpinner$DefaultEditor"
- * "java.security.KeyStore$Builder$FileBuilder$1"
- * "java.net.URLClassLoader$3$1"
- * </pre></blockquote>
- *
- * @see #resolveClass(Class)
- * @since 1.0
- */
-public abstract class ClassLoader {
-
- // If initialization succeed this is set to true and security checks will
- // succeed. Otherwise the object is not initialized and the object is
- // useless.
- private final boolean initialized;
-
- // The parent class loader for delegation
- // Note: VM hardcoded the offset of this field, thus all new fields
- // must be added *after* it.
- private final ClassLoader parent;
-
- /**
- * Encapsulates the set of parallel capable loader types.
- */
- private static class ParallelLoaders {
- private ParallelLoaders() {}
-
- // the set of parallel capable loader types
- private static final Set<Class<? extends ClassLoader>> loaderTypes =
- Collections.newSetFromMap(
- new WeakHashMap<Class<? extends ClassLoader>, Boolean>());
- static {
- synchronized (loaderTypes) { loaderTypes.add(ClassLoader.class); }
- }
-
- /**
- * Registers the given class loader type as parallel capabale.
- * Returns {@code true} is successfully registered; {@code false} if
- * loader's super class is not registered.
- */
- static boolean register(Class<? extends ClassLoader> c) {
- synchronized (loaderTypes) {
- if (loaderTypes.contains(c.getSuperclass())) {
- // register the class loader as parallel capable
- // if and only if all of its super classes are.
- // Note: given current classloading sequence, if
- // the immediate super class is parallel capable,
- // all the super classes higher up must be too.
- loaderTypes.add(c);
- return true;
- } else {
- return false;
- }
- }
- }
-
- /**
- * Returns {@code true} if the given class loader type is
- * registered as parallel capable.
- */
- static boolean isRegistered(Class<? extends ClassLoader> c) {
- synchronized (loaderTypes) {
- return loaderTypes.contains(c);
- }
- }
- }
-
- // Maps class name to the corresponding lock object when the current
- // class loader is parallel capable.
- // Note: VM also uses this field to decide if the current class loader
- // is parallel capable and the appropriate lock object for class loading.
- private final ConcurrentHashMap<String, Object> parallelLockMap;
-
- // Hashtable that maps packages to certs
- private final Map <String, Certificate[]> package2certs;
-
- // Shared among all packages with unsigned classes
- private static final Certificate[] nocerts = new Certificate[0];
-
- // The classes loaded by this class loader. The only purpose of this table
- // is to keep the classes from being GC'ed until the loader is GC'ed.
- private final Vector<Class<?>> classes = new Vector<>();
-
- // The "default" domain. Set as the default ProtectionDomain on newly
- // created classes.
- private final ProtectionDomain defaultDomain =
- new ProtectionDomain(new CodeSource(null, (Certificate[]) null),
- null, this, null);
-
- // The initiating protection domains for all classes loaded by this loader
- private final Set<ProtectionDomain> domains;
-
- // Invoked by the VM to record every loaded class with this loader.
- void addClass(Class c) {
- classes.addElement(c);
- }
-
- // The packages defined in this class loader. Each package name is mapped
- // to its corresponding Package object.
- // @GuardedBy("itself")
- private final HashMap<String, Package> packages = new HashMap<>();
-
- @ikvm.lang.Internal
- public static final ClassLoader DUMMY = new ClassLoader(false) { };
-
- ClassLoader(boolean ignored)
- {
- // [IKVM] This constructor is IKVM specific and only used to construct DUMMY.
- // Note that this body is replaced in map.xml with an empty body as
- // we don't want to execute any of the instance field initializers.
- this((Void)null, (ClassLoader)null);
- }
-
- private static Void checkCreateClassLoader() {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkCreateClassLoader();
- }
- return null;
- }
-
- // [IKVM] this normally private constructor is also used by ikvm.runtime.AssemblyClassLoader
- // to construct an assembly class loader without doing a security check
- @ikvm.lang.Internal
- protected ClassLoader(Void unused, ClassLoader parent) {
- if (parent != null) {
- parent.check();
- }
- this.parent = parent;
- if (ParallelLoaders.isRegistered(this.getClass())) {
- parallelLockMap = new ConcurrentHashMap<>();
- package2certs = new ConcurrentHashMap<>();
- domains =
- Collections.synchronizedSet(new HashSet<ProtectionDomain>());
- assertionLock = new Object();
- } else {
- // no finer-grained lock; lock on the classloader instance
- parallelLockMap = null;
- package2certs = new Hashtable<>();
- domains = new HashSet<>();
- assertionLock = this;
- }
- initialized = true;
- }
-
- /**
- * Creates a new class loader using the specified parent class loader for
- * delegation.
- *
- * <p> If there is a security manager, its {@link
- * SecurityManager#checkCreateClassLoader()
- * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
- * a security exception. </p>
- *
- * @param parent
- * The parent class loader
- *
- * @throws SecurityException
- * If a security manager exists and its
- * <tt>checkCreateClassLoader</tt> method doesn't allow creation
- * of a new class loader.
- *
- * @since 1.2
- */
- protected ClassLoader(ClassLoader parent) {
- this(checkCreateClassLoader(), parent);
- }
-
- /**
- * Creates a new class loader using the <tt>ClassLoader</tt> returned by
- * the method {@link #getSystemClassLoader()
- * <tt>getSystemClassLoader()</tt>} as the parent class loader.
- *
- * <p> If there is a security manager, its {@link
- * SecurityManager#checkCreateClassLoader()
- * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
- * a security exception. </p>
- *
- * @throws SecurityException
- * If a security manager exists and its
- * <tt>checkCreateClassLoader</tt> method doesn't allow creation
- * of a new class loader.
- */
- protected ClassLoader() {
- this(checkCreateClassLoader(), getSystemClassLoader());
- }
-
- // -- Class --
-
- /**
- * Loads the class with the specified <a href="#name">binary name</a>.
- * This method searches for classes in the same manner as the {@link
- * #loadClass(String, boolean)} method. It is invoked by the Java virtual
- * machine to resolve class references. Invoking this method is equivalent
- * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
- * false)</tt>}. </p>
- *
- * @param name
- * The <a href="#name">binary name</a> of the class
- *
- * @return The resulting <tt>Class</tt> object
- *
- * @throws ClassNotFoundException
- * If the class was not found
- */
- public Class<?> loadClass(String name) throws ClassNotFoundException {
- return loadClass(name, false);
- }
-
- /**
- * Loads the class with the specified <a href="#name">binary name</a>. The
- * default implementation of this method searches for classes in the
- * following order:
- *
- * <p><ol>
- *
- * <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
- * has already been loaded. </p></li>
- *
- * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
- * on the parent class loader. If the parent is <tt>null</tt> the class
- * loader built-in to the virtual machine is used, instead. </p></li>
- *
- * <li><p> Invoke the {@link #findClass(String)} method to find the
- * class. </p></li>
- *
- * </ol>
- *
- * <p> If the class was found using the above steps, and the
- * <tt>resolve</tt> flag is true, this method will then invoke the {@link
- * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
- *
- * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
- * #findClass(String)}, rather than this method. </p>
- *
- * <p> Unless overridden, this method synchronizes on the result of
- * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
- * during the entire class loading process.
- *
- * @param name
- * The <a href="#name">binary name</a> of the class
- *
- * @param resolve
- * If <tt>true</tt> then resolve the class
- *
- * @return The resulting <tt>Class</tt> object
- *
- * @throws ClassNotFoundException
- * If the class could not be found
- */
- protected Class<?> loadClass(String name, boolean resolve)
- throws ClassNotFoundException
- {
- synchronized (getClassLoadingLock(name)) {
- // First, check if the class has already been loaded
- Class c = findLoadedClass(name);
- if (c == null) {
- try {
- if (parent != null) {
- c = parent.loadClass(name, false);
- } else {
- c = findBootstrapClassOrNull(name);
- }
- } catch (ClassNotFoundException e) {
- // ClassNotFoundException thrown if class not found
- // from the non-null parent class loader
- }
-
- if (c == null) {
- // If still not found, then invoke findClass in order
- // to find the class.
- c = findClass(name);
- }
- }
- if (resolve) {
- resolveClass(c);
- }
- return c;
- }
- }
-
- /**
- * Returns the lock object for class loading operations.
- * For backward compatibility, the default implementation of this method
- * behaves as follows. If this ClassLoader object is registered as
- * parallel capable, the method returns a dedicated object associated
- * with the specified class name. Otherwise, the method returns this
- * ClassLoader object. </p>
- *
- * @param className
- * The name of the to-be-loaded class
- *
- * @return the lock for class loading operations
- *
- * @throws NullPointerException
- * If registered as parallel capable and <tt>className</tt> is null
- *
- * @see #loadClass(String, boolean)
- *
- * @since 1.7
- */
- protected Object getClassLoadingLock(String className) {
- Object lock = this;
- if (parallelLockMap != null) {
- Object newLock = new Object();
- lock = parallelLockMap.putIfAbsent(className, newLock);
- if (lock == null) {
- lock = newLock;
- }
- }
- return lock;
- }
-
- // This method is invoked by the virtual machine to load a class.
- final Class loadClassInternal(String name)
- throws ClassNotFoundException
- {
- // For backward compatibility, explicitly lock on 'this' when
- // the current class loader is not parallel capable.
- if (parallelLockMap == null) {
- synchronized (this) {
- return loadClass(name);
- }
- } else {
- return loadClass(name);
- }
- }
-
- // Invoked by the VM after loading class with this loader.
- final void checkPackageAccess(Class cls, ProtectionDomain pd) {
- final SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- final String name = cls.getName();
- final int i = name.lastIndexOf('.');
- if (i != -1) {
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- sm.checkPackageAccess(name.substring(0, i));
- return null;
- }
- }, new AccessControlContext(new ProtectionDomain[] {pd}));
- }
- }
- domains.add(pd);
- }
-
- /**
- * Finds the class with the specified <a href="#name">binary name</a>.
- * This method should be overridden by class loader implementations that
- * follow the delegation model for loading classes, and will be invoked by
- * the {@link #loadClass <tt>loadClass</tt>} method after checking the
- * parent class loader for the requested class. The default implementation
- * throws a <tt>ClassNotFoundException</tt>. </p>
- *
- * @param name
- * The <a href="#name">binary name</a> of the class
- *
- * @return The resulting <tt>Class</tt> object
- *
- * @throws ClassNotFoundException
- * If the class could not be found
- *
- * @since 1.2
- */
- protected Class<?> findClass(String name) throws ClassNotFoundException {
- throw new ClassNotFoundException(name);
- }
-
- /**
- * Converts an array of bytes into an instance of class <tt>Class</tt>.
- * Before the <tt>Class</tt> can be used it must be resolved. This method
- * is deprecated in favor of the version that takes a <a
- * href="#name">binary name</a> as its first argument, and is more secure.
- *
- * @param b
- * The bytes that make up the class data. The bytes in positions
- * <tt>off</tt> through <tt>off+len-1</tt> should have the format
- * of a valid class file as defined by
- * <cite>The Java&trade; Virtual Machine Specification</cite>.
- *
- * @param off
- * The start offset in <tt>b</tt> of the class data
- *
- * @param len
- * The length of the class data
- *
- * @return The <tt>Class</tt> object that was created from the specified
- * class data
- *
- * @throws ClassFormatError
- * If the data did not contain a valid class
- *
- * @throws IndexOutOfBoundsException
- * If either <tt>off</tt> or <tt>len</tt> is negative, or if
- * <tt>off+len</tt> is greater than <tt>b.length</tt>.
- *
- * @throws SecurityException
- * If an attempt is made to add this class to a package that
- * contains classes that were signed by a different set of
- * certificates than this class, or if an attempt is made
- * to define a class in a package with a fully-qualified name
- * that starts with "{@code java.}".
- *
- * @see #loadClass(String, boolean)
- * @see #resolveClass(Class)
- *
- * @deprecated Replaced by {@link #defineClass(String, byte[], int, int)
- * defineClass(String, byte[], int, int)}
- */
- @Deprecated
- protected final Class<?> defineClass(byte[] b, int off, int len)
- throws ClassFormatError
- {
- return defineClass(null, b, off, len, null);
- }
-
- /**
- * Converts an array of bytes into an instance of class <tt>Class</tt>.
- * Before the <tt>Class</tt> can be used it must be resolved.
- *
- * <p> This method assigns a default {@link java.security.ProtectionDomain
- * <tt>ProtectionDomain</tt>} to the newly defined class. The
- * <tt>ProtectionDomain</tt> is effectively granted the same set of
- * permissions returned when {@link
- * java.security.Policy#getPermissions(java.security.CodeSource)
- * <tt>Policy.getPolicy().getPermissions(new CodeSource(null, null))</tt>}
- * is invoked. The default domain is created on the first invocation of
- * {@link #defineClass(String, byte[], int, int) <tt>defineClass</tt>},
- * and re-used on subsequent invocations.
- *
- * <p> To assign a specific <tt>ProtectionDomain</tt> to the class, use
- * the {@link #defineClass(String, byte[], int, int,
- * java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a
- * <tt>ProtectionDomain</tt> as one of its arguments. </p>
- *
- * @param name
- * The expected <a href="#name">binary name</a> of the class, or
- * <tt>null</tt> if not known
- *
- * @param b
- * The bytes that make up the class data. The bytes in positions
- * <tt>off</tt> through <tt>off+len-1</tt> should have the format
- * of a valid class file as defined by
- * <cite>The Java&trade; Virtual Machine Specification</cite>.
- *
- * @param off
- * The start offset in <tt>b</tt> of the class data
- *
- * @param len
- * The length of the class data
- *
- * @return The <tt>Class</tt> object that was created from the specified
- * class data.
- *
- * @throws ClassFormatError
- * If the data did not contain a valid class
- *
- * @throws IndexOutOfBoundsException
- * If either <tt>off</tt> or <tt>len</tt> is negative, or if
- * <tt>off+len</tt> is greater than <tt>b.length</tt>.
- *
- * @throws SecurityException
- * If an attempt is made to add this class to a package that
- * contains classes that were signed by a different set of
- * certificates than this class (which is unsigned), or if
- * <tt>name</tt> begins with "<tt>java.</tt>".
- *
- * @see #loadClass(String, boolean)
- * @see #resolveClass(Class)
- * @see java.security.CodeSource
- * @see java.security.SecureClassLoader
- *
- * @since 1.1
- */
- protected final Class<?> defineClass(String name, byte[] b, int off, int len)
- throws ClassFormatError
- {
- return defineClass(name, b, off, len, null);
- }
-
- /* Determine protection domain, and check that:
- - not define java.* class,
- - signer of this class matches signers for the rest of the classes in
- package.
- */
- private ProtectionDomain preDefineClass(String name,
- ProtectionDomain pd)
- {
- if (!checkName(name))
- throw new NoClassDefFoundError("IllegalName: " + name);
-
- if ((name != null) && name.startsWith("java.")) {
- throw new SecurityException
- ("Prohibited package name: " +
- name.substring(0, name.lastIndexOf('.')));
- }
- if (pd == null) {
- pd = defaultDomain;
- }
-
- if (name != null) checkCerts(name, pd.getCodeSource());
-
- return pd;
- }
-
- private String defineClassSourceLocation(ProtectionDomain pd)
- {
- CodeSource cs = pd.getCodeSource();
- String source = null;
- if (cs != null && cs.getLocation() != null) {
- source = cs.getLocation().toString();
- }
- return source;
- }
-
- private Class defineTransformedClass(String name, byte[] b, int off, int len,
- ProtectionDomain pd,
- ClassFormatError cfe, String source)
- throws ClassFormatError
- {
- // Class format error - try to transform the bytecode and
- // define the class again
- //
- ClassFileTransformer[] transformers =
- ClassFileTransformer.getTransformers();
- Class c = null;
-
- if (transformers != null) {
- for (ClassFileTransformer transformer : transformers) {
- try {
- // Transform byte code using transformer
- byte[] tb = transformer.transform(b, off, len);
- c = defineClass1(name, tb, 0, tb.length,
- pd, source);
- break;
- } catch (ClassFormatError cfe2) {
- // If ClassFormatError occurs, try next transformer
- }
- }
- }
-
- // Rethrow original ClassFormatError if unable to transform
- // bytecode to well-formed
- //
- if (c == null)
- throw cfe;
-
- return c;
- }
-
- private void postDefineClass(Class c, ProtectionDomain pd)
- {
- if (pd.getCodeSource() != null) {
- Certificate certs[] = pd.getCodeSource().getCertificates();
- if (certs != null)
- setSigners(c, certs);
- }
- }
-
- /**
- * Converts an array of bytes into an instance of class <tt>Class</tt>,
- * with an optional <tt>ProtectionDomain</tt>. If the domain is
- * <tt>null</tt>, then a default domain will be assigned to the class as
- * specified in the documentation for {@link #defineClass(String, byte[],
- * int, int)}. Before the class can be used it must be resolved.
- *
- * <p> The first class defined in a package determines the exact set of
- * certificates that all subsequent classes defined in that package must
- * contain. The set of certificates for a class is obtained from the
- * {@link java.security.CodeSource <tt>CodeSource</tt>} within the
- * <tt>ProtectionDomain</tt> of the class. Any classes added to that
- * package must contain the same set of certificates or a
- * <tt>SecurityException</tt> will be thrown. Note that if
- * <tt>name</tt> is <tt>null</tt>, this check is not performed.
- * You should always pass in the <a href="#name">binary name</a> of the
- * class you are defining as well as the bytes. This ensures that the
- * class you are defining is indeed the class you think it is.
- *
- * <p> The specified <tt>name</tt> cannot begin with "<tt>java.</tt>", since
- * all classes in the "<tt>java.*</tt> packages can only be defined by the
- * bootstrap class loader. If <tt>name</tt> is not <tt>null</tt>, it
- * must be equal to the <a href="#name">binary name</a> of the class
- * specified by the byte array "<tt>b</tt>", otherwise a {@link
- * <tt>NoClassDefFoundError</tt>} will be thrown. </p>
- *
- * @param name
- * The expected <a href="#name">binary name</a> of the class, or
- * <tt>null</tt> if not known
- *
- * @param b
- * The bytes that make up the class data. The bytes in positions
- * <tt>off</tt> through <tt>off+len-1</tt> should have the format
- * of a valid class file as defined by
- * <cite>The Java&trade; Virtual Machine Specification</cite>.
- *
- * @param off
- * The start offset in <tt>b</tt> of the class data
- *
- * @param len
- * The length of the class data
- *
- * @param protectionDomain
- * The ProtectionDomain of the class
- *
- * @return The <tt>Class</tt> object created from the data,
- * and optional <tt>ProtectionDomain</tt>.
- *
- * @throws ClassFormatError
- * If the data did not contain a valid class
- *
- * @throws NoClassDefFoundError
- * If <tt>name</tt> is not equal to the <a href="#name">binary
- * name</a> of the class specified by <tt>b</tt>
- *
- * @throws IndexOutOfBoundsException
- * If either <tt>off</tt> or <tt>len</tt> is negative, or if
- * <tt>off+len</tt> is greater than <tt>b.length</tt>.
- *
- * @throws SecurityException
- * If an attempt is made to add this class to a package that
- * contains classes that were signed by a different set of
- * certificates than this class, or if <tt>name</tt> begins with
- * "<tt>java.</tt>".
- */
- protected final Class<?> defineClass(String name, byte[] b, int off, int len,
- ProtectionDomain protectionDomain)
- throws ClassFormatError
- {
- check();
- protectionDomain = preDefineClass(name, protectionDomain);
-
- Class c = null;
- String source = defineClassSourceLocation(protectionDomain);
-
- try {
- c = defineClass1(name, b, off, len, protectionDomain, source);
- } catch (ClassFormatError cfe) {
- c = defineTransformedClass(name, b, off, len, protectionDomain, cfe,
- source);
- }
-
- postDefineClass(c, protectionDomain);
- return c;
- }
-
- /**
- * Converts a {@link java.nio.ByteBuffer <tt>ByteBuffer</tt>}
- * into an instance of class <tt>Class</tt>,
- * with an optional <tt>ProtectionDomain</tt>. If the domain is
- * <tt>null</tt>, then a default domain will be assigned to the class as
- * specified in the documentation for {@link #defineClass(String, byte[],
- * int, int)}. Before the class can be used it must be resolved.
- *
- * <p>The rules about the first class defined in a package determining the
- * set of certificates for the package, and the restrictions on class names
- * are identical to those specified in the documentation for {@link
- * #defineClass(String, byte[], int, int, ProtectionDomain)}.
- *
- * <p> An invocation of this method of the form
- * <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt>
- * <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same
- * result as the statements
- *
- * <blockquote><tt>
- * ...<br>
- * byte[] temp = new byte[</tt><i>bBuffer</i><tt>.{@link
- * java.nio.ByteBuffer#remaining remaining}()];<br>
- * </tt><i>bBuffer</i><tt>.{@link java.nio.ByteBuffer#get(byte[])
- * get}(temp);<br>
- * return {@link #defineClass(String, byte[], int, int, ProtectionDomain)
- * </tt><i>cl</i><tt>.defineClass}(</tt><i>name</i><tt>, temp, 0,
- * temp.length, </tt><i>pd</i><tt>);<br>
- * </tt></blockquote>
- *
- * @param name
- * The expected <a href="#name">binary name</a>. of the class, or
- * <tt>null</tt> if not known
- *
- * @param b
- * The bytes that make up the class data. The bytes from positions
- * <tt>b.position()</tt> through <tt>b.position() + b.limit() -1
- * </tt> should have the format of a valid class file as defined by
- * <cite>The Java&trade; Virtual Machine Specification</cite>.
- *
- * @param protectionDomain
- * The ProtectionDomain of the class, or <tt>null</tt>.
- *
- * @return The <tt>Class</tt> object created from the data,
- * and optional <tt>ProtectionDomain</tt>.
- *
- * @throws ClassFormatError
- * If the data did not contain a valid class.
- *
- * @throws NoClassDefFoundError
- * If <tt>name</tt> is not equal to the <a href="#name">binary
- * name</a> of the class specified by <tt>b</tt>
- *
- * @throws SecurityException
- * If an attempt is made to add this class to a package that
- * contains classes that were signed by a different set of
- * certificates than this class, or if <tt>name</tt> begins with
- * "<tt>java.</tt>".
- *
- * @see #defineClass(String, byte[], int, int, ProtectionDomain)
- *
- * @since 1.5
- */
- protected final Class<?> defineClass(String name, java.nio.ByteBuffer b,
- ProtectionDomain protectionDomain)
- throws ClassFormatError
- {
- check();
-
- int len = b.remaining();
-
- // Use byte[] if not a direct ByteBufer:
- if (!b.isDirect()) {
- if (b.hasArray()) {
- return defineClass(name, b.array(),
- b.position() + b.arrayOffset(), len,
- protectionDomain);
- } else {
- // no array, or read-only array
- byte[] tb = new byte[len];
- b.get(tb); // get bytes out of byte buffer.
- return defineClass(name, tb, 0, len, protectionDomain);
- }
- }
-
- protectionDomain = preDefineClass(name, protectionDomain);
-
- Class c = null;
- String source = defineClassSourceLocation(protectionDomain);
-
- try {
- c = defineClass2(name, b, b.position(), len, protectionDomain,
- source);
- } catch (ClassFormatError cfe) {
- byte[] tb = new byte[len];
- b.get(tb); // get bytes out of byte buffer.
- c = defineTransformedClass(name, tb, 0, len, protectionDomain, cfe,
- source);
- }
-
- postDefineClass(c, protectionDomain);
- return c;
- }
-
- private native Class defineClass0(String name, byte[] b, int off, int len,
- ProtectionDomain pd);
-
- private native Class defineClass1(String name, byte[] b, int off, int len,
- ProtectionDomain pd, String source);
-
- private native Class defineClass2(String name, java.nio.ByteBuffer b,
- int off, int len, ProtectionDomain pd,
- String source);
-
- // true if the name is null or has the potential to be a valid binary name
- static boolean checkName(String name) {
- if ((name == null) || (name.length() == 0))
- return true;
- if ((name.indexOf('/') != -1)
- || (!VM.allowArraySyntax() && (name.charAt(0) == '[')))
- return false;
- return true;
- }
-
- private void checkCerts(String name, CodeSource cs) {
- int i = name.lastIndexOf('.');
- String pname = (i == -1) ? "" : name.substring(0, i);
-
- Certificate[] certs = null;
- if (cs != null) {
- certs = cs.getCertificates();
- }
- Certificate[] pcerts = null;
- if (parallelLockMap == null) {
- synchronized (this) {
- pcerts = package2certs.get(pname);
- if (pcerts == null) {
- package2certs.put(pname, (certs == null? nocerts:certs));
- }
- }
- } else {
- pcerts = ((ConcurrentHashMap<String, Certificate[]>)package2certs).
- putIfAbsent(pname, (certs == null? nocerts:certs));
- }
- if (pcerts != null && !compareCerts(pcerts, certs)) {
- throw new SecurityException("class \""+ name +
- "\"'s signer information does not match signer information of other classes in the same package");
- }
- }
-
- /**
- * check to make sure the certs for the new class (certs) are the same as
- * the certs for the first class inserted in the package (pcerts)
- */
- private boolean compareCerts(Certificate[] pcerts,
- Certificate[] certs)
- {
- // certs can be null, indicating no certs.
- if ((certs == null) || (certs.length == 0)) {
- return pcerts.length == 0;
- }
-
- // the length must be the same at this point
- if (certs.length != pcerts.length)
- return false;
-
- // go through and make sure all the certs in one array
- // are in the other and vice-versa.
- boolean match;
- for (int i = 0; i < certs.length; i++) {
- match = false;
- for (int j = 0; j < pcerts.length; j++) {
- if (certs[i].equals(pcerts[j])) {
- match = true;
- break;
- }
- }
- if (!match) return false;
- }
-
- // now do the same for pcerts
- for (int i = 0; i < pcerts.length; i++) {
- match = false;
- for (int j = 0; j < certs.length; j++) {
- if (pcerts[i].equals(certs[j])) {
- match = true;
- break;
- }
- }
- if (!match) return false;
- }
-
- return true;
- }
-
- /**
- * Links the specified class. This (misleadingly named) method may be
- * used by a class loader to link a class. If the class <tt>c</tt> has
- * already been linked, then this method simply returns. Otherwise, the
- * class is linked as described in the "Execution" chapter of
- * <cite>The Java&trade; Language Specification</cite>.
- * </p>
- *
- * @param c
- * The class to link
- *
- * @throws NullPointerException
- * If <tt>c</tt> is <tt>null</tt>.
- *
- * @see #defineClass(String, byte[], int, int)
- */
- protected final void resolveClass(Class<?> c) {
- check();
- resolveClass0(c);
- }
-
- private native void resolveClass0(Class c);
-
- /**
- * Finds a class with the specified <a href="#name">binary name</a>,
- * loading it if necessary.
- *
- * <p> This method loads the class through the system class loader (see
- * {@link #getSystemClassLoader()}). The <tt>Class</tt> object returned
- * might have more than one <tt>ClassLoader</tt> associated with it.
- * Subclasses of <tt>ClassLoader</tt> need not usually invoke this method,
- * because most class loaders need to override just {@link
- * #findClass(String)}. </p>
- *
- * @param name
- * The <a href="#name">binary name</a> of the class
- *
- * @return The <tt>Class</tt> object for the specified <tt>name</tt>
- *
- * @throws ClassNotFoundException
- * If the class could not be found
- *
- * @see #ClassLoader(ClassLoader)
- * @see #getParent()
- */
- protected final Class<?> findSystemClass(String name)
- throws ClassNotFoundException
- {
- check();
- ClassLoader system = getSystemClassLoader();
- if (system == null) {
- if (!checkName(name))
- throw new ClassNotFoundException(name);
- Class cls = findBootstrapClass(name);
- if (cls == null) {
- throw new ClassNotFoundException(name);
- }
- return cls;
- }
- return system.loadClass(name);
- }
-
- /**
- * Returns a class loaded by the bootstrap class loader;
- * or return null if not found.
- */
- private Class findBootstrapClassOrNull(String name)
- {
- check();
- if (!checkName(name)) return null;
-
- return findBootstrapClass(name);
- }
-
- // return null if not found
- private native Class findBootstrapClass(String name);
-
- // Check to make sure the class loader has been initialized.
- private void check() {
- if (!initialized) {
- throw new SecurityException("ClassLoader object not initialized");
- }
- }
-
- /**
- * Returns the class with the given <a href="#name">binary name</a> if this
- * loader has been recorded by the Java virtual machine as an initiating
- * loader of a class with that <a href="#name">binary name</a>. Otherwise
- * <tt>null</tt> is returned. </p>
- *
- * @param name
- * The <a href="#name">binary name</a> of the class
- *
- * @return The <tt>Class</tt> object, or <tt>null</tt> if the class has
- * not been loaded
- *
- * @since 1.1
- */
- protected final Class<?> findLoadedClass(String name) {
- check();
- if (!checkName(name))
- return null;
- return findLoadedClass0(name);
- }
-
- private native final Class findLoadedClass0(String name);
-
- /**
- * Sets the signers of a class. This should be invoked after defining a
- * class. </p>
- *
- * @param c
- * The <tt>Class</tt> object
- *
- * @param signers
- * The signers for the class
- *
- * @since 1.1
- */
- protected final void setSigners(Class<?> c, Object[] signers) {
- check();
- c.setSigners(signers);
- }
-
-
- // -- Resource --
-
- /**
- * Finds the resource with the given name. A resource is some data
- * (images, audio, text, etc) that can be accessed by class code in a way
- * that is independent of the location of the code.
- *
- * <p> The name of a resource is a '<tt>/</tt>'-separated path name that
- * identifies the resource.
- *
- * <p> This method will first search the parent class loader for the
- * resource; if the parent is <tt>null</tt> the path of the class loader
- * built-in to the virtual machine is searched. That failing, this method
- * will invoke {@link #findResource(String)} to find the resource. </p>
- *
- * @param name
- * The resource name
- *
- * @return A <tt>URL</tt> object for reading the resource, or
- * <tt>null</tt> if the resource could not be found or the invoker
- * doesn't have adequate privileges to get the resource.
- *
- * @since 1.1
- */
- public URL getResource(String name) {
- URL url;
- if (parent != null) {
- url = parent.getResource(name);
- } else {
- url = getBootstrapResource(name);
- }
- if (url == null) {
- url = findResource(name);
- }
- return url;
- }
-
- /**
- * Finds all the resources with the given name. A resource is some data
- * (images, audio, text, etc) that can be accessed by class code in a way
- * that is independent of the location of the code.
- *
- * <p>The name of a resource is a <tt>/</tt>-separated path name that
- * identifies the resource.
- *
- * <p> The search order is described in the documentation for {@link
- * #getResource(String)}. </p>
- *
- * @param name
- * The resource name
- *
- * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
- * the resource. If no resources could be found, the enumeration
- * will be empty. Resources that the class loader doesn't have
- * access to will not be in the enumeration.
- *
- * @throws IOException
- * If I/O errors occur
- *
- * @see #findResources(String)
- *
- * @since 1.2
- */
- public Enumeration<URL> getResources(String name) throws IOException {
- Enumeration[] tmp = new Enumeration[2];
- if (parent != null) {
- tmp[0] = parent.getResources(name);
- } else {
- tmp[0] = getBootstrapResources(name);
- }
- tmp[1] = findResources(name);
-
- return new CompoundEnumeration<>(tmp);
- }
-
- /**
- * Finds the resource with the given name. Class loader implementations
- * should override this method to specify where to find resources. </p>
- *
- * @param name
- * The resource name
- *
- * @return A <tt>URL</tt> object for reading the resource, or
- * <tt>null</tt> if the resource could not be found
- *
- * @since 1.2
- */
- protected URL findResource(String name) {
- return null;
- }
-
- /**
- * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
- * representing all the resources with the given name. Class loader
- * implementations should override this method to specify where to load
- * resources from. </p>
- *
- * @param name
- * The resource name
- *
- * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
- * the resources
- *
- * @throws IOException
- * If I/O errors occur
- *
- * @since 1.2
- */
- protected Enumeration<URL> findResources(String name) throws IOException {
- return java.util.Collections.emptyEnumeration();
- }
-
- /**
- * Registers the caller as parallel capable.</p>
- * The registration succeeds if and only if all of the following
- * conditions are met: <br>
- * 1. no instance of the caller has been created</p>
- * 2. all of the super classes (except class Object) of the caller are
- * registered as parallel capable</p>
- * Note that once a class loader is registered as parallel capable, there
- * is no way to change it back. </p>
- *
- * @return true if the caller is successfully registered as
- * parallel capable and false if otherwise.
- *
- * @since 1.7
- */
- @CallerSensitive
- protected static boolean registerAsParallelCapable() {
- Class<? extends ClassLoader> callerClass =
- Reflection.getCallerClass().asSubclass(ClassLoader.class);
- return ParallelLoaders.register(callerClass);
- }
-
- /**
- * Find a resource of the specified name from the search path used to load
- * classes. This method locates the resource through the system class
- * loader (see {@link #getSystemClassLoader()}). </p>
- *
- * @param name
- * The resource name
- *
- * @return A {@link java.net.URL <tt>URL</tt>} object for reading the
- * resource, or <tt>null</tt> if the resource could not be found
- *
- * @since 1.1
- */
- public static URL getSystemResource(String name) {
- ClassLoader system = getSystemClassLoader();
- if (system == null) {
- return getBootstrapResource(name);
- }
- return system.getResource(name);
- }
-
- /**
- * Finds all resources of the specified name from the search path used to
- * load classes. The resources thus found are returned as an
- * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link
- * java.net.URL <tt>URL</tt>} objects.
- *
- * <p> The search order is described in the documentation for {@link
- * #getSystemResource(String)}. </p>
- *
- * @param name
- * The resource name
- *
- * @return An enumeration of resource {@link java.net.URL <tt>URL</tt>}
- * objects
- *
- * @throws IOException
- * If I/O errors occur
-
- * @since 1.2
- */
- public static Enumeration<URL> getSystemResources(String name)
- throws IOException
- {
- ClassLoader system = getSystemClassLoader();
- if (system == null) {
- return getBootstrapResources(name);
- }
- return system.getResources(name);
- }
-
- /**
- * Find resources from the VM's built-in classloader.
- */
- private static native URL getBootstrapResource(String name);
-
- /**
- * Find resources from the VM's built-in classloader.
- */
- private static native Enumeration<URL> getBootstrapResources(String name)
- throws IOException;
-
- // Returns the URLClassPath that is used for finding system resources.
- static URLClassPath getBootstrapClassPath() {
- return sun.misc.Launcher.getBootstrapClassPath();
- }
-
-
- /**
- * Returns an input stream for reading the specified resource.
- *
- * <p> The search order is described in the documentation for {@link
- * #getResource(String)}. </p>
- *
- * @param name
- * The resource name
- *
- * @return An input stream for reading the resource, or <tt>null</tt>
- * if the resource could not be found
- *
- * @since 1.1
- */
- public InputStream getResourceAsStream(String name) {
- URL url = getResource(name);
- try {
- return url != null ? url.openStream() : null;
- } catch (IOException e) {
- return null;
- }
- }
-
- /**
- * Open for reading, a resource of the specified name from the search path
- * used to load classes. This method locates the resource through the
- * system class loader (see {@link #getSystemClassLoader()}). </p>
- *
- * @param name
- * The resource name
- *
- * @return An input stream for reading the resource, or <tt>null</tt>
- * if the resource could not be found
- *
- * @since 1.1
- */
- public static InputStream getSystemResourceAsStream(String name) {
- URL url = getSystemResource(name);
- try {
- return url != null ? url.openStream() : null;
- } catch (IOException e) {
- return null;
- }
- }
-
-
- // -- Hierarchy --
-
- /**
- * Returns the parent class loader for delegation. Some implementations may
- * use <tt>null</tt> to represent the bootstrap class loader. This method
- * will return <tt>null</tt> in such implementations if this class loader's
- * parent is the bootstrap class loader.
- *
- * <p> If a security manager is present, and the invoker's class loader is
- * not <tt>null</tt> and is not an ancestor of this class loader, then this
- * method invokes the security manager's {@link
- * SecurityManager#checkPermission(java.security.Permission)
- * <tt>checkPermission</tt>} method with a {@link
- * RuntimePermission#RuntimePermission(String)
- * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
- * access to the parent class loader is permitted. If not, a
- * <tt>SecurityException</tt> will be thrown. </p>
- *
- * @return The parent <tt>ClassLoader</tt>
- *
- * @throws SecurityException
- * If a security manager exists and its <tt>checkPermission</tt>
- * method doesn't allow access to this class loader's parent class
- * loader.
- *
- * @since 1.2
- */
- @CallerSensitive
- public final ClassLoader getParent() {
- if (parent == null)
- return null;
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- checkClassLoaderPermission(parent, Reflection.getCallerClass());
- }
- return parent;
- }
-
- /**
- * Returns the system class loader for delegation. This is the default
- * delegation parent for new <tt>ClassLoader</tt> instances, and is
- * typically the class loader used to start the application.
- *
- * <p> This method is first invoked early in the runtime's startup
- * sequence, at which point it creates the system class loader and sets it
- * as the context class loader of the invoking <tt>Thread</tt>.
- *
- * <p> The default system class loader is an implementation-dependent
- * instance of this class.
- *
- * <p> If the system property "<tt>java.system.class.loader</tt>" is defined
- * when this method is first invoked then the value of that property is
- * taken to be the name of a class that will be returned as the system
- * class loader. The class is loaded using the default system class loader
- * and must define a public constructor that takes a single parameter of
- * type <tt>ClassLoader</tt> which is used as the delegation parent. An
- * instance is then created using this constructor with the default system
- * class loader as the parameter. The resulting class loader is defined
- * to be the system class loader.
- *
- * <p> If a security manager is present, and the invoker's class loader is
- * not <tt>null</tt> and the invoker's class loader is not the same as or
- * an ancestor of the system class loader, then this method invokes the
- * security manager's {@link
- * SecurityManager#checkPermission(java.security.Permission)
- * <tt>checkPermission</tt>} method with a {@link
- * RuntimePermission#RuntimePermission(String)
- * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
- * access to the system class loader. If not, a
- * <tt>SecurityException</tt> will be thrown. </p>
- *
- * @return The system <tt>ClassLoader</tt> for delegation, or
- * <tt>null</tt> if none
- *
- * @throws SecurityException
- * If a security manager exists and its <tt>checkPermission</tt>
- * method doesn't allow access to the system class loader.
- *
- * @throws IllegalStateException
- * If invoked recursively during the construction of the class
- * loader specified by the "<tt>java.system.class.loader</tt>"
- * property.
- *
- * @throws Error
- * If the system property "<tt>java.system.class.loader</tt>"
- * is defined but the named class could not be loaded, the
- * provider class does not define the required constructor, or an
- * exception is thrown by that constructor when it is invoked. The
- * underlying cause of the error can be retrieved via the
- * {@link Throwable#getCause()} method.
- *
- * @revised 1.4
- */
- @CallerSensitive
- public static ClassLoader getSystemClassLoader() {
- initSystemClassLoader();
- if (scl == null) {
- return null;
- }
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- checkClassLoaderPermission(scl, Reflection.getCallerClass());
- }
- return scl;
- }
-
- private static synchronized void initSystemClassLoader() {
- if (!sclSet) {
- if (scl != null)
- throw new IllegalStateException("recursive invocation");
- sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
- if (l != null) {
- Throwable oops = null;
- scl = l.getClassLoader();
- try {
- scl = AccessController.doPrivileged(
- new SystemClassLoaderAction(scl));
- } catch (PrivilegedActionException pae) {
- oops = pae.getCause();
- if (oops instanceof InvocationTargetException) {
- oops = oops.getCause();
- }
- }
- if (oops != null) {
- if (oops instanceof Error) {
- throw (Error) oops;
- } else {
- // wrap the exception
- throw new Error(oops);
- }
- }
- }
- sclSet = true;
- }
- }
-
- // Returns true if the specified class loader can be found in this class
- // loader's delegation chain.
- boolean isAncestor(ClassLoader cl) {
- ClassLoader acl = this;
- do {
- acl = acl.parent;
- if (cl == acl) {
- return true;
- }
- } while (acl != null);
- return false;
- }
-
- // Tests if class loader access requires "getClassLoader" permission
- // check. A class loader 'from' can access class loader 'to' if
- // class loader 'from' is same as class loader 'to' or an ancestor
- // of 'to'. The class loader in a system domain can access
- // any class loader.
- private static boolean needsClassLoaderPermissionCheck(ClassLoader from,
- ClassLoader to)
- {
- if (from == to)
- return false;
-
- if (from == null)
- return false;
-
- return !to.isAncestor(from);
- }
-
- // Returns the class's class loader, or null if none.
- static ClassLoader getClassLoader(Class<?> caller) {
- // This can be null if the VM is requesting it
- if (caller == null) {
- return null;
- }
- // Circumvent security check since this is package-private
- return caller.getClassLoader0();
- }
-
- static void checkClassLoaderPermission(ClassLoader cl, Class<?> caller) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- // caller can be null if the VM is requesting it
- ClassLoader ccl = getClassLoader(caller);
- if (needsClassLoaderPermissionCheck(ccl, cl)) {
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
- }
- }
-
- // The class loader for the system
- // @GuardedBy("ClassLoader.class")
- private static ClassLoader scl;
-
- // Set to true once the system class loader has been set
- // @GuardedBy("ClassLoader.class")
- private static boolean sclSet;
-
-
- // -- Package --
-
- /**
- * Defines a package by name in this <tt>ClassLoader</tt>. This allows
- * class loaders to define the packages for their classes. Packages must
- * be created before the class is defined, and package names must be
- * unique within a class loader and cannot be redefined or changed once
- * created. </p>
- *
- * @param name
- * The package name
- *
- * @param specTitle
- * The specification title
- *
- * @param specVersion
- * The specification version
- *
- * @param specVendor
- * The specification vendor
- *
- * @param implTitle
- * The implementation title
- *
- * @param implVersion
- * The implementation version
- *
- * @param implVendor
- * The implementation vendor
- *
- * @param sealBase
- * If not <tt>null</tt>, then this package is sealed with
- * respect to the given code source {@link java.net.URL
- * <tt>URL</tt>} object. Otherwise, the package is not sealed.
- *
- * @return The newly defined <tt>Package</tt> object
- *
- * @throws IllegalArgumentException
- * If package name duplicates an existing package either in this
- * class loader or one of its ancestors
- *
- * @since 1.2
- */
- protected Package definePackage(String name, String specTitle,
- String specVersion, String specVendor,
- String implTitle, String implVersion,
- String implVendor, URL sealBase)
- throws IllegalArgumentException
- {
- synchronized (packages) {
- Package pkg = getPackage(name);
- if (pkg != null) {
- throw new IllegalArgumentException(name);
- }
- pkg = new Package(name, specTitle, specVersion, specVendor,
- implTitle, implVersion, implVendor,
- sealBase, this);
- packages.put(name, pkg);
- return pkg;
- }
- }
-
- /**
- * Returns a <tt>Package</tt> that has been defined by this class loader
- * or any of its ancestors. </p>
- *
- * @param name
- * The package name
- *
- * @return The <tt>Package</tt> corresponding to the given name, or
- * <tt>null</tt> if not found
- *
- * @since 1.2
- */
- protected Package getPackage(String name) {
- Package pkg;
- synchronized (packages) {
- pkg = packages.get(name);
- }
- if (pkg == null) {
- if (parent != null) {
- pkg = parent.getPackage(name);
- } else {
- pkg = Package.getSystemPackage(name);
- }
- if (pkg != null) {
- synchronized (packages) {
- Package pkg2 = packages.get(name);
- if (pkg2 == null) {
- packages.put(name, pkg);
- } else {
- pkg = pkg2;
- }
- }
- }
- }
- return pkg;
- }
-
- /**
- * Returns all of the <tt>Packages</tt> defined by this class loader and
- * its ancestors. </p>
- *
- * @return The array of <tt>Package</tt> objects defined by this
- * <tt>ClassLoader</tt>
- *
- * @since 1.2
- */
- protected Package[] getPackages() {
- Map<String, Package> map;
- synchronized (packages) {
- map = new HashMap<>(packages);
- }
- Package[] pkgs;
- if (parent != null) {
- pkgs = parent.getPackages();
- } else {
- pkgs = Package.getSystemPackages();
- }
- if (pkgs != null) {
- for (int i = 0; i < pkgs.length; i++) {
- String pkgName = pkgs[i].getName();
- if (map.get(pkgName) == null) {
- map.put(pkgName, pkgs[i]);
- }
- }
- }
- return map.values().toArray(new Package[map.size()]);
- }
-
-
- // -- Native library access --
-
- /**
- * Returns the absolute path name of a native library. The VM invokes this
- * method to locate the native libraries that belong to classes loaded with
- * this class loader. If this method returns <tt>null</tt>, the VM
- * searches the library along the path specified as the
- * "<tt>java.library.path</tt>" property. </p>
- *
- * @param libname
- * The library name
- *
- * @return The absolute path of the native library
- *
- * @see System#loadLibrary(String)
- * @see System#mapLibraryName(String)
- *
- * @since 1.2
- */
- protected String findLibrary(String libname) {
- return null;
- }
-
- /**
- * The inner class NativeLibrary denotes a loaded native library instance.
- * Every classloader contains a vector of loaded native libraries in the
- * private field <tt>nativeLibraries</tt>. The native libraries loaded
- * into the system are entered into the <tt>systemNativeLibraries</tt>
- * vector.
- *
- * <p> Every native library requires a particular version of JNI. This is
- * denoted by the private <tt>jniVersion</tt> field. This field is set by
- * the VM when it loads the library, and used by the VM to pass the correct
- * version of JNI to the native methods. </p>
- *
- * @see ClassLoader
- * @since 1.2
- */
- static class NativeLibrary {
- // opaque handle to native library, used in native code.
- long handle;
- // the version of JNI environment the native library requires.
- private int jniVersion;
- // the class from which the library is loaded, also indicates
- // the loader this native library belongs.
- Class fromClass;
- // the canonicalized name of the native library.
- String name;
-
- native void load(String name);
- native long find(String name);
- native void unload();
-
- public NativeLibrary(Class fromClass, String name) {
- this.name = name;
- this.fromClass = fromClass;
- }
-
- protected void finalize() {
- synchronized (loadedLibraryNames) {
- if (fromClass.getClassLoader() != null && handle != 0) {
- /* remove the native library name */
- int size = loadedLibraryNames.size();
- for (int i = 0; i < size; i++) {
- if (name.equals(loadedLibraryNames.elementAt(i))) {
- loadedLibraryNames.removeElementAt(i);
- break;
- }
- }
- /* unload the library. */
- ClassLoader.nativeLibraryContext.push(this);
- try {
- unload();
- } finally {
- ClassLoader.nativeLibraryContext.pop();
- }
- }
- }
- }
- // Invoked in the VM to determine the context class in
- // JNI_Load/JNI_Unload
- static Class getFromClass() {
- return ClassLoader.nativeLibraryContext.peek().fromClass;
- }
- }
-
- // All native library names we've loaded.
- private static Vector<String> loadedLibraryNames = new Vector<>();
-
- // Native libraries belonging to system classes.
- private static Vector<NativeLibrary> systemNativeLibraries
- = new Vector<>();
-
- // Native libraries associated with the class loader.
- private Vector<NativeLibrary> nativeLibraries = new Vector<>();
-
- // native libraries being loaded/unloaded.
- private static Stack<NativeLibrary> nativeLibraryContext = new Stack<>();
-
- // The paths searched for libraries
- private static String usr_paths[];
- private static String sys_paths[];
-
- private static String[] initializePath(String ldpath) {
- String ps = File.pathSeparator;
- int ldlen = ldpath.length();
- int i, j, n;
- // Count the separators in the path
- i = ldpath.indexOf(ps);
- n = 0;
- while (i >= 0) {
- n++;
- i = ldpath.indexOf(ps, i + 1);
- }
-
- // allocate the array of paths - n :'s = n + 1 path elements
- String[] paths = new String[n + 1];
-
- // Fill the array with paths from the ldpath
- n = i = 0;
- j = ldpath.indexOf(ps);
- while (j >= 0) {
- if (j - i > 0) {
- paths[n++] = ldpath.substring(i, j);
- } else if (j - i == 0) {
- paths[n++] = ".";
- }
- i = j + 1;
- j = ldpath.indexOf(ps, i);
- }
- paths[n] = ldpath.substring(i, ldlen);
- return paths;
- }
-
- private static String java_library_path;
- private static String sun_boot_library_path;
-
- static void initializeLibraryPaths(java.util.Properties props)
- {
- java_library_path = props.getProperty("java.library.path", "");
- sun_boot_library_path = props.getProperty("sun.boot.library.path", "");
- }
-
- // Invoked in the java.lang.Runtime class to implement load and loadLibrary.
- static void loadLibrary(Class fromClass, String name,
- boolean isAbsolute) {
- ClassLoader loader =
- (fromClass == null) ? null : fromClass.getClassLoader();
- if (sys_paths == null) {
- usr_paths = initializePath(java_library_path);
- sys_paths = initializePath(sun_boot_library_path);
- }
- if (isAbsolute) {
- if (loadLibrary0(fromClass, new File(name))) {
- return;
- }
- throw new UnsatisfiedLinkError("Can't load library: " + name);
- }
- if (loader != null) {
- String libfilename = loader.findLibrary(name);
- if (libfilename != null) {
- File libfile = new File(libfilename);
- if (!libfile.isAbsolute()) {
- throw new UnsatisfiedLinkError(
- "ClassLoader.findLibrary failed to return an absolute path: " + libfilename);
- }
- if (loadLibrary0(fromClass, libfile)) {
- return;
- }
- throw new UnsatisfiedLinkError("Can't load " + libfilename);
- }
- }
- for (int i = 0 ; i < sys_paths.length ; i++) {
- File libfile = new File(sys_paths[i], System.mapLibraryName(name));
- if (loadLibrary0(fromClass, libfile)) {
- return;
- }
- }
- if (loader != null) {
- for (int i = 0 ; i < usr_paths.length ; i++) {
- File libfile = new File(usr_paths[i],
- System.mapLibraryName(name));
- if (loadLibrary0(fromClass, libfile)) {
- return;
- }
- }
- }
- // Oops, it failed
- throw new UnsatisfiedLinkError("no " + name + " in java.library.path");
- }
-
- private static boolean loadLibrary0(Class fromClass, final File file) {
- if (loadLibrary1(fromClass, file)) {
- return true;
- }
- final File libfile = ClassLoaderHelper.mapAlternativeName(file);
- if (libfile != null && loadLibrary1(fromClass, libfile)) {
- return true;
- }
- return false;
- }
-
- private static boolean loadLibrary1(Class fromClass, final File file) {
- boolean exists = AccessController.doPrivileged(
- new PrivilegedAction<Object>() {
- public Object run() {
- return file.exists() ? Boolean.TRUE : null;
- }})
- != null;
- if (!exists) {
- return false;
- }
- String name;
- try {
- name = file.getCanonicalPath();
- } catch (IOException e) {
- return false;
- }
- ClassLoader loader =
- (fromClass == null) ? null : fromClass.getClassLoader();
- Vector<NativeLibrary> libs =
- loader != null ? loader.nativeLibraries : systemNativeLibraries;
- synchronized (libs) {
- int size = libs.size();
- for (int i = 0; i < size; i++) {
- NativeLibrary lib = libs.elementAt(i);
- if (name.equals(lib.name)) {
- return true;
- }
- }
-
- synchronized (loadedLibraryNames) {
- if (loadedLibraryNames.contains(name)) {
- throw new UnsatisfiedLinkError
- ("Native Library " +
- name +
- " already loaded in another classloader");
- }
- /* If the library is being loaded (must be by the same thread,
- * because Runtime.load and Runtime.loadLibrary are
- * synchronous). The reason is can occur is that the JNI_OnLoad
- * function can cause another loadLibrary invocation.
- *
- * Thus we can use a static stack to hold the list of libraries
- * we are loading.
- *
- * If there is a pending load operation for the library, we
- * immediately return success; otherwise, we raise
- * UnsatisfiedLinkError.
- */
- int n = nativeLibraryContext.size();
- for (int i = 0; i < n; i++) {
- NativeLibrary lib = nativeLibraryContext.elementAt(i);
- if (name.equals(lib.name)) {
- if (loader == lib.fromClass.getClassLoader()) {
- return true;
- } else {
- throw new UnsatisfiedLinkError
- ("Native Library " +
- name +
- " is being loaded in another classloader");
- }
- }
- }
- NativeLibrary lib = new NativeLibrary(fromClass, name);
- nativeLibraryContext.push(lib);
- try {
- lib.load(name);
- } finally {
- nativeLibraryContext.pop();
- }
- if (lib.handle != 0) {
- loadedLibraryNames.addElement(name);
- libs.addElement(lib);
- return true;
- }
- return false;
- }
- }
- }
-
- // Invoked in the VM class linking code.
- static long findNative(ClassLoader loader, String name) {
- Vector<NativeLibrary> libs =
- loader != null ? loader.nativeLibraries : systemNativeLibraries;
- synchronized (libs) {
- int size = libs.size();
- for (int i = 0; i < size; i++) {
- NativeLibrary lib = libs.elementAt(i);
- long entry = lib.find(name);
- if (entry != 0)
- return entry;
- }
- }
- return 0;
- }
-
-
- // -- Assertion management --
-
- final Object assertionLock;
-
- // The default toggle for assertion checking.
- // @GuardedBy("assertionLock")
- private boolean defaultAssertionStatus = false;
-
- // Maps String packageName to Boolean package default assertion status Note
- // that the default package is placed under a null map key. If this field
- // is null then we are delegating assertion status queries to the VM, i.e.,
- // none of this ClassLoader's assertion status modification methods have
- // been invoked.
- // @GuardedBy("assertionLock")
- private Map<String, Boolean> packageAssertionStatus = null;
-
- // Maps String fullyQualifiedClassName to Boolean assertionStatus If this
- // field is null then we are delegating assertion status queries to the VM,
- // i.e., none of this ClassLoader's assertion status modification methods
- // have been invoked.
- // @GuardedBy("assertionLock")
- Map<String, Boolean> classAssertionStatus = null;
-
- /**
- * Sets the default assertion status for this class loader. This setting
- * determines whether classes loaded by this class loader and initialized
- * in the future will have assertions enabled or disabled by default.
- * This setting may be overridden on a per-package or per-class basis by
- * invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link
- * #setClassAssertionStatus(String, boolean)}. </p>
- *
- * @param enabled
- * <tt>true</tt> if classes loaded by this class loader will
- * henceforth have assertions enabled by default, <tt>false</tt>
- * if they will have assertions disabled by default.
- *
- * @since 1.4
- */
- public void setDefaultAssertionStatus(boolean enabled) {
- synchronized (assertionLock) {
- if (classAssertionStatus == null)
- initializeJavaAssertionMaps();
-
- defaultAssertionStatus = enabled;
- }
- }
-
- /**
- * Sets the package default assertion status for the named package. The
- * package default assertion status determines the assertion status for
- * classes initialized in the future that belong to the named package or
- * any of its "subpackages".
- *
- * <p> A subpackage of a package named p is any package whose name begins
- * with "<tt>p.</tt>". For example, <tt>javax.swing.text</tt> is a
- * subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and
- * <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>.
- *
- * <p> In the event that multiple package defaults apply to a given class,
- * the package default pertaining to the most specific package takes
- * precedence over the others. For example, if <tt>javax.lang</tt> and
- * <tt>javax.lang.reflect</tt> both have package defaults associated with
- * them, the latter package default applies to classes in
- * <tt>javax.lang.reflect</tt>.
- *
- * <p> Package defaults take precedence over the class loader's default
- * assertion status, and may be overridden on a per-class basis by invoking
- * {@link #setClassAssertionStatus(String, boolean)}. </p>
- *
- * @param packageName
- * The name of the package whose package default assertion status
- * is to be set. A <tt>null</tt> value indicates the unnamed
- * package that is "current"
- * (see section 7.4.2 of
- * <cite>The Java&trade; Language Specification</cite>.)
- *
- * @param enabled
- * <tt>true</tt> if classes loaded by this classloader and
- * belonging to the named package or any of its subpackages will
- * have assertions enabled by default, <tt>false</tt> if they will
- * have assertions disabled by default.
- *
- * @since 1.4
- */
- public void setPackageAssertionStatus(String packageName,
- boolean enabled) {
- synchronized (assertionLock) {
- if (packageAssertionStatus == null)
- initializeJavaAssertionMaps();
-
- packageAssertionStatus.put(packageName, enabled);
- }
- }
-
- /**
- * Sets the desired assertion status for the named top-level class in this
- * class loader and any nested classes contained therein. This setting
- * takes precedence over the class loader's default assertion status, and
- * over any applicable per-package default. This method has no effect if
- * the named class has already been initialized. (Once a class is
- * initialized, its assertion status cannot change.)
- *
- * <p> If the named class is not a top-level class, this invocation will
- * have no effect on the actual assertion status of any class. </p>
- *
- * @param className
- * The fully qualified class name of the top-level class whose
- * assertion status is to be set.
- *
- * @param enabled
- * <tt>true</tt> if the named class is to have assertions
- * enabled when (and if) it is initialized, <tt>false</tt> if the
- * class is to have assertions disabled.
- *
- * @since 1.4
- */
- public void setClassAssertionStatus(String className, boolean enabled) {
- synchronized (assertionLock) {
- if (classAssertionStatus == null)
- initializeJavaAssertionMaps();
-
- classAssertionStatus.put(className, enabled);
- }
- }
-
- /**
- * Sets the default assertion status for this class loader to
- * <tt>false</tt> and discards any package defaults or class assertion
- * status settings associated with the class loader. This method is
- * provided so that class loaders can be made to ignore any command line or
- * persistent assertion status settings and "start with a clean slate."
- * </p>
- *
- * @since 1.4
- */
- public void clearAssertionStatus() {
- /*
- * Whether or not "Java assertion maps" are initialized, set
- * them to empty maps, effectively ignoring any present settings.
- */
- synchronized (assertionLock) {
- classAssertionStatus = new HashMap<>();
- packageAssertionStatus = new HashMap<>();
- defaultAssertionStatus = false;
- }
- }
-
- /**
- * Returns the assertion status that would be assigned to the specified
- * class if it were to be initialized at the time this method is invoked.
- * If the named class has had its assertion status set, the most recent
- * setting will be returned; otherwise, if any package default assertion
- * status pertains to this class, the most recent setting for the most
- * specific pertinent package default assertion status is returned;
- * otherwise, this class loader's default assertion status is returned.
- * </p>
- *
- * @param className
- * The fully qualified class name of the class whose desired
- * assertion status is being queried.
- *
- * @return The desired assertion status of the specified class.
- *
- * @see #setClassAssertionStatus(String, boolean)
- * @see #setPackageAssertionStatus(String, boolean)
- * @see #setDefaultAssertionStatus(boolean)
- *
- * @since 1.4
- */
- boolean desiredAssertionStatus(String className) {
- synchronized (assertionLock) {
- // assert classAssertionStatus != null;
- // assert packageAssertionStatus != null;
-
- // Check for a class entry
- Boolean result = classAssertionStatus.get(className);
- if (result != null)
- return result.booleanValue();
-
- // Check for most specific package entry
- int dotIndex = className.lastIndexOf(".");
- if (dotIndex < 0) { // default package
- result = packageAssertionStatus.get(null);
- if (result != null)
- return result.booleanValue();
- }
- while(dotIndex > 0) {
- className = className.substring(0, dotIndex);
- result = packageAssertionStatus.get(className);
- if (result != null)
- return result.booleanValue();
- dotIndex = className.lastIndexOf(".", dotIndex-1);
- }
-
- // Return the classloader default
- return defaultAssertionStatus;
- }
- }
-
- // Set up the assertions with information provided by the VM.
- // Note: Should only be called inside a synchronized block
- private void initializeJavaAssertionMaps() {
- // assert Thread.holdsLock(assertionLock);
-
- classAssertionStatus = new HashMap<>();
- packageAssertionStatus = new HashMap<>();
- AssertionStatusDirectives directives = retrieveDirectives();
-
- for(int i = 0; i < directives.classes.length; i++)
- classAssertionStatus.put(directives.classes[i],
- directives.classEnabled[i]);
-
- for(int i = 0; i < directives.packages.length; i++)
- packageAssertionStatus.put(directives.packages[i],
- directives.packageEnabled[i]);
-
- defaultAssertionStatus = directives.deflt;
- }
-
- // Retrieves the assertion directives from the VM.
- private static native AssertionStatusDirectives retrieveDirectives();
-
- // [IKVM] equivalent of HotSpot's java_lang_ClassLoader::is_trusted_loader()
- static boolean isTrustedLoader(ClassLoader loader) {
- ClassLoader cl = scl;
- while (cl != null) {
- if (cl == loader) return true;
- cl = cl.parent;
- }
- return false;
- }
-}
-
-
-class SystemClassLoaderAction
- implements PrivilegedExceptionAction<ClassLoader> {
- private ClassLoader parent;
-
- SystemClassLoaderAction(ClassLoader parent) {
- this.parent = parent;
- }
-
- public ClassLoader run() throws Exception {
- String cls = System.getProperty("java.system.class.loader");
- if (cls == null) {
- return parent;
- }
-
- Constructor ctor = Class.forName(cls, true, parent)
- .getDeclaredConstructor(new Class[] { ClassLoader.class });
- ClassLoader sys = (ClassLoader) ctor.newInstance(
- new Object[] { parent });
- Thread.currentThread().setContextClassLoader(sys);
- return sys;
- }
-}
diff --git a/openjdk/java/lang/ClassLoaderHelper.java b/openjdk/java/lang/ClassLoaderHelper.java
deleted file mode 100644
index c37c47e8..00000000
--- a/openjdk/java/lang/ClassLoaderHelper.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.lang;
-
-import java.io.File;
-
-class ClassLoaderHelper {
-
- private ClassLoaderHelper() {}
-
- /**
- * Returns an alternate path name for the given file
- * such that if the original pathname did not exist, then the
- * file may be located at the alternate location.
- * For mac, this replaces the final .dylib suffix with .jnilib
- */
- static File mapAlternativeName(File lib) {
- if (ikvm.internal.Util.MACOSX) {
- String name = lib.toString();
- int index = name.toLowerCase().lastIndexOf(".dylib");
- if (index < 0) {
- return null;
- }
- return new File(name.substring(0, index) + ".jnilib");
- } else {
- return null;
- }
- }
-}
diff --git a/openjdk/java/lang/Enum.java b/openjdk/java/lang/Enum.java
deleted file mode 100644
index b29550b4..00000000
--- a/openjdk/java/lang/Enum.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang;
-
-import java.io.Serializable;
-import java.io.IOException;
-import java.io.InvalidObjectException;
-import java.io.ObjectInputStream;
-import java.io.ObjectStreamException;
-import cli.System.Runtime.Serialization.IObjectReference;
-import cli.System.Runtime.Serialization.SerializationException;
-import cli.System.Runtime.Serialization.SerializationInfo;
-import cli.System.Runtime.Serialization.StreamingContext;
-
-/**
- * This is the common base class of all Java language enumeration types.
- *
- * More information about enums, including descriptions of the
- * implicitly declared methods synthesized by the compiler, can be
- * found in section 8.9 of
- * <cite>The Java&trade; Language Specification</cite>.
- *
- * <p> Note that when using an enumeration type as the type of a set
- * or as the type of the keys in a map, specialized and efficient
- * {@linkplain java.util.EnumSet set} and {@linkplain
- * java.util.EnumMap map} implementations are available.
- *
- * @param <E> The enum type subclass
- * @author Josh Bloch
- * @author Neal Gafter
- * @see Class#getEnumConstants()
- * @see java.util.EnumSet
- * @see java.util.EnumMap
- * @since 1.5
- */
-@cli.System.SerializableAttribute.Annotation
-public abstract class Enum<E extends Enum<E>>
- implements Comparable<E>, Serializable {
- /**
- * The name of this enum constant, as declared in the enum declaration.
- * Most programmers should use the {@link #toString} method rather than
- * accessing this field.
- */
- private final String name;
-
- /**
- * Returns the name of this enum constant, exactly as declared in its
- * enum declaration.
- *
- * <b>Most programmers should use the {@link #toString} method in
- * preference to this one, as the toString method may return
- * a more user-friendly name.</b> This method is designed primarily for
- * use in specialized situations where correctness depends on getting the
- * exact name, which will not vary from release to release.
- *
- * @return the name of this enum constant
- */
- public final String name() {
- return name;
- }
-
- /**
- * The ordinal of this enumeration constant (its position
- * in the enum declaration, where the initial constant is assigned
- * an ordinal of zero).
- *
- * Most programmers will have no use for this field. It is designed
- * for use by sophisticated enum-based data structures, such as
- * {@link java.util.EnumSet} and {@link java.util.EnumMap}.
- */
- private final int ordinal;
-
- /**
- * Returns the ordinal of this enumeration constant (its position
- * in its enum declaration, where the initial constant is assigned
- * an ordinal of zero).
- *
- * Most programmers will have no use for this method. It is
- * designed for use by sophisticated enum-based data structures, such
- * as {@link java.util.EnumSet} and {@link java.util.EnumMap}.
- *
- * @return the ordinal of this enumeration constant
- */
- public final int ordinal() {
- return ordinal;
- }
-
- /**
- * Sole constructor. Programmers cannot invoke this constructor.
- * It is for use by code emitted by the compiler in response to
- * enum type declarations.
- *
- * @param name - The name of this enum constant, which is the identifier
- * used to declare it.
- * @param ordinal - The ordinal of this enumeration constant (its position
- * in the enum declaration, where the initial constant is assigned
- * an ordinal of zero).
- */
- protected Enum(String name, int ordinal) {
- this.name = name;
- this.ordinal = ordinal;
- }
-
- /**
- * Returns the name of this enum constant, as contained in the
- * declaration. This method may be overridden, though it typically
- * isn't necessary or desirable. An enum type should override this
- * method when a more "programmer-friendly" string form exists.
- *
- * @return the name of this enum constant
- */
- public String toString() {
- return name;
- }
-
- /**
- * Returns true if the specified object is equal to this
- * enum constant.
- *
- * @param other the object to be compared for equality with this object.
- * @return true if the specified object is equal to this
- * enum constant.
- */
- public final boolean equals(Object other) {
- return this==other;
- }
-
- /**
- * Returns a hash code for this enum constant.
- *
- * @return a hash code for this enum constant.
- */
- public final int hashCode() {
- return super.hashCode();
- }
-
- /**
- * Throws CloneNotSupportedException. This guarantees that enums
- * are never cloned, which is necessary to preserve their "singleton"
- * status.
- *
- * @return (never returns)
- */
- protected final Object clone() throws CloneNotSupportedException {
- throw new CloneNotSupportedException();
- }
-
- /**
- * Compares this enum with the specified object for order. Returns a
- * negative integer, zero, or a positive integer as this object is less
- * than, equal to, or greater than the specified object.
- *
- * Enum constants are only comparable to other enum constants of the
- * same enum type. The natural order implemented by this
- * method is the order in which the constants are declared.
- */
- public final int compareTo(E o) {
- Enum other = (Enum)o;
- Enum self = this;
- if (self.getClass() != other.getClass() && // optimization
- self.getDeclaringClass() != other.getDeclaringClass())
- throw new ClassCastException();
- return self.ordinal - other.ordinal;
- }
-
- /**
- * Returns the Class object corresponding to this enum constant's
- * enum type. Two enum constants e1 and e2 are of the
- * same enum type if and only if
- * e1.getDeclaringClass() == e2.getDeclaringClass().
- * (The value returned by this method may differ from the one returned
- * by the {@link Object#getClass} method for enum constants with
- * constant-specific class bodies.)
- *
- * @return the Class object corresponding to this enum constant's
- * enum type
- */
- public final Class<E> getDeclaringClass() {
- Class clazz = getClass();
- Class zuper = clazz.getSuperclass();
- return (zuper == Enum.class) ? clazz : zuper;
- }
-
- /**
- * Returns the enum constant of the specified enum type with the
- * specified name. The name must match exactly an identifier used
- * to declare an enum constant in this type. (Extraneous whitespace
- * characters are not permitted.)
- *
- * <p>Note that for a particular enum type {@code T}, the
- * implicitly declared {@code public static T valueOf(String)}
- * method on that enum may be used instead of this method to map
- * from a name to the corresponding enum constant. All the
- * constants of an enum type can be obtained by calling the
- * implicit {@code public static T[] values()} method of that
- * type.
- *
- * @param <T> The enum type whose constant is to be returned
- * @param enumType the {@code Class} object of the enum type from which
- * to return a constant
- * @param name the name of the constant to return
- * @return the enum constant of the specified enum type with the
- * specified name
- * @throws IllegalArgumentException if the specified enum type has
- * no constant with the specified name, or the specified
- * class object does not represent an enum type
- * @throws NullPointerException if {@code enumType} or {@code name}
- * is null
- * @since 1.5
- */
- public static <T extends Enum<T>> T valueOf(Class<T> enumType,
- String name) {
- T result = enumType.enumConstantDirectory().get(name);
- if (result != null)
- return result;
- if (name == null)
- throw new NullPointerException("Name is null");
- throw new IllegalArgumentException(
- "No enum constant " + enumType.getCanonicalName() + "." + name);
- }
-
- /**
- * enum classes cannot have finalize methods.
- */
- protected final void finalize() { }
-
- /**
- * prevent default deserialization
- */
- private void readObject(ObjectInputStream in) throws IOException,
- ClassNotFoundException {
- throw new InvalidObjectException("can't deserialize enum");
- }
-
- private void readObjectNoData() throws ObjectStreamException {
- throw new InvalidObjectException("can't deserialize enum");
- }
-
- // [IKVM] .NET serialization support starts here
- // Note that we don't have a security demand, because the info is harmless.
- @cli.IKVM.Attributes.HideFromJavaAttribute.Annotation
- @cli.System.Security.SecurityCriticalAttribute.Annotation
- public final void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- info.AddValue("enumType", getDeclaringClass());
- info.AddValue("name", name);
- info.SetType(ikvm.runtime.Util.getInstanceTypeFromClass(EnumSerializationProxy.class));
- }
-}
-
-@cli.System.SerializableAttribute.Annotation
-final class EnumSerializationProxy implements IObjectReference
-{
- private Class enumType;
- private String name;
-
- @cli.System.Security.SecurityCriticalAttribute.Annotation
- public Object GetRealObject(StreamingContext context)
- {
- try
- {
- return Enum.valueOf(enumType, name);
- }
- catch (IllegalArgumentException x)
- {
- ikvm.runtime.Util.throwException(new SerializationException("Enum value " + name + " not found in " + enumType, x));
- return null;
- }
- }
-}
diff --git a/openjdk/java/lang/LangHelper.java b/openjdk/java/lang/LangHelper.java
deleted file mode 100644
index 8d725d43..00000000
--- a/openjdk/java/lang/LangHelper.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- Copyright (C) 2007-2014 Jeroen Frijters
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jeroen Frijters
- jeroen@frijters.net
-
-*/
-
-package java.lang;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Executable;
-import java.security.AccessControlContext;
-import java.util.Map;
-import sun.nio.ch.Interruptible;
-import sun.reflect.annotation.AnnotationType;
-
-@ikvm.lang.Internal
-public class LangHelper
-{
- public static sun.misc.JavaLangAccess getJavaLangAccess()
- {
- return new sun.misc.JavaLangAccess() {
- public sun.reflect.ConstantPool getConstantPool(Class klass) {
- return klass.getConstantPool();
- }
- public boolean casAnnotationType(Class<?> klass, AnnotationType oldType, AnnotationType newType) {
- return klass.casAnnotationType(oldType, newType);
- }
- public AnnotationType getAnnotationType(Class klass) {
- return klass.getAnnotationType();
- }
- public Map<Class<? extends Annotation>, Annotation> getDeclaredAnnotationMap(Class<?> klass) {
- return klass.getDeclaredAnnotationMap();
- }
- public byte[] getRawClassAnnotations(Class<?> klass) {
- throw new InternalError();
- }
- public byte[] getRawClassTypeAnnotations(Class<?> klass) {
- return klass.getRawTypeAnnotations();
- }
- public byte[] getRawExecutableTypeAnnotations(Executable executable) {
- return Class.getExecutableTypeAnnotationBytes(executable);
- }
- public <E extends Enum<E>>
- E[] getEnumConstantsShared(Class<E> klass) {
- return klass.getEnumConstantsShared();
- }
- public void blockedOn(Thread t, Interruptible b) {
- t.blockedOn(b);
- }
- public void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook) {
- Shutdown.add(slot, registerShutdownInProgress, hook);
- }
- public int getStackTraceDepth(Throwable t) {
- return t.getStackTraceDepth();
- }
- public StackTraceElement getStackTraceElement(Throwable t, int i) {
- return t.getStackTraceElement(i);
- }
- public String newStringUnsafe(char[] chars) {
- return String.valueOf(chars);
- }
- public Thread newThreadWithAcc(Runnable target, AccessControlContext acc) {
- return new Thread(target, acc);
- }
- public void invokeFinalize(Object o) throws Throwable {
- // we don't actually support invoking the finalize method explicitly
- }
- };
- }
-}
diff --git a/openjdk/java/lang/Package.java b/openjdk/java/lang/Package.java
deleted file mode 100644
index 395cf336..00000000
--- a/openjdk/java/lang/Package.java
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang;
-
-import java.io.InputStream;
-import java.util.Enumeration;
-
-import java.util.StringTokenizer;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.URL;
-import java.net.MalformedURLException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-import java.util.jar.JarInputStream;
-import java.util.jar.Manifest;
-import java.util.jar.Attributes;
-import java.util.jar.Attributes.Name;
-import java.util.jar.JarException;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Iterator;
-
-import java.lang.annotation.Annotation;
-import sun.net.www.ParseUtil;
-import sun.reflect.CallerSensitive;
-import sun.reflect.Reflection;
-
-/**
- * {@code Package} objects contain version information
- * about the implementation and specification of a Java package.
- * This versioning information is retrieved and made available
- * by the {@link ClassLoader} instance that
- * loaded the class(es). Typically, it is stored in the manifest that is
- * distributed with the classes.
- *
- * <p>The set of classes that make up the package may implement a
- * particular specification and if so the specification title, version number,
- * and vendor strings identify that specification.
- * An application can ask if the package is
- * compatible with a particular version, see the {@link
- * #isCompatibleWith isCompatibleWith}
- * method for details.
- *
- * <p>Specification version numbers use a syntax that consists of nonnegative
- * decimal integers separated by periods ".", for example "2.0" or
- * "1.2.3.4.5.6.7". This allows an extensible number to be used to represent
- * major, minor, micro, etc. versions. The version specification is described
- * by the following formal grammar:
- * <blockquote>
- * <dl>
- * <dt><i>SpecificationVersion:
- * <dd>Digits RefinedVersion<sub>opt</sub></i>
-
- * <p><dt><i>RefinedVersion:</i>
- * <dd>{@code .} <i>Digits</i>
- * <dd>{@code .} <i>Digits RefinedVersion</i>
- *
- * <p><dt><i>Digits:
- * <dd>Digit
- * <dd>Digits</i>
- *
- * <p><dt><i>Digit:</i>
- * <dd>any character for which {@link Character#isDigit} returns {@code true},
- * e.g. 0, 1, 2, ...
- * </dl>
- * </blockquote>
- *
- * <p>The implementation title, version, and vendor strings identify an
- * implementation and are made available conveniently to enable accurate
- * reporting of the packages involved when a problem occurs. The contents
- * all three implementation strings are vendor specific. The
- * implementation version strings have no specified syntax and should
- * only be compared for equality with desired version identifiers.
- *
- * <p>Within each {@code ClassLoader} instance all classes from the same
- * java package have the same Package object. The static methods allow a package
- * to be found by name or the set of all packages known to the current class
- * loader to be found.
- *
- * @see ClassLoader#definePackage
- */
-public class Package implements java.lang.reflect.AnnotatedElement {
- /**
- * Return the name of this package.
- *
- * @return The fully-qualified name of this package as defined in section 6.5.3 of
- * <cite>The Java&trade; Language Specification</cite>,
- * for example, {@code java.lang}
- */
- public String getName() {
- return pkgName;
- }
-
-
- /**
- * Return the title of the specification that this package implements.
- * @return the specification title, null is returned if it is not known.
- */
- public String getSpecificationTitle() {
- return specTitle;
- }
-
- /**
- * Returns the version number of the specification
- * that this package implements.
- * This version string must be a sequence of nonnegative decimal
- * integers separated by "."'s and may have leading zeros.
- * When version strings are compared the most significant
- * numbers are compared.
- * @return the specification version, null is returned if it is not known.
- */
- public String getSpecificationVersion() {
- return specVersion;
- }
-
- /**
- * Return the name of the organization, vendor,
- * or company that owns and maintains the specification
- * of the classes that implement this package.
- * @return the specification vendor, null is returned if it is not known.
- */
- public String getSpecificationVendor() {
- return specVendor;
- }
-
- /**
- * Return the title of this package.
- * @return the title of the implementation, null is returned if it is not known.
- */
- public String getImplementationTitle() {
- return implTitle;
- }
-
- /**
- * Return the version of this implementation. It consists of any string
- * assigned by the vendor of this implementation and does
- * not have any particular syntax specified or expected by the Java
- * runtime. It may be compared for equality with other
- * package version strings used for this implementation
- * by this vendor for this package.
- * @return the version of the implementation, null is returned if it is not known.
- */
- public String getImplementationVersion() {
- return implVersion;
- }
-
- /**
- * Returns the name of the organization,
- * vendor or company that provided this implementation.
- * @return the vendor that implemented this package..
- */
- public String getImplementationVendor() {
- return implVendor;
- }
-
- /**
- * Returns true if this package is sealed.
- *
- * @return true if the package is sealed, false otherwise
- */
- public boolean isSealed() {
- return sealBase != null;
- }
-
- /**
- * Returns true if this package is sealed with respect to the specified
- * code source url.
- *
- * @param url the code source url
- * @return true if this package is sealed with respect to url
- */
- public boolean isSealed(URL url) {
- return url.equals(sealBase);
- }
-
- /**
- * Compare this package's specification version with a
- * desired version. It returns true if
- * this packages specification version number is greater than or equal
- * to the desired version number. <p>
- *
- * Version numbers are compared by sequentially comparing corresponding
- * components of the desired and specification strings.
- * Each component is converted as a decimal integer and the values
- * compared.
- * If the specification value is greater than the desired
- * value true is returned. If the value is less false is returned.
- * If the values are equal the period is skipped and the next pair of
- * components is compared.
- *
- * @param desired the version string of the desired version.
- * @return true if this package's version number is greater
- * than or equal to the desired version number
- *
- * @exception NumberFormatException if the desired or current version
- * is not of the correct dotted form.
- */
- public boolean isCompatibleWith(String desired)
- throws NumberFormatException
- {
- if (specVersion == null || specVersion.length() < 1) {
- throw new NumberFormatException("Empty version string");
- }
-
- String [] sa = specVersion.split("\\.", -1);
- int [] si = new int[sa.length];
- for (int i = 0; i < sa.length; i++) {
- si[i] = Integer.parseInt(sa[i]);
- if (si[i] < 0)
- throw NumberFormatException.forInputString("" + si[i]);
- }
-
- String [] da = desired.split("\\.", -1);
- int [] di = new int[da.length];
- for (int i = 0; i < da.length; i++) {
- di[i] = Integer.parseInt(da[i]);
- if (di[i] < 0)
- throw NumberFormatException.forInputString("" + di[i]);
- }
-
- int len = Math.max(di.length, si.length);
- for (int i = 0; i < len; i++) {
- int d = (i < di.length ? di[i] : 0);
- int s = (i < si.length ? si[i] : 0);
- if (s < d)
- return false;
- if (s > d)
- return true;
- }
- return true;
- }
-
- /**
- * Find a package by name in the callers {@code ClassLoader} instance.
- * The callers {@code ClassLoader} instance is used to find the package
- * instance corresponding to the named class. If the callers
- * {@code ClassLoader} instance is null then the set of packages loaded
- * by the system {@code ClassLoader} instance is searched to find the
- * named package. <p>
- *
- * Packages have attributes for versions and specifications only if the class
- * loader created the package instance with the appropriate attributes. Typically,
- * those attributes are defined in the manifests that accompany the classes.
- *
- * @param name a package name, for example, java.lang.
- * @return the package of the requested name. It may be null if no package
- * information is available from the archive or codebase.
- */
- @CallerSensitive
- public static Package getPackage(String name) {
- ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
- if (l != null) {
- return l.getPackage(name);
- } else {
- return getSystemPackage(name);
- }
- }
-
- /**
- * Get all the packages currently known for the caller's {@code ClassLoader}
- * instance. Those packages correspond to classes loaded via or accessible by
- * name to that {@code ClassLoader} instance. If the caller's
- * {@code ClassLoader} instance is the bootstrap {@code ClassLoader}
- * instance, which may be represented by {@code null} in some implementations,
- * only packages corresponding to classes loaded by the bootstrap
- * {@code ClassLoader} instance will be returned.
- *
- * @return a new array of packages known to the callers {@code ClassLoader}
- * instance. An zero length array is returned if none are known.
- */
- @CallerSensitive
- public static Package[] getPackages() {
- ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
- if (l != null) {
- return l.getPackages();
- } else {
- return getSystemPackages();
- }
- }
-
- /**
- * Get the package for the specified class.
- * The class's class loader is used to find the package instance
- * corresponding to the specified class. If the class loader
- * is the bootstrap class loader, which may be represented by
- * {@code null} in some implementations, then the set of packages
- * loaded by the bootstrap class loader is searched to find the package.
- * <p>
- * Packages have attributes for versions and specifications only
- * if the class loader created the package
- * instance with the appropriate attributes. Typically those
- * attributes are defined in the manifests that accompany
- * the classes.
- *
- * @param class the class to get the package of.
- * @return the package of the class. It may be null if no package
- * information is available from the archive or codebase. */
- static Package getPackage(Class<?> c) {
- String name = c.getName();
- int i = name.lastIndexOf('.');
- if (i != -1) {
- name = name.substring(0, i);
- ClassLoader cl = c.getClassLoader();
- if (cl != null) {
- return cl.getPackage(name);
- } else {
- return getSystemPackage(name);
- }
- } else {
- return null;
- }
- }
-
- /**
- * Return the hash code computed from the package name.
- * @return the hash code computed from the package name.
- */
- public int hashCode(){
- return pkgName.hashCode();
- }
-
- /**
- * Returns the string representation of this Package.
- * Its value is the string "package " and the package name.
- * If the package title is defined it is appended.
- * If the package version is defined it is appended.
- * @return the string representation of the package.
- */
- public String toString() {
- String spec = specTitle;
- String ver = specVersion;
- if (spec != null && spec.length() > 0)
- spec = ", " + spec;
- else
- spec = "";
- if (ver != null && ver.length() > 0)
- ver = ", version " + ver;
- else
- ver = "";
- return "package " + pkgName + spec + ver;
- }
-
- private Class<?> getPackageInfo() {
- if (packageInfo == null) {
- try {
- packageInfo = Class.forName(pkgName + ".package-info", false, loader);
- } catch (ClassNotFoundException ex) {
- // store a proxy for the package info that has no annotations
- class PackageInfoProxy {}
- packageInfo = PackageInfoProxy.class;
- }
- }
- return packageInfo;
- }
-
- /**
- * @throws NullPointerException {@inheritDoc}
- * @since 1.5
- */
- public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
- return getPackageInfo().getAnnotation(annotationClass);
- }
-
- /**
- * @throws NullPointerException {@inheritDoc}
- * @since 1.5
- */
- public boolean isAnnotationPresent(
- Class<? extends Annotation> annotationClass) {
- return getPackageInfo().isAnnotationPresent(annotationClass);
- }
-
- /**
- * @since 1.5
- */
- public Annotation[] getAnnotations() {
- return getPackageInfo().getAnnotations();
- }
-
- /**
- * @since 1.5
- */
- public Annotation[] getDeclaredAnnotations() {
- return getPackageInfo().getDeclaredAnnotations();
- }
-
- /**
- * Construct a package instance with the specified version
- * information.
- * @param pkgName the name of the package
- * @param spectitle the title of the specification
- * @param specversion the version of the specification
- * @param specvendor the organization that maintains the specification
- * @param impltitle the title of the implementation
- * @param implversion the version of the implementation
- * @param implvendor the organization that maintains the implementation
- * @return a new package for containing the specified information.
- */
- Package(String name,
- String spectitle, String specversion, String specvendor,
- String impltitle, String implversion, String implvendor,
- URL sealbase, ClassLoader loader)
- {
- pkgName = name;
- implTitle = impltitle;
- implVersion = implversion;
- implVendor = implvendor;
- specTitle = spectitle;
- specVersion = specversion;
- specVendor = specvendor;
- sealBase = sealbase;
- this.loader = loader;
- }
-
- /*
- * Construct a package using the attributes from the specified manifest.
- *
- * @param name the package name
- * @param man the optional manifest for the package
- * @param url the optional code source url for the package
- */
- private Package(String name, Manifest man, URL url, ClassLoader loader) {
- String path = name.replace('.', '/').concat("/");
- String sealed = null;
- String specTitle= null;
- String specVersion= null;
- String specVendor= null;
- String implTitle= null;
- String implVersion= null;
- String implVendor= null;
- URL sealBase= null;
- Attributes attr = man.getAttributes(path);
- if (attr != null) {
- specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
- specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
- specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
- implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
- implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
- implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
- sealed = attr.getValue(Name.SEALED);
- }
- attr = man.getMainAttributes();
- if (attr != null) {
- if (specTitle == null) {
- specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
- }
- if (specVersion == null) {
- specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
- }
- if (specVendor == null) {
- specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
- }
- if (implTitle == null) {
- implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
- }
- if (implVersion == null) {
- implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
- }
- if (implVendor == null) {
- implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
- }
- if (sealed == null) {
- sealed = attr.getValue(Name.SEALED);
- }
- }
- if ("true".equalsIgnoreCase(sealed)) {
- sealBase = url;
- }
- pkgName = name;
- this.specTitle = specTitle;
- this.specVersion = specVersion;
- this.specVendor = specVendor;
- this.implTitle = implTitle;
- this.implVersion = implVersion;
- this.implVendor = implVendor;
- this.sealBase = sealBase;
- this.loader = loader;
- }
-
- /*
- * Returns the loaded system package for the specified name.
- */
- static Package getSystemPackage(String name) {
- synchronized (pkgs) {
- Package pkg = pkgs.get(name);
- if (pkg == null) {
- name = name.replace('.', '/').concat("/");
- String fn = getSystemPackage0(name);
- if (fn != null) {
- pkg = defineSystemPackage(name, fn);
- }
- }
- return pkg;
- }
- }
-
- /*
- * Return an array of loaded system packages.
- */
- static Package[] getSystemPackages() {
- // First, update the system package map with new package names
- String[] names = getSystemPackages0();
- synchronized (pkgs) {
- for (int i = 0; i < names.length; i++) {
- defineSystemPackage(names[i], getSystemPackage0(names[i]));
- }
- return pkgs.values().toArray(new Package[pkgs.size()]);
- }
- }
-
- private static Package defineSystemPackage(final String iname,
- final String fn)
- {
- return AccessController.doPrivileged(new PrivilegedAction<Package>() {
- public Package run() {
- String name = iname;
- // Get the cached code source url for the file name
- URL url = urls.get(fn);
- if (url == null) {
- // URL not found, so create one
- File file = new File(fn);
- try {
- url = ParseUtil.fileToEncodedURL(file);
- } catch (MalformedURLException e) {
- }
- if (url != null) {
- urls.put(fn, url);
- // If loading a JAR file, then also cache the manifest
- if (file.isFile()) {
- mans.put(fn, loadManifest(fn));
- }
- }
- }
- // Convert to "."-separated package name
- name = name.substring(0, name.length() - 1).replace('/', '.');
- Package pkg;
- Manifest man = mans.get(fn);
- if (man != null) {
- pkg = new Package(name, man, url, null);
- } else {
- pkg = new Package(name, null, null, null,
- null, null, null, null, null);
- }
- pkgs.put(name, pkg);
- return pkg;
- }
- });
- }
-
- /*
- * Returns the Manifest for the specified JAR file name.
- */
- private static Manifest loadManifest(String fn) {
- try (FileInputStream fis = new FileInputStream(fn);
- JarInputStream jis = new JarInputStream(fis, false))
- {
- return jis.getManifest();
- } catch (IOException e) {
- return null;
- }
- }
-
- // The map of loaded system packages
- private static Map<String, Package> pkgs = new HashMap<>(31);
-
- // Maps each directory or zip file name to its corresponding url
- private static Map<String, URL> urls = new HashMap<>(10);
-
- // Maps each code source url for a jar file to its manifest
- private static Map<String, Manifest> mans = new HashMap<>(10);
-
- private static native String getSystemPackage0(String name);
- private static native String[] getSystemPackages0();
-
- /*
- * Private storage for the package name and attributes.
- */
- private final String pkgName;
- private final String specTitle;
- private final String specVersion;
- private final String specVendor;
- private final String implTitle;
- private final String implVersion;
- private final String implVendor;
- private final URL sealBase;
- private transient final ClassLoader loader;
- private transient Class packageInfo;
-}
diff --git a/openjdk/java/lang/ProcessImpl.java b/openjdk/java/lang/ProcessImpl.java
deleted file mode 100644
index 0624dc17..00000000
--- a/openjdk/java/lang/ProcessImpl.java
+++ /dev/null
@@ -1,834 +0,0 @@
-/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*IKVM*/
-/*
- * Modified for IKVM by Jeroen Frijters
- */
-
-package java.lang;
-
-import java.io.IOException;
-import java.io.File;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileDescriptor;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.lang.ProcessBuilder.Redirect;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import cli.System.AsyncCallback;
-import cli.System.IAsyncResult;
-import cli.System.Diagnostics.ProcessStartInfo;
-import cli.System.EventArgs;
-import cli.System.EventHandler;
-import cli.System.IO.FileAccess;
-import cli.System.IO.FileShare;
-import cli.System.IO.FileMode;
-import cli.System.IO.FileOptions;
-import cli.System.IO.FileStream;
-import cli.System.IO.Stream;
-import cli.System.Security.AccessControl.FileSystemRights;
-
-/* This class is for the exclusive use of ProcessBuilder.start() to
- * create new processes.
- *
- * @author Martin Buchholz
- * @since 1.5
- */
-
-final class ProcessImpl extends Process {
- static class fdAccess {
- static Stream getHandle(FileDescriptor fd) {
- return fd.getStream();
- }
- }
-
- /**
- * Open a file for writing. If {@code append} is {@code true} then the file
- * is opened for atomic append directly and a FileOutputStream constructed
- * with the resulting handle. This is because a FileOutputStream created
- * to append to a file does not open the file in a manner that guarantees
- * that writes by the child process will be atomic.
- */
- private static FileOutputStream newFileOutputStream(File f, boolean append)
- throws IOException
- {
- if (append) {
- String path = f.getPath();
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkWrite(path);
- final FileDescriptor fd = openForAtomicAppend(path);
- return AccessController.doPrivileged(
- new PrivilegedAction<FileOutputStream>() {
- public FileOutputStream run() {
- return new FileOutputStream(fd);
- }
- }
- );
- } else {
- return new FileOutputStream(f);
- }
- }
-
- // System-dependent portion of ProcessBuilder.start()
- static Process start(String cmdarray[],
- java.util.Map<String,String> environment,
- String dir,
- ProcessBuilder.Redirect[] redirects,
- boolean redirectErrorStream)
- throws IOException
- {
- FileInputStream f0 = null;
- FileOutputStream f1 = null;
- FileOutputStream f2 = null;
-
- try {
- Stream[] stdHandles;
- if (redirects == null) {
- stdHandles = new Stream[3];
- } else {
- stdHandles = new Stream[3];
-
- if (redirects[0] == Redirect.PIPE)
- stdHandles[0] = null;
- else if (redirects[0] == Redirect.INHERIT)
- stdHandles[0] = fdAccess.getHandle(FileDescriptor.in);
- else {
- f0 = new FileInputStream(redirects[0].file());
- stdHandles[0] = fdAccess.getHandle(f0.getFD());
- }
-
- if (redirects[1] == Redirect.PIPE)
- stdHandles[1] = null;
- else if (redirects[1] == Redirect.INHERIT)
- stdHandles[1] = fdAccess.getHandle(FileDescriptor.out);
- else {
- f1 = newFileOutputStream(redirects[1].file(),
- redirects[1].append());
- stdHandles[1] = fdAccess.getHandle(f1.getFD());
- }
-
- if (redirects[2] == Redirect.PIPE)
- stdHandles[2] = null;
- else if (redirects[2] == Redirect.INHERIT)
- stdHandles[2] = fdAccess.getHandle(FileDescriptor.err);
- else {
- f2 = newFileOutputStream(redirects[2].file(),
- redirects[2].append());
- stdHandles[2] = fdAccess.getHandle(f2.getFD());
- }
- }
-
- return new ProcessImpl(cmdarray, environment, dir,
- stdHandles, redirectErrorStream);
- } catch (Throwable t) {
- if (f0 != null)
- f0.close();
- if (f1 != null)
- f1.close();
- if (f2 != null)
- f2.close();
- throw t;
- } finally {
- // HACK prevent the File[In|Out]putStream objects from closing the streams
- // (the System.IO.FileStream will eventually be closed explicitly or by its finalizer)
- if (f0 != null)
- cli.System.GC.SuppressFinalize(f0);
- if (f1 != null)
- cli.System.GC.SuppressFinalize(f1);
- if (f2 != null)
- cli.System.GC.SuppressFinalize(f2);
- }
-
- }
-
- private static class LazyPattern {
- // Escape-support version:
- // "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)";
- private static final Pattern PATTERN =
- Pattern.compile("[^\\s\"]+|\"[^\"]*\"");
- };
-
- /* Parses the command string parameter into the executable name and
- * program arguments.
- *
- * The command string is broken into tokens. The token separator is a space
- * or quota character. The space inside quotation is not a token separator.
- * There are no escape sequences.
- */
- private static String[] getTokensFromCommand(String command) {
- ArrayList<String> matchList = new ArrayList<>(8);
- Matcher regexMatcher = LazyPattern.PATTERN.matcher(command);
- while (regexMatcher.find())
- matchList.add(regexMatcher.group());
- return matchList.toArray(new String[matchList.size()]);
- }
-
- private static final int VERIFICATION_CMD_BAT = 0;
- private static final int VERIFICATION_WIN32 = 1;
- private static final int VERIFICATION_LEGACY = 2;
- private static final char ESCAPE_VERIFICATION[][] = {
- // We guarantee the only command file execution for implicit [cmd.exe] run.
- // http://technet.microsoft.com/en-us/library/bb490954.aspx
- {' ', '\t', '<', '>', '&', '|', '^'},
-
- {' ', '\t', '<', '>'},
- {' ', '\t'}
- };
-
- private static String createCommandLine(int verificationType,
- final String executablePath,
- final String cmd[])
- {
- StringBuilder cmdbuf = new StringBuilder(80);
-
- cmdbuf.append(executablePath);
-
- for (int i = 1; i < cmd.length; ++i) {
- cmdbuf.append(' ');
- String s = cmd[i];
- if (needsEscaping(verificationType, s)) {
- cmdbuf.append('"').append(s);
-
- // The code protects the [java.exe] and console command line
- // parser, that interprets the [\"] combination as an escape
- // sequence for the ["] char.
- // http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
- //
- // If the argument is an FS path, doubling of the tail [\]
- // char is not a problem for non-console applications.
- //
- // The [\"] sequence is not an escape sequence for the [cmd.exe]
- // command line parser. The case of the [""] tail escape
- // sequence could not be realized due to the argument validation
- // procedure.
- if ((verificationType != VERIFICATION_CMD_BAT) && s.endsWith("\\")) {
- cmdbuf.append('\\');
- }
- cmdbuf.append('"');
- } else {
- cmdbuf.append(s);
- }
- }
- return cmdbuf.toString();
- }
-
- private static boolean isQuoted(boolean noQuotesInside, String arg,
- String errorMessage) {
- int lastPos = arg.length() - 1;
- if (lastPos >=1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
- // The argument has already been quoted.
- if (noQuotesInside) {
- if (arg.indexOf('"', 1) != lastPos) {
- // There is ["] inside.
- throw new IllegalArgumentException(errorMessage);
- }
- }
- return true;
- }
- if (noQuotesInside) {
- if (arg.indexOf('"') >= 0) {
- // There is ["] inside.
- throw new IllegalArgumentException(errorMessage);
- }
- }
- return false;
- }
-
- private static boolean needsEscaping(int verificationType, String arg) {
- // Switch off MS heuristic for internal ["].
- // Please, use the explicit [cmd.exe] call
- // if you need the internal ["].
- // Example: "cmd.exe", "/C", "Extended_MS_Syntax"
-
- // For [.exe] or [.com] file the unpaired/internal ["]
- // in the argument is not a problem.
- boolean argIsQuoted = isQuoted(
- (verificationType == VERIFICATION_CMD_BAT),
- arg, "Argument has embedded quote, use the explicit CMD.EXE call.");
-
- if (!argIsQuoted) {
- char testEscape[] = ESCAPE_VERIFICATION[verificationType];
- for (int i = 0; i < testEscape.length; ++i) {
- if (arg.indexOf(testEscape[i]) >= 0) {
- return true;
- }
- }
- }
- return false;
- }
-
- private static String getExecutablePath(String path)
- throws IOException
- {
- boolean pathIsQuoted = isQuoted(true, path,
- "Executable name has embedded quote, split the arguments");
-
- // Win32 CreateProcess requires path to be normalized
- File fileToRun = new File(pathIsQuoted
- ? path.substring(1, path.length() - 1)
- : path);
-
- // From the [CreateProcess] function documentation:
- //
- // "If the file name does not contain an extension, .exe is appended.
- // Therefore, if the file name extension is .com, this parameter
- // must include the .com extension. If the file name ends in
- // a period (.) with no extension, or if the file name contains a path,
- // .exe is not appended."
- //
- // "If the file name !does not contain a directory path!,
- // the system searches for the executable file in the following
- // sequence:..."
- //
- // In practice ANY non-existent path is extended by [.exe] extension
- // in the [CreateProcess] funcion with the only exception:
- // the path ends by (.)
-
- return fileToRun.getPath();
- }
-
-
- private boolean isShellFile(String executablePath) {
- String upPath = executablePath.toUpperCase();
- return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
- }
-
- private String quoteString(String arg) {
- StringBuilder argbuf = new StringBuilder(arg.length() + 2);
- return argbuf.append('"').append(arg).append('"').toString();
- }
-
-
- private cli.System.Diagnostics.Process handle;
- private OutputStream stdin_stream;
- private InputStream stdout_stream;
- private InputStream stderr_stream;
-
- private ProcessImpl(String cmd[],
- final java.util.Map<String,String> envblock,
- final String path,
- final Stream[] stdHandles,
- final boolean redirectErrorStream)
- throws IOException
- {
- String cmdstr;
- SecurityManager security = System.getSecurityManager();
- boolean allowAmbiguousCommands = false;
- if (security == null) {
- allowAmbiguousCommands = true;
- String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
- if (value != null)
- allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
- }
- if (allowAmbiguousCommands) {
- // Legacy mode.
-
- // Normalize path if possible.
- String executablePath = new File(cmd[0]).getPath();
-
- // No worry about internal, unpaired ["], and redirection/piping.
- if (needsEscaping(VERIFICATION_LEGACY, executablePath) )
- executablePath = quoteString(executablePath);
-
- cmdstr = createCommandLine(
- //legacy mode doesn't worry about extended verification
- VERIFICATION_LEGACY,
- executablePath,
- cmd);
- } else {
- String executablePath;
- try {
- executablePath = getExecutablePath(cmd[0]);
- } catch (IllegalArgumentException e) {
- // Workaround for the calls like
- // Runtime.getRuntime().exec("\"C:\\Program Files\\foo\" bar")
-
- // No chance to avoid CMD/BAT injection, except to do the work
- // right from the beginning. Otherwise we have too many corner
- // cases from
- // Runtime.getRuntime().exec(String[] cmd [, ...])
- // calls with internal ["] and escape sequences.
-
- // Restore original command line.
- StringBuilder join = new StringBuilder();
- // terminal space in command line is ok
- for (String s : cmd)
- join.append(s).append(' ');
-
- // Parse the command line again.
- cmd = getTokensFromCommand(join.toString());
- executablePath = getExecutablePath(cmd[0]);
-
- // Check new executable name once more
- if (security != null)
- security.checkExec(executablePath);
- }
-
- // Quotation protects from interpretation of the [path] argument as
- // start of longer path with spaces. Quotation has no influence to
- // [.exe] extension heuristic.
- cmdstr = createCommandLine(
- // We need the extended verification procedure for CMD files.
- isShellFile(executablePath)
- ? VERIFICATION_CMD_BAT
- : VERIFICATION_WIN32,
- quoteString(executablePath),
- cmd);
- }
-
- handle = create(cmdstr, envblock, path,
- stdHandles, redirectErrorStream);
-
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- if (stdHandles[0] == null)
- stdin_stream = ProcessBuilder.NullOutputStream.INSTANCE;
- else {
- FileDescriptor stdin_fd = FileDescriptor.fromStream(stdHandles[0]);
- stdin_stream = new BufferedOutputStream(
- new FileOutputStream(stdin_fd));
- }
-
- if (stdHandles[1] == null)
- stdout_stream = ProcessBuilder.NullInputStream.INSTANCE;
- else {
- FileDescriptor stdout_fd = FileDescriptor.fromStream(stdHandles[1]);
- stdout_stream = new BufferedInputStream(
- new FileInputStream(stdout_fd));
- }
-
- if (stdHandles[2] == null)
- stderr_stream = ProcessBuilder.NullInputStream.INSTANCE;
- else {
- FileDescriptor stderr_fd = FileDescriptor.fromStream(stdHandles[2]);
- stderr_stream = new FileInputStream(stderr_fd);
- }
-
- return null; }});
- }
-
- private static native String mapVfsExecutable(String path);
-
- public OutputStream getOutputStream() {
- return stdin_stream;
- }
-
- public InputStream getInputStream() {
- return stdout_stream;
- }
-
- public InputStream getErrorStream() {
- return stderr_stream;
- }
-
- public int exitValue() {
- if (!handle.get_HasExited())
- throw new IllegalThreadStateException("process has not exited");
- return handle.get_ExitCode();
- }
-
- public int waitFor() throws InterruptedException {
- waitForInterruptibly(handle);
- if (Thread.interrupted())
- throw new InterruptedException();
- return exitValue();
- }
-
- private static void waitForInterruptibly(cli.System.Diagnostics.Process handle) throws InterruptedException {
- // to be interruptable we have to use polling
- // (on .NET 2.0 WaitForExit is actually interruptible, but this isn't documented)
- Thread current = Thread.currentThread();
- while (!current.isInterrupted() && !handle.WaitForExit(100))
- ;
- }
-
- @Override
- public boolean waitFor(long timeout, TimeUnit unit)
- throws InterruptedException
- {
- if (handle.get_HasExited()) return true;
- if (timeout <= 0) return false;
-
- long msTimeout = unit.toMillis(timeout);
-
- waitForTimeoutInterruptibly(handle, msTimeout);
- if (Thread.interrupted())
- throw new InterruptedException();
- return handle.get_HasExited();
- }
-
- private static void waitForTimeoutInterruptibly(
- cli.System.Diagnostics.Process handle, long timeout) {
- long now = System.currentTimeMillis();
- long exp = now + timeout;
- if (exp < now) {
- // if we overflowed, just wait for a really long time
- exp = Long.MAX_VALUE;
- }
- Thread current = Thread.currentThread();
- for (;;) {
- if (current.isInterrupted()) {
- return;
- }
- // wait for a maximum of 100 ms to be interruptible
- if (handle.WaitForExit((int)Math.min(100, exp - now))) {
- return;
- }
- now = System.currentTimeMillis();
- if (now >= exp) {
- return;
- }
- }
- }
-
- public void destroy() { terminateProcess(handle); }
-
- @Override
- public Process destroyForcibly() {
- destroy();
- return this;
- }
-
- private static void terminateProcess(cli.System.Diagnostics.Process handle) {
- try {
- if (false) throw new cli.System.ComponentModel.Win32Exception();
- if (false) throw new cli.System.InvalidOperationException();
- handle.Kill();
- } catch (cli.System.ComponentModel.Win32Exception _) {
- } catch (cli.System.InvalidOperationException _) {
- }
- }
-
- @Override
- public boolean isAlive() {
- return isProcessAlive(handle);
- }
-
- private static boolean isProcessAlive(cli.System.Diagnostics.Process handle) {
- return !handle.get_HasExited();
- }
-
- /**
- * Create a process using the win32 function CreateProcess.
- * The method is synchronized due to MS kb315939 problem.
- * All native handles should restore the inherit flag at the end of call.
- *
- * @param cmdstr the Windows command line
- * @param envblock NUL-separated, double-NUL-terminated list of
- * environment strings in VAR=VALUE form
- * @param dir the working directory of the process, or null if
- * inheriting the current directory from the parent process
- * @param stdHandles array of windows HANDLEs. Indexes 0, 1, and
- * 2 correspond to standard input, standard output and
- * standard error, respectively. On input, a value of -1
- * means to create a pipe to connect child and parent
- * processes. On output, a value which is not -1 is the
- * parent pipe handle corresponding to the pipe which has
- * been created. An element of this array is -1 on input
- * if and only if it is <em>not</em> -1 on output.
- * @param redirectErrorStream redirectErrorStream attribute
- * @return the native subprocess HANDLE returned by CreateProcess
- */
- private static cli.System.Diagnostics.Process create(String cmdstr,
- java.util.Map<String,String> envblock,
- String dir,
- Stream[] stdHandles,
- boolean redirectErrorStream)
- throws IOException {
-
- int programEnd = parseCommandString(cmdstr);
- int argumentsStart = programEnd;
- if (cmdstr.length() > argumentsStart && cmdstr.charAt(argumentsStart) == ' ') {
- argumentsStart++;
- }
-
- String fileName = cmdstr.substring(0, programEnd);
- ProcessStartInfo si = new ProcessStartInfo(mapVfsExecutable(fileName), cmdstr.substring(argumentsStart));
- si.set_UseShellExecute(false);
- si.set_RedirectStandardError(true);
- si.set_RedirectStandardOutput(true);
- si.set_RedirectStandardInput(true);
- si.set_CreateNoWindow(true);
- if (dir != null) {
- si.set_WorkingDirectory(dir);
- }
- if (envblock != null) {
- si.get_EnvironmentVariables().Clear();
- for (String key : envblock.keySet()) {
- si.get_EnvironmentVariables().set_Item(key, envblock.get(key));
- }
- }
-
- cli.System.Diagnostics.Process proc;
- try {
- if (false) throw new cli.System.ComponentModel.Win32Exception();
- if (false) throw new cli.System.InvalidOperationException();
- proc = cli.System.Diagnostics.Process.Start(si);
- } catch (cli.System.ComponentModel.Win32Exception x1) {
- throw new IOException(x1.getMessage());
- } catch (cli.System.InvalidOperationException x2) {
- throw new IOException(x2.getMessage());
- }
-
- // if any of the handles is redirected to/from a file,
- // we need to close the files as soon as the process exits
- if (stdHandles[0] instanceof FileStream
- || stdHandles[1] instanceof FileStream
- || stdHandles[2] instanceof FileStream) {
- final Stream s0 = stdHandles[0];
- final Stream s1 = stdHandles[1];
- final Stream s2 = stdHandles[2];
- proc.set_EnableRaisingEvents(true);
- proc.add_Exited(new EventHandler(new EventHandler.Method() {
- public void Invoke(Object sender, EventArgs e) {
- if (s0 instanceof FileStream)
- s0.Close();
- if (s1 instanceof FileStream)
- s1.Close();
- if (s2 instanceof FileStream)
- s2.Close();
- }
- }));
- }
-
- Stream stdin = proc.get_StandardInput().get_BaseStream();
- Stream stdout = proc.get_StandardOutput().get_BaseStream();
- Stream stderr = proc.get_StandardError().get_BaseStream();
-
- if (stdHandles[0] != null) {
- connectPipe(stdHandles[0], stdin);
- stdHandles[0] = null;
- } else {
- stdHandles[0] = stdin;
- }
-
- Stream stdoutDrain = null;
- if (stdHandles[1] != null) {
- stdoutDrain = stdHandles[1];
- connectPipe(stdout, stdoutDrain);
- stdHandles[1] = null;
- } else if (redirectErrorStream) {
- PipeStream pipe = new PipeStream();
- connectPipe(stdout, pipe);
- connectPipe(stderr, pipe);
- stdHandles[1] = pipe;
- } else {
- stdHandles[1] = stdout;
- }
-
- if (redirectErrorStream) {
- if (stdoutDrain != null) {
- connectPipe(stderr, stdoutDrain);
- }
- stdHandles[2] = null;
- } else if (stdHandles[2] != null) {
- connectPipe(stderr, stdHandles[2]);
- stdHandles[2] = null;
- } else {
- stdHandles[2] = stderr;
- }
-
- return proc;
- }
-
- private static final class PipeStream extends Stream
- {
- private final byte[] buf = new byte[4096];
- private int pos;
- private int users = 2;
-
- @Override
- public synchronized int Read(byte[] buffer, int offset, int count)
- {
- if (count == 0)
- {
- return 0;
- }
- while (pos == 0)
- {
- try
- {
- wait();
- }
- catch (InterruptedException _) { }
- }
- if (pos == -1)
- {
- return 0;
- }
- count = Math.min(count, pos);
- System.arraycopy(buf, 0, buffer, offset, count);
- pos -= count;
- System.arraycopy(buf, count, buf, 0, pos);
- notifyAll();
- return count;
- }
-
- @Override
- public synchronized void Write(byte[] buffer, int offset, int count)
- {
- while (buf.length - pos < count)
- {
- try
- {
- wait();
- }
- catch (InterruptedException _) { }
- }
- System.arraycopy(buffer, offset, buf, pos, count);
- pos += count;
- notifyAll();
- }
-
- @Override
- public synchronized void Close()
- {
- if (--users == 0)
- {
- pos = -1;
- notifyAll();
- }
- }
-
- @Override
- public boolean get_CanRead()
- {
- return true;
- }
-
- @Override
- public boolean get_CanSeek()
- {
- return false;
- }
-
- @Override
- public boolean get_CanWrite()
- {
- return true;
- }
-
- @Override
- public void Flush()
- {
- }
-
- @Override
- public long get_Length()
- {
- ikvm.runtime.Util.throwException(new cli.System.NotSupportedException());
- return 0;
- }
-
- @Override
- public long get_Position()
- {
- ikvm.runtime.Util.throwException(new cli.System.NotSupportedException());
- return 0;
- }
-
- @Override
- public long Seek(long offset, cli.System.IO.SeekOrigin origin)
- {
- ikvm.runtime.Util.throwException(new cli.System.NotSupportedException());
- return 0;
- }
-
- @Override
- public void SetLength(long value)
- {
- ikvm.runtime.Util.throwException(new cli.System.NotSupportedException());
- }
-
- @Override
- public void set_Position(long position)
- {
- ikvm.runtime.Util.throwException(new cli.System.NotSupportedException());
- }
- }
-
- private static native int parseCommandString(String cmdstr);
-
- /**
- * Opens a file for atomic append. The file is created if it doesn't
- * already exist.
- *
- * @param file the file to open or create
- * @return the native HANDLE
- */
- private static FileDescriptor openForAtomicAppend(String path)
- throws IOException {
- try {
- if (false) throw new cli.System.ArgumentException();
- if (false) throw new cli.System.IO.IOException();
- if (false) throw new cli.System.Security.SecurityException();
- if (false) throw new cli.System.UnauthorizedAccessException();
- return FileDescriptor.fromStream(new FileStream(path, FileMode.wrap(FileMode.Append), FileSystemRights.wrap(FileSystemRights.AppendData), FileShare.wrap(FileShare.ReadWrite), 1, FileOptions.wrap(FileOptions.None)));
- } catch (cli.System.ArgumentException x) {
- throw new IOException(x.getMessage());
- } catch (cli.System.IO.IOException x) {
- throw new IOException(x.getMessage());
- } catch (cli.System.Security.SecurityException x) {
- throw new IOException(x.getMessage());
- } catch (cli.System.UnauthorizedAccessException x) {
- throw new IOException(x.getMessage());
- }
- }
-
- private static void connectPipe(final Stream in, final Stream out) {
- final byte[] buf = new byte[4096];
- final AsyncCallback[] callback = new AsyncCallback[1];
- callback[0] = new AsyncCallback(new AsyncCallback.Method() {
- public void Invoke(IAsyncResult ar) {
- try {
- int count = in.EndRead(ar);
- if (count > 0) {
- out.Write(buf, 0, count);
- out.Flush();
- in.BeginRead(buf, 0, buf.length, callback[0], null);
- } else {
- out.Close();
- }
- } catch (Throwable _) {
- }
- }
- });
- try {
- in.BeginRead(buf, 0, buf.length, callback[0], null);
- } catch (Throwable _) {
- }
- }
-}
diff --git a/openjdk/java/lang/PropertyConstants.java.in b/openjdk/java/lang/PropertyConstants.java.in
deleted file mode 100644
index 69e7796f..00000000
--- a/openjdk/java/lang/PropertyConstants.java.in
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- Copyright (C) 2007, 2009 Jeroen Frijters
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jeroen Frijters
- jeroen@frijters.net
-
-*/
-package java.lang;
-
-interface PropertyConstants
-{
- String awt_toolkit = "ikvm.awt.NetToolkit, @AWTASSEMBLY@";
- String java_awt_graphicsenv = "ikvm.awt.NetGraphicsEnvironment, @AWTASSEMBLY@";
- String java_vm_version = "@VERSION@";
- String java_runtime_version = "@VERSION@";
- String openjdk_version = "@OPENJDK_VERSION@";
-}
diff --git a/openjdk/java/lang/Shutdown.java b/openjdk/java/lang/Shutdown.java
deleted file mode 100644
index 947f0e39..00000000
--- a/openjdk/java/lang/Shutdown.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang;
-
-import cli.System.AppDomain;
-import cli.System.EventArgs;
-import cli.System.EventHandler;
-import cli.System.Threading.Monitor;
-
-/**
- * Package-private utility class containing data structures and logic
- * governing the virtual-machine shutdown sequence.
- *
- * @author Mark Reinhold
- * @since 1.3
- */
-
-class Shutdown {
-
- /* Shutdown state */
- private static final int RUNNING = 0;
- private static final int HOOKS = 1;
- private static final int FINALIZERS = 2;
- private static int state = RUNNING;
-
- /* Should we run all finalizers upon exit? */
- static volatile boolean runFinalizersOnExit = false;
-
- // The system shutdown hooks are registered with a predefined slot.
- // The list of shutdown hooks is as follows:
- // (0) Console restore hook
- // (1) Application hooks
- // (2) DeleteOnExit hook
- private static final int MAX_SYSTEM_HOOKS = 10;
- private static final Runnable[] hooks = new Runnable[MAX_SYSTEM_HOOKS];
-
- // the index of the currently running shutdown hook to the hooks array
- private static int currentRunningHook = 0;
-
- // [IKVM] have we registered the AppDomain.ProcessExit event handler?
- private static boolean registeredProcessExit;
-
- /* The preceding static fields are protected by this lock */
- private static class Lock { };
- private static Object lock = new Lock();
-
- /* Lock object for the native halt method */
- private static Object haltLock = new Lock();
-
- /* Invoked by Runtime.runFinalizersOnExit */
- static void setRunFinalizersOnExit(boolean run) {
- synchronized (lock) {
- runFinalizersOnExit = run;
- }
- }
-
- private static void registerProcessExit() {
- try {
- // MONOBUG Mono doesn't support starting a new thread during ProcessExit
- // (and application shutdown hooks are based on threads)
- // see https://bugzilla.xamarin.com/show_bug.cgi?id=5650
- if (!ikvm.internal.Util.MONO) {
- // AppDomain.ProcessExit has a LinkDemand, so we have to have a separate method
- registerShutdownHook();
- if (false) throw new cli.System.Security.SecurityException();
- }
- }
- catch (cli.System.Security.SecurityException _) {
- }
- }
-
- private static void registerShutdownHook()
- {
- AppDomain.get_CurrentDomain().add_ProcessExit(new EventHandler(new EventHandler.Method() {
- public void Invoke(Object sender, EventArgs e) {
- shutdown();
- }
- }));
- }
-
- /**
- * Add a new shutdown hook. Checks the shutdown state and the hook itself,
- * but does not do any security checks.
- *
- * The registerShutdownInProgress parameter should be false except
- * registering the DeleteOnExitHook since the first file may
- * be added to the delete on exit list by the application shutdown
- * hooks.
- *
- * @params slot the slot in the shutdown hook array, whose element
- * will be invoked in order during shutdown
- * @params registerShutdownInProgress true to allow the hook
- * to be registered even if the shutdown is in progress.
- * @params hook the hook to be registered
- *
- * @throw IllegalStateException
- * if registerShutdownInProgress is false and shutdown is in progress; or
- * if registerShutdownInProgress is true and the shutdown process
- * already passes the given slot
- */
- static void add(int slot, boolean registerShutdownInProgress, Runnable hook) {
- synchronized (lock) {
- if (hooks[slot] != null)
- throw new InternalError("Shutdown hook at slot " + slot + " already registered");
-
- if (!registerShutdownInProgress) {
- if (state > RUNNING)
- throw new IllegalStateException("Shutdown in progress");
- } else {
- if (state > HOOKS || (state == HOOKS && slot <= currentRunningHook))
- throw new IllegalStateException("Shutdown in progress");
- }
-
- if (!registeredProcessExit) {
- registeredProcessExit = true;
- registerProcessExit();
- }
-
- hooks[slot] = hook;
- }
- }
-
- /* Run all registered shutdown hooks
- */
- private static void runHooks() {
- for (int i=0; i < MAX_SYSTEM_HOOKS; i++) {
- try {
- Runnable hook;
- synchronized (lock) {
- // acquire the lock to make sure the hook registered during
- // shutdown is visible here.
- currentRunningHook = i;
- hook = hooks[i];
- }
- if (hook != null) hook.run();
- } catch(Throwable t) {
- if (t instanceof ThreadDeath) {
- ThreadDeath td = (ThreadDeath)t;
- throw td;
- }
- }
- }
- }
-
- /* The halt method is synchronized on the halt lock
- * to avoid corruption of the delete-on-shutdown file list.
- * It invokes the true native halt method.
- */
- static void halt(int status) {
- synchronized (haltLock) {
- halt0(status);
- }
- }
-
- static void halt0(int status) {
- cli.System.Environment.Exit(status);
- }
-
- /* Wormhole for invoking java.lang.ref.Finalizer.runAllFinalizers */
- private static void runAllFinalizers() { /* [IKVM] Don't need to do anything here */ }
-
-
- /* The actual shutdown sequence is defined here.
- *
- * If it weren't for runFinalizersOnExit, this would be simple -- we'd just
- * run the hooks and then halt. Instead we need to keep track of whether
- * we're running hooks or finalizers. In the latter case a finalizer could
- * invoke exit(1) to cause immediate termination, while in the former case
- * any further invocations of exit(n), for any n, simply stall. Note that
- * if on-exit finalizers are enabled they're run iff the shutdown is
- * initiated by an exit(0); they're never run on exit(n) for n != 0 or in
- * response to SIGINT, SIGTERM, etc.
- */
- private static void sequence() {
- synchronized (lock) {
- /* Guard against the possibility of a daemon thread invoking exit
- * after DestroyJavaVM initiates the shutdown sequence
- */
- if (state != HOOKS) return;
- }
- runHooks();
- boolean rfoe;
- synchronized (lock) {
- state = FINALIZERS;
- rfoe = runFinalizersOnExit;
- }
- if (rfoe) runAllFinalizers();
- }
-
-
- /* Invoked by Runtime.exit, which does all the security checks.
- * Also invoked by handlers for system-provided termination events,
- * which should pass a nonzero status code.
- */
- static void exit(int status) {
- boolean runMoreFinalizers = false;
- synchronized (lock) {
- if (status != 0) runFinalizersOnExit = false;
- switch (state) {
- case RUNNING: /* Initiate shutdown */
- state = HOOKS;
- break;
- case HOOKS: /* Stall and halt */
- break;
- case FINALIZERS:
- if (status != 0) {
- /* Halt immediately on nonzero status */
- halt(status);
- } else {
- /* Compatibility with old behavior:
- * Run more finalizers and then halt
- */
- runMoreFinalizers = runFinalizersOnExit;
- }
- break;
- }
- }
- if (runMoreFinalizers) {
- runAllFinalizers();
- halt(status);
- }
- synchronized (Shutdown.class) {
- /* Synchronize on the class object, causing any other thread
- * that attempts to initiate shutdown to stall indefinitely
- */
- sequence();
- halt(status);
- }
- }
-
-
- /* Invoked by the JNI DestroyJavaVM procedure when the last non-daemon
- * thread has finished. Unlike the exit method, this method does not
- * actually halt the VM.
- */
- static void shutdown() {
- synchronized (lock) {
- switch (state) {
- case RUNNING: /* Initiate shutdown */
- state = HOOKS;
- break;
- case HOOKS: /* Stall and then return */
- case FINALIZERS:
- break;
- }
- }
- // [IKVM] We don't block here, because we're being called
- // from the AppDomain.ProcessExit event and we don't want to
- // deadlock with the thread that called exit.
- // Note that our JNI DestroyJavaVM implementation doesn't
- // call this method.
- if (Monitor.TryEnter(Shutdown.class)) {
- try {
- sequence();
- } finally {
- Monitor.Exit(Shutdown.class);
- }
- }
- }
-
-}
diff --git a/openjdk/java/lang/StringHelper.java b/openjdk/java/lang/StringHelper.java
deleted file mode 100644
index 98f7816c..00000000
--- a/openjdk/java/lang/StringHelper.java
+++ /dev/null
@@ -1,2592 +0,0 @@
-/*
- * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.lang;
-
-import java.io.ObjectStreamField;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Formatter;
-import java.util.Locale;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-/**
- * The <code>String</code> class represents character strings. All
- * string literals in Java programs, such as <code>"abc"</code>, are
- * implemented as instances of this class.
- * <p>
- * Strings are constant; their values cannot be changed after they
- * are created. String buffers support mutable strings.
- * Because String objects are immutable they can be shared. For example:
- * <p><blockquote><pre>
- * String str = "abc";
- * </pre></blockquote><p>
- * is equivalent to:
- * <p><blockquote><pre>
- * char data[] = {'a', 'b', 'c'};
- * String str = new String(data);
- * </pre></blockquote><p>
- * Here are some more examples of how strings can be used:
- * <p><blockquote><pre>
- * System.out.println("abc");
- * String cde = "cde";
- * System.out.println("abc" + cde);
- * String c = "abc".substring(2,3);
- * String d = cde.substring(1, 2);
- * </pre></blockquote>
- * <p>
- * The class <code>String</code> includes methods for examining
- * individual characters of the sequence, for comparing strings, for
- * searching strings, for extracting substrings, and for creating a
- * copy of a string with all characters translated to uppercase or to
- * lowercase. Case mapping is based on the Unicode Standard version
- * specified by the {@link java.lang.Character Character} class.
- * <p>
- * The Java language provides special support for the string
- * concatenation operator (&nbsp;+&nbsp;), and for conversion of
- * other objects to strings. String concatenation is implemented
- * through the <code>StringBuilder</code>(or <code>StringBuffer</code>)
- * class and its <code>append</code> method.
- * String conversions are implemented through the method
- * <code>toString</code>, defined by <code>Object</code> and
- * inherited by all classes in Java. For additional information on
- * string concatenation and conversion, see Gosling, Joy, and Steele,
- * <i>The Java Language Specification</i>.
- *
- * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
- * or method in this class will cause a {@link NullPointerException} to be
- * thrown.
- *
- * <p>A <code>String</code> represents a string in the UTF-16 format
- * in which <em>supplementary characters</em> are represented by <em>surrogate
- * pairs</em> (see the section <a href="Character.html#unicode">Unicode
- * Character Representations</a> in the <code>Character</code> class for
- * more information).
- * Index values refer to <code>char</code> code units, so a supplementary
- * character uses two positions in a <code>String</code>.
- * <p>The <code>String</code> class provides methods for dealing with
- * Unicode code points (i.e., characters), in addition to those for
- * dealing with Unicode code units (i.e., <code>char</code> values).
- *
- * @author Lee Boynton
- * @author Arthur van Hoff
- * @author Martin Buchholz
- * @author Ulf Zibis
- * @see java.lang.Object#toString()
- * @see java.lang.StringBuffer
- * @see java.lang.StringBuilder
- * @see java.nio.charset.Charset
- * @since JDK1.0
- */
-
-final class StringHelper
-{
- /**
- * Allocates a new {@code String} that contains characters from a subarray
- * of the <a href="Character.html#unicode">Unicode code point</a> array
- * argument. The {@code offset} argument is the index of the first code
- * point of the subarray and the {@code count} argument specifies the
- * length of the subarray. The contents of the subarray are converted to
- * {@code char}s; subsequent modification of the {@code int} array does not
- * affect the newly created string.
- *
- * @param codePoints
- * Array that is the source of Unicode code points
- *
- * @param offset
- * The initial offset
- *
- * @param count
- * The length
- *
- * @throws IllegalArgumentException
- * If any invalid Unicode code point is found in {@code
- * codePoints}
- *
- * @throws IndexOutOfBoundsException
- * If the {@code offset} and {@code count} arguments index
- * characters outside the bounds of the {@code codePoints} array
- *
- * @since 1.5
- */
- static String NewString(int[] codePoints, int offset, int count) {
- if (offset < 0) {
- throw new StringIndexOutOfBoundsException(offset);
- }
- if (count < 0) {
- throw new StringIndexOutOfBoundsException(count);
- }
- // Note: offset or count might be near -1>>>1.
- if (offset > codePoints.length - count) {
- throw new StringIndexOutOfBoundsException(offset + count);
- }
-
- final int end = offset + count;
-
- // Pass 1: Compute precise size of char[]
- int n = count;
- for (int i = offset; i < end; i++) {
- int c = codePoints[i];
- if (Character.isBmpCodePoint(c))
- continue;
- else if (Character.isValidCodePoint(c))
- n++;
- else throw new IllegalArgumentException(Integer.toString(c));
- }
-
- // Pass 2: Allocate and fill in char[]
- final char[] v = new char[n];
-
- for (int i = offset, j = 0; i < end; i++, j++) {
- int c = codePoints[i];
- if (Character.isBmpCodePoint(c))
- v[j] = (char)c;
- else
- Character.toSurrogates(c, v, j++);
- }
-
- return new String(v);
- }
-
- /**
- * Allocates a new {@code String} constructed from a subarray of an array
- * of 8-bit integer values.
- *
- * <p> The {@code offset} argument is the index of the first byte of the
- * subarray, and the {@code count} argument specifies the length of the
- * subarray.
- *
- * <p> Each {@code byte} in the subarray is converted to a {@code char} as
- * specified in the method above.
- *
- * @deprecated This method does not properly convert bytes into characters.
- * As of JDK&nbsp;1.1, the preferred way to do this is via the
- * {@code String} constructors that take a {@link
- * java.nio.charset.Charset}, charset name, or that use the platform's
- * default charset.
- *
- * @param ascii
- * The bytes to be converted to characters
- *
- * @param hibyte
- * The top 8 bits of each 16-bit Unicode code unit
- *
- * @param offset
- * The initial offset
- * @param count
- * The length
- *
- * @throws IndexOutOfBoundsException
- * If the {@code offset} or {@code count} argument is invalid
- *
- * @see #String(byte[], int)
- * @see #String(byte[], int, int, java.lang.String)
- * @see #String(byte[], int, int, java.nio.charset.Charset)
- * @see #String(byte[], int, int)
- * @see #String(byte[], java.lang.String)
- * @see #String(byte[], java.nio.charset.Charset)
- * @see #String(byte[])
- */
- @Deprecated
- static String NewString(byte ascii[], int hibyte, int offset, int count) {
- checkBounds(ascii, offset, count);
- char value[] = new char[count];
-
- if (hibyte == 0) {
- for (int i = count; i-- > 0;) {
- value[i] = (char)(ascii[i + offset] & 0xff);
- }
- } else {
- hibyte <<= 8;
- for (int i = count; i-- > 0;) {
- value[i] = (char)(hibyte | (ascii[i + offset] & 0xff));
- }
- }
- return new String(value, 0, count);
- }
-
- /**
- * Allocates a new {@code String} containing characters constructed from
- * an array of 8-bit integer values. Each character <i>c</i>in the
- * resulting string is constructed from the corresponding component
- * <i>b</i> in the byte array such that:
- *
- * <blockquote><pre>
- * <b><i>c</i></b> == (char)(((hibyte &amp; 0xff) &lt;&lt; 8)
- * | (<b><i>b</i></b> &amp; 0xff))
- * </pre></blockquote>
- *
- * @deprecated This method does not properly convert bytes into
- * characters. As of JDK&nbsp;1.1, the preferred way to do this is via the
- * {@code String} constructors that take a {@link
- * java.nio.charset.Charset}, charset name, or that use the platform's
- * default charset.
- *
- * @param ascii
- * The bytes to be converted to characters
- *
- * @param hibyte
- * The top 8 bits of each 16-bit Unicode code unit
- *
- * @see #String(byte[], int, int, java.lang.String)
- * @see #String(byte[], int, int, java.nio.charset.Charset)
- * @see #String(byte[], int, int)
- * @see #String(byte[], java.lang.String)
- * @see #String(byte[], java.nio.charset.Charset)
- * @see #String(byte[])
- */
- @Deprecated
- static String NewString(byte ascii[], int hibyte) {
- return NewString(ascii, hibyte, 0, ascii.length);
- }
-
- /* Common private utility method used to bounds check the byte array
- * and requested offset & length values used by the String(byte[],..)
- * constructors.
- */
- private static void checkBounds(byte[] bytes, int offset, int length) {
- if (length < 0)
- throw new StringIndexOutOfBoundsException(length);
- if (offset < 0)
- throw new StringIndexOutOfBoundsException(offset);
- if (offset > bytes.length - length)
- throw new StringIndexOutOfBoundsException(offset + length);
- }
-
- /**
- * Constructs a new {@code String} by decoding the specified subarray of
- * bytes using the specified charset. The length of the new {@code String}
- * is a function of the charset, and hence may not be equal to the length
- * of the subarray.
- *
- * <p> The behavior of this constructor when the given bytes are not valid
- * in the given charset is unspecified. The {@link
- * java.nio.charset.CharsetDecoder} class should be used when more control
- * over the decoding process is required.
- *
- * @param bytes
- * The bytes to be decoded into characters
- *
- * @param offset
- * The index of the first byte to decode
- *
- * @param length
- * The number of bytes to decode
-
- * @param charsetName
- * The name of a supported {@linkplain java.nio.charset.Charset
- * charset}
- *
- * @throws UnsupportedEncodingException
- * If the named charset is not supported
- *
- * @throws IndexOutOfBoundsException
- * If the {@code offset} and {@code length} arguments index
- * characters outside the bounds of the {@code bytes} array
- *
- * @since JDK1.1
- */
- static String NewString(byte bytes[], int offset, int length, String charsetName)
- throws UnsupportedEncodingException {
- if (charsetName == null)
- throw new NullPointerException("charsetName");
- checkBounds(bytes, offset, length);
- char[] v = StringCoding.decode(charsetName, bytes, offset, length);
- return new String(v);
- }
-
- /**
- * Constructs a new {@code String} by decoding the specified subarray of
- * bytes using the specified {@linkplain java.nio.charset.Charset charset}.
- * The length of the new {@code String} is a function of the charset, and
- * hence may not be equal to the length of the subarray.
- *
- * <p> This method always replaces malformed-input and unmappable-character
- * sequences with this charset's default replacement string. The {@link
- * java.nio.charset.CharsetDecoder} class should be used when more control
- * over the decoding process is required.
- *
- * @param bytes
- * The bytes to be decoded into characters
- *
- * @param offset
- * The index of the first byte to decode
- *
- * @param length
- * The number of bytes to decode
- *
- * @param charset
- * The {@linkplain java.nio.charset.Charset charset} to be used to
- * decode the {@code bytes}
- *
- * @throws IndexOutOfBoundsException
- * If the {@code offset} and {@code length} arguments index
- * characters outside the bounds of the {@code bytes} array
- *
- * @since 1.6
- */
- static String NewString(byte bytes[], int offset, int length, Charset charset) {
- if (charset == null)
- throw new NullPointerException("charset");
- checkBounds(bytes, offset, length);
- char[] v = StringCoding.decode(charset, bytes, offset, length);
- return new String(v);
- }
-
- /**
- * Constructs a new {@code String} by decoding the specified array of bytes
- * using the specified {@linkplain java.nio.charset.Charset charset}. The
- * length of the new {@code String} is a function of the charset, and hence
- * may not be equal to the length of the byte array.
- *
- * <p> The behavior of this constructor when the given bytes are not valid
- * in the given charset is unspecified. The {@link
- * java.nio.charset.CharsetDecoder} class should be used when more control
- * over the decoding process is required.
- *
- * @param bytes
- * The bytes to be decoded into characters
- *
- * @param charsetName
- * The name of a supported {@linkplain java.nio.charset.Charset
- * charset}
- *
- * @throws UnsupportedEncodingException
- * If the named charset is not supported
- *
- * @since JDK1.1
- */
- static String NewString(byte bytes[], String charsetName)
- throws UnsupportedEncodingException {
- return NewString(bytes, 0, bytes.length, charsetName);
- }
-
- /**
- * Constructs a new {@code String} by decoding the specified array of
- * bytes using the specified {@linkplain java.nio.charset.Charset charset}.
- * The length of the new {@code String} is a function of the charset, and
- * hence may not be equal to the length of the byte array.
- *
- * <p> This method always replaces malformed-input and unmappable-character
- * sequences with this charset's default replacement string. The {@link
- * java.nio.charset.CharsetDecoder} class should be used when more control
- * over the decoding process is required.
- *
- * @param bytes
- * The bytes to be decoded into characters
- *
- * @param charset
- * The {@linkplain java.nio.charset.Charset charset} to be used to
- * decode the {@code bytes}
- *
- * @since 1.6
- */
- static String NewString(byte bytes[], Charset charset) {
- return NewString(bytes, 0, bytes.length, charset);
- }
-
- /**
- * Constructs a new {@code String} by decoding the specified subarray of
- * bytes using the platform's default charset. The length of the new
- * {@code String} is a function of the charset, and hence may not be equal
- * to the length of the subarray.
- *
- * <p> The behavior of this constructor when the given bytes are not valid
- * in the default charset is unspecified. The {@link
- * java.nio.charset.CharsetDecoder} class should be used when more control
- * over the decoding process is required.
- *
- * @param bytes
- * The bytes to be decoded into characters
- *
- * @param offset
- * The index of the first byte to decode
- *
- * @param length
- * The number of bytes to decode
- *
- * @throws IndexOutOfBoundsException
- * If the {@code offset} and the {@code length} arguments index
- * characters outside the bounds of the {@code bytes} array
- *
- * @since JDK1.1
- */
- static String NewString(byte bytes[], int offset, int length) {
- checkBounds(bytes, offset, length);
- char[] v = StringCoding.decode(bytes, offset, length);
- return new String(v);
- }
-
- /**
- * Constructs a new {@code String} by decoding the specified array of bytes
- * using the platform's default charset. The length of the new {@code
- * String} is a function of the charset, and hence may not be equal to the
- * length of the byte array.
- *
- * <p> The behavior of this constructor when the given bytes are not valid
- * in the default charset is unspecified. The {@link
- * java.nio.charset.CharsetDecoder} class should be used when more control
- * over the decoding process is required.
- *
- * @param bytes
- * The bytes to be decoded into characters
- *
- * @since JDK1.1
- */
- static String NewString(byte bytes[]) {
- return NewString(bytes, 0, bytes.length);
- }
-
- /**
- * Allocates a new string that contains the sequence of characters
- * currently contained in the string buffer argument. The contents of the
- * string buffer are copied; subsequent modification of the string buffer
- * does not affect the newly created string.
- *
- * @param buffer
- * A {@code StringBuffer}
- */
- static String NewString(StringBuffer buffer) {
- return buffer.toString();
- }
-
- /**
- * Allocates a new string that contains the sequence of characters
- * currently contained in the string builder argument. The contents of the
- * string builder are copied; subsequent modification of the string builder
- * does not affect the newly created string.
- *
- * <p> This constructor is provided to ease migration to {@code
- * StringBuilder}. Obtaining a string from a string builder via the {@code
- * toString} method is likely to run faster and is generally preferred.
- *
- * @param builder
- * A {@code StringBuilder}
- *
- * @since 1.5
- */
- static String NewString(StringBuilder builder) {
- return builder.toString();
- }
-
-
- // Package private constructor which shares value array for speed.
- static String NewString(int offset, int count, char value[]) {
- return new String(value, offset, count);
- }
-
- /**
- * Returns the character (Unicode code point) at the specified
- * index. The index refers to <code>char</code> values
- * (Unicode code units) and ranges from <code>0</code> to
- * {@link #length()}<code> - 1</code>.
- *
- * <p> If the <code>char</code> value specified at the given index
- * is in the high-surrogate range, the following index is less
- * than the length of this <code>String</code>, and the
- * <code>char</code> value at the following index is in the
- * low-surrogate range, then the supplementary code point
- * corresponding to this surrogate pair is returned. Otherwise,
- * the <code>char</code> value at the given index is returned.
- *
- * @param index the index to the <code>char</code> values
- * @return the code point value of the character at the
- * <code>index</code>
- * @exception IndexOutOfBoundsException if the <code>index</code>
- * argument is negative or not less than the length of this
- * string.
- * @since 1.5
- */
- static int codePointAt(String _this, int index) {
- if ((index < 0) || (index >= _this.length())) {
- throw new StringIndexOutOfBoundsException(index);
- }
- char c1 = _this.charAt(index++);
- if (Character.isHighSurrogate(c1)) {
- if (index < _this.length()) {
- char c2 = _this.charAt(index);
- if (Character.isLowSurrogate(c2)) {
- return Character.toCodePoint(c1, c2);
- }
- }
- }
- return c1;
- }
-
- /**
- * Returns the character (Unicode code point) before the specified
- * index. The index refers to <code>char</code> values
- * (Unicode code units) and ranges from <code>1</code> to {@link
- * CharSequence#length() length}.
- *
- * <p> If the <code>char</code> value at <code>(index - 1)</code>
- * is in the low-surrogate range, <code>(index - 2)</code> is not
- * negative, and the <code>char</code> value at <code>(index -
- * 2)</code> is in the high-surrogate range, then the
- * supplementary code point value of the surrogate pair is
- * returned. If the <code>char</code> value at <code>index -
- * 1</code> is an unpaired low-surrogate or a high-surrogate, the
- * surrogate value is returned.
- *
- * @param index the index following the code point that should be returned
- * @return the Unicode code point value before the given index.
- * @exception IndexOutOfBoundsException if the <code>index</code>
- * argument is less than 1 or greater than the length
- * of this string.
- * @since 1.5
- */
- static int codePointBefore(String _this, int index) {
- int i = index - 1;
- if ((i < 0) || (i >= _this.length())) {
- throw new StringIndexOutOfBoundsException(index);
- }
- char c2 = _this.charAt(--index);
- if (Character.isLowSurrogate(c2)) {
- if (index > 0) {
- char c1 = _this.charAt(--index);
- if (Character.isHighSurrogate(c1)) {
- return Character.toCodePoint(c1, c2);
- }
- }
- }
- return c2;
- }
-
- /**
- * Returns the number of Unicode code points in the specified text
- * range of this <code>String</code>. The text range begins at the
- * specified <code>beginIndex</code> and extends to the
- * <code>char</code> at index <code>endIndex - 1</code>. Thus the
- * length (in <code>char</code>s) of the text range is
- * <code>endIndex-beginIndex</code>. Unpaired surrogates within
- * the text range count as one code point each.
- *
- * @param beginIndex the index to the first <code>char</code> of
- * the text range.
- * @param endIndex the index after the last <code>char</code> of
- * the text range.
- * @return the number of Unicode code points in the specified text
- * range
- * @exception IndexOutOfBoundsException if the
- * <code>beginIndex</code> is negative, or <code>endIndex</code>
- * is larger than the length of this <code>String</code>, or
- * <code>beginIndex</code> is larger than <code>endIndex</code>.
- * @since 1.5
- */
- static int codePointCount(String _this, int beginIndex, int endIndex) {
- if (beginIndex < 0 || endIndex > _this.length() || beginIndex > endIndex) {
- throw new IndexOutOfBoundsException();
- }
- int n = 0;
- for (int i = beginIndex; i < endIndex; ) {
- n++;
- if (Character.isHighSurrogate(_this.charAt(i++))) {
- if (i < endIndex && Character.isLowSurrogate(_this.charAt(i))) {
- i++;
- }
- }
- }
- return n;
- }
-
- /**
- * Returns the index within this <code>String</code> that is
- * offset from the given <code>index</code> by
- * <code>codePointOffset</code> code points. Unpaired surrogates
- * within the text range given by <code>index</code> and
- * <code>codePointOffset</code> count as one code point each.
- *
- * @param index the index to be offset
- * @param codePointOffset the offset in code points
- * @return the index within this <code>String</code>
- * @exception IndexOutOfBoundsException if <code>index</code>
- * is negative or larger then the length of this
- * <code>String</code>, or if <code>codePointOffset</code> is positive
- * and the substring starting with <code>index</code> has fewer
- * than <code>codePointOffset</code> code points,
- * or if <code>codePointOffset</code> is negative and the substring
- * before <code>index</code> has fewer than the absolute value
- * of <code>codePointOffset</code> code points.
- * @since 1.5
- */
- static int offsetByCodePoints(String _this, int index, int codePointOffset) {
- int count = _this.length();
- if (index < 0 || index > count) {
- throw new IndexOutOfBoundsException();
- }
- int x = index;
- if (codePointOffset >= 0) {
- int limit = count;
- int i;
- for (i = 0; x < limit && i < codePointOffset; i++) {
- if (Character.isHighSurrogate(_this.charAt(x++))) {
- if (x < limit && Character.isLowSurrogate(_this.charAt(x))) {
- x++;
- }
- }
- }
- if (i < codePointOffset) {
- throw new IndexOutOfBoundsException();
- }
- } else {
- int i;
- for (i = codePointOffset; x > 0 && i < 0; i++) {
- if (Character.isLowSurrogate(_this.charAt(--x))) {
- if (x > 0 && Character.isHighSurrogate(_this.charAt(x-1))) {
- x--;
- }
- }
- }
- if (i < 0) {
- throw new IndexOutOfBoundsException();
- }
- }
- return x;
- }
-
- /**
- * Copy characters from this string into dst starting at dstBegin.
- * This method doesn't perform any range checking.
- */
- static void getChars(String _this, char dst[], int dstBegin) {
- _this.getChars(0, _this.length(), dst, dstBegin);
- }
-
- /**
- * Copies characters from this string into the destination character
- * array.
- * <p>
- * The first character to be copied is at index <code>srcBegin</code>;
- * the last character to be copied is at index <code>srcEnd-1</code>
- * (thus the total number of characters to be copied is
- * <code>srcEnd-srcBegin</code>). The characters are copied into the
- * subarray of <code>dst</code> starting at index <code>dstBegin</code>
- * and ending at index:
- * <p><blockquote><pre>
- * dstbegin + (srcEnd-srcBegin) - 1
- * </pre></blockquote>
- *
- * @param srcBegin index of the first character in the string
- * to copy.
- * @param srcEnd index after the last character in the string
- * to copy.
- * @param dst the destination array.
- * @param dstBegin the start offset in the destination array.
- * @exception IndexOutOfBoundsException If any of the following
- * is true:
- * <ul><li><code>srcBegin</code> is negative.
- * <li><code>srcBegin</code> is greater than <code>srcEnd</code>
- * <li><code>srcEnd</code> is greater than the length of this
- * string
- * <li><code>dstBegin</code> is negative
- * <li><code>dstBegin+(srcEnd-srcBegin)</code> is larger than
- * <code>dst.length</code></ul>
- */
- static void getChars(cli.System.String _this, int srcBegin, int srcEnd, char dst[], int dstBegin) {
- if (srcBegin < 0) {
- throw new StringIndexOutOfBoundsException(srcBegin);
- }
- if (srcEnd > _this.get_Length()) {
- throw new StringIndexOutOfBoundsException(srcEnd);
- }
- if (srcBegin > srcEnd) {
- throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
- }
- _this.CopyTo(srcBegin, dst, dstBegin, srcEnd - srcBegin);
- }
-
- /**
- * Copies characters from this string into the destination byte array. Each
- * byte receives the 8 low-order bits of the corresponding character. The
- * eight high-order bits of each character are not copied and do not
- * participate in the transfer in any way.
- *
- * <p> The first character to be copied is at index {@code srcBegin}; the
- * last character to be copied is at index {@code srcEnd-1}. The total
- * number of characters to be copied is {@code srcEnd-srcBegin}. The
- * characters, converted to bytes, are copied into the subarray of {@code
- * dst} starting at index {@code dstBegin} and ending at index:
- *
- * <blockquote><pre>
- * dstbegin + (srcEnd-srcBegin) - 1
- * </pre></blockquote>
- *
- * @deprecated This method does not properly convert characters into
- * bytes. As of JDK&nbsp;1.1, the preferred way to do this is via the
- * {@link #getBytes()} method, which uses the platform's default charset.
- *
- * @param srcBegin
- * Index of the first character in the string to copy
- *
- * @param srcEnd
- * Index after the last character in the string to copy
- *
- * @param dst
- * The destination array
- *
- * @param dstBegin
- * The start offset in the destination array
- *
- * @throws IndexOutOfBoundsException
- * If any of the following is true:
- * <ul>
- * <li> {@code srcBegin} is negative
- * <li> {@code srcBegin} is greater than {@code srcEnd}
- * <li> {@code srcEnd} is greater than the length of this String
- * <li> {@code dstBegin} is negative
- * <li> {@code dstBegin+(srcEnd-srcBegin)} is larger than {@code
- * dst.length}
- * </ul>
- */
- @Deprecated
- static void getBytes(String _this, int srcBegin, int srcEnd, byte dst[], int dstBegin) {
- if (srcBegin < 0) {
- throw new StringIndexOutOfBoundsException(srcBegin);
- }
- if (srcEnd > _this.length()) {
- throw new StringIndexOutOfBoundsException(srcEnd);
- }
- if (srcBegin > srcEnd) {
- throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
- }
- int j = dstBegin;
- int n = srcEnd;
- int i = srcBegin;
-
- while (i < n) {
- dst[j++] = (byte)_this.charAt(i++);
- }
- }
-
- /**
- * Encodes this {@code String} into a sequence of bytes using the named
- * charset, storing the result into a new byte array.
- *
- * <p> The behavior of this method when this string cannot be encoded in
- * the given charset is unspecified. The {@link
- * java.nio.charset.CharsetEncoder} class should be used when more control
- * over the encoding process is required.
- *
- * @param charsetName
- * The name of a supported {@linkplain java.nio.charset.Charset
- * charset}
- *
- * @return The resultant byte array
- *
- * @throws UnsupportedEncodingException
- * If the named charset is not supported
- *
- * @since JDK1.1
- */
- static byte[] getBytes(String _this, String charsetName)
- throws UnsupportedEncodingException {
- if (charsetName == null) throw new NullPointerException();
- char[] value = _this.toCharArray();
- return StringCoding.encode(charsetName, value, 0, value.length);
- }
-
- /**
- * Encodes this {@code String} into a sequence of bytes using the given
- * {@linkplain java.nio.charset.Charset charset}, storing the result into a
- * new byte array.
- *
- * <p> This method always replaces malformed-input and unmappable-character
- * sequences with this charset's default replacement byte array. The
- * {@link java.nio.charset.CharsetEncoder} class should be used when more
- * control over the encoding process is required.
- *
- * @param charset
- * The {@linkplain java.nio.charset.Charset} to be used to encode
- * the {@code String}
- *
- * @return The resultant byte array
- *
- * @since 1.6
- */
- static byte[] getBytes(String _this, Charset charset) {
- if (charset == null) throw new NullPointerException();
- char[] value = _this.toCharArray();
- return StringCoding.encode(charset, value, 0, value.length);
- }
-
- /**
- * Encodes this {@code String} into a sequence of bytes using the
- * platform's default charset, storing the result into a new byte array.
- *
- * <p> The behavior of this method when this string cannot be encoded in
- * the default charset is unspecified. The {@link
- * java.nio.charset.CharsetEncoder} class should be used when more control
- * over the encoding process is required.
- *
- * @return The resultant byte array
- *
- * @since JDK1.1
- */
- static byte[] getBytes(String _this) {
- char[] value = _this.toCharArray();
- return StringCoding.encode(value, 0, value.length);
- }
-
- /**
- * Compares this string to the specified {@code StringBuffer}. The result
- * is {@code true} if and only if this {@code String} represents the same
- * sequence of characters as the specified {@code StringBuffer}.
- *
- * @param sb
- * The {@code StringBuffer} to compare this {@code String} against
- *
- * @return {@code true} if this {@code String} represents the same
- * sequence of characters as the specified {@code StringBuffer},
- * {@code false} otherwise
- *
- * @since 1.4
- */
- static boolean contentEquals(String _this, StringBuffer sb) {
- synchronized (sb) {
- return contentEquals(_this, (CharSequence) sb);
- }
- }
-
- /**
- * Compares this string to the specified {@code CharSequence}. The result
- * is {@code true} if and only if this {@code String} represents the same
- * sequence of char values as the specified sequence.
- *
- * @param cs
- * The sequence to compare this {@code String} against
- *
- * @return {@code true} if this {@code String} represents the same
- * sequence of char values as the specified sequence, {@code
- * false} otherwise
- *
- * @since 1.5
- */
- static boolean contentEquals(String _this, CharSequence cs) {
- if (_this.length() != cs.length())
- return false;
- // Argument is a StringBuffer, StringBuilder
- if (cs instanceof AbstractStringBuilder) {
- char v2[] = ((AbstractStringBuilder) cs).getValue();
- int i = 0;
- int n = _this.length();
- while (n-- != 0) {
- if (_this.charAt(i) != v2[i])
- return false;
- i++;
- }
- return true;
- }
- // Argument is a String
- if (cs.equals(_this))
- return true;
- // Argument is a generic CharSequence
- int i = 0;
- int n = _this.length();
- while (n-- != 0) {
- if (_this.charAt(i) != cs.charAt(i))
- return false;
- i++;
- }
- return true;
- }
-
- /**
- * Compares this {@code String} to another {@code String}, ignoring case
- * considerations. Two strings are considered equal ignoring case if they
- * are of the same length and corresponding characters in the two strings
- * are equal ignoring case.
- *
- * <p> Two characters {@code c1} and {@code c2} are considered the same
- * ignoring case if at least one of the following is true:
- * <ul>
- * <li> The two characters are the same (as compared by the
- * {@code ==} operator)
- * <li> Applying the method {@link
- * java.lang.Character#toUpperCase(char)} to each character
- * produces the same result
- * <li> Applying the method {@link
- * java.lang.Character#toLowerCase(char)} to each character
- * produces the same result
- * </ul>
- *
- * @param anotherString
- * The {@code String} to compare this {@code String} against
- *
- * @return {@code true} if the argument is not {@code null} and it
- * represents an equivalent {@code String} ignoring case; {@code
- * false} otherwise
- *
- * @see #equals(Object)
- */
- static boolean equalsIgnoreCase(String _this, String anotherString) {
- return (_this == anotherString) ? true
- : (anotherString != null)
- && (anotherString.length() == _this.length())
- && regionMatches(_this, true, 0, anotherString, 0, _this.length());
- }
-
- /**
- * Compares two strings lexicographically.
- * The comparison is based on the Unicode value of each character in
- * the strings. The character sequence represented by this
- * <code>String</code> object is compared lexicographically to the
- * character sequence represented by the argument string. The result is
- * a negative integer if this <code>String</code> object
- * lexicographically precedes the argument string. The result is a
- * positive integer if this <code>String</code> object lexicographically
- * follows the argument string. The result is zero if the strings
- * are equal; <code>compareTo</code> returns <code>0</code> exactly when
- * the {@link #equals(Object)} method would return <code>true</code>.
- * <p>
- * This is the definition of lexicographic ordering. If two strings are
- * different, then either they have different characters at some index
- * that is a valid index for both strings, or their lengths are different,
- * or both. If they have different characters at one or more index
- * positions, let <i>k</i> be the smallest such index; then the string
- * whose character at position <i>k</i> has the smaller value, as
- * determined by using the &lt; operator, lexicographically precedes the
- * other string. In this case, <code>compareTo</code> returns the
- * difference of the two character values at position <code>k</code> in
- * the two string -- that is, the value:
- * <blockquote><pre>
- * this.charAt(k)-anotherString.charAt(k)
- * </pre></blockquote>
- * If there is no index position at which they differ, then the shorter
- * string lexicographically precedes the longer string. In this case,
- * <code>compareTo</code> returns the difference of the lengths of the
- * strings -- that is, the value:
- * <blockquote><pre>
- * this.length()-anotherString.length()
- * </pre></blockquote>
- *
- * @param anotherString the <code>String</code> to be compared.
- * @return the value <code>0</code> if the argument string is equal to
- * this string; a value less than <code>0</code> if this string
- * is lexicographically less than the string argument; and a
- * value greater than <code>0</code> if this string is
- * lexicographically greater than the string argument.
- */
- static int compareTo(String _this, String anotherString) {
- int len = Math.min(_this.length(), anotherString.length());
- for (int i = 0; i < len; i++)
- {
- int diff = _this.charAt(i) - anotherString.charAt(i);
- if (diff != 0)
- {
- return diff;
- }
- }
- return _this.length() - anotherString.length();
- }
-
- /**
- * Compares two strings lexicographically, ignoring case
- * differences. This method returns an integer whose sign is that of
- * calling <code>compareTo</code> with normalized versions of the strings
- * where case differences have been eliminated by calling
- * <code>Character.toLowerCase(Character.toUpperCase(character))</code> on
- * each character.
- * <p>
- * Note that this method does <em>not</em> take locale into account,
- * and will result in an unsatisfactory ordering for certain locales.
- * The java.text package provides <em>collators</em> to allow
- * locale-sensitive ordering.
- *
- * @param str the <code>String</code> to be compared.
- * @return a negative integer, zero, or a positive integer as the
- * specified String is greater than, equal to, or less
- * than this String, ignoring case considerations.
- * @see java.text.Collator#compare(String, String)
- * @since 1.2
- */
- static int compareToIgnoreCase(String _this, String str) {
- return String.CASE_INSENSITIVE_ORDER.compare(_this, str);
- }
-
- /**
- * Tests if two string regions are equal.
- * <p>
- * A substring of this <tt>String</tt> object is compared to a substring
- * of the argument other. The result is true if these substrings
- * represent identical character sequences. The substring of this
- * <tt>String</tt> object to be compared begins at index <tt>toffset</tt>
- * and has length <tt>len</tt>. The substring of other to be compared
- * begins at index <tt>ooffset</tt> and has length <tt>len</tt>. The
- * result is <tt>false</tt> if and only if at least one of the following
- * is true:
- * <ul><li><tt>toffset</tt> is negative.
- * <li><tt>ooffset</tt> is negative.
- * <li><tt>toffset+len</tt> is greater than the length of this
- * <tt>String</tt> object.
- * <li><tt>ooffset+len</tt> is greater than the length of the other
- * argument.
- * <li>There is some nonnegative integer <i>k</i> less than <tt>len</tt>
- * such that:
- * <tt>this.charAt(toffset+<i>k</i>)&nbsp;!=&nbsp;other.charAt(ooffset+<i>k</i>)</tt>
- * </ul>
- *
- * @param toffset the starting offset of the subregion in this string.
- * @param other the string argument.
- * @param ooffset the starting offset of the subregion in the string
- * argument.
- * @param len the number of characters to compare.
- * @return <code>true</code> if the specified subregion of this string
- * exactly matches the specified subregion of the string argument;
- * <code>false</code> otherwise.
- */
- static boolean regionMatches(String _this, int toffset, String other, int ooffset,
- int len) {
- int to = toffset;
- int po = ooffset;
- // Note: toffset, ooffset, or len might be near -1>>>1.
- if ((ooffset < 0) || (toffset < 0)
- || (toffset > (long)_this.length() - len)
- || (ooffset > (long)other.length() - len)) {
- return false;
- }
- while (len-- > 0) {
- if (_this.charAt(to++) != other.charAt(po++)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Tests if two string regions are equal.
- * <p>
- * A substring of this <tt>String</tt> object is compared to a substring
- * of the argument <tt>other</tt>. The result is <tt>true</tt> if these
- * substrings represent character sequences that are the same, ignoring
- * case if and only if <tt>ignoreCase</tt> is true. The substring of
- * this <tt>String</tt> object to be compared begins at index
- * <tt>toffset</tt> and has length <tt>len</tt>. The substring of
- * <tt>other</tt> to be compared begins at index <tt>ooffset</tt> and
- * has length <tt>len</tt>. The result is <tt>false</tt> if and only if
- * at least one of the following is true:
- * <ul><li><tt>toffset</tt> is negative.
- * <li><tt>ooffset</tt> is negative.
- * <li><tt>toffset+len</tt> is greater than the length of this
- * <tt>String</tt> object.
- * <li><tt>ooffset+len</tt> is greater than the length of the other
- * argument.
- * <li><tt>ignoreCase</tt> is <tt>false</tt> and there is some nonnegative
- * integer <i>k</i> less than <tt>len</tt> such that:
- * <blockquote><pre>
- * this.charAt(toffset+k) != other.charAt(ooffset+k)
- * </pre></blockquote>
- * <li><tt>ignoreCase</tt> is <tt>true</tt> and there is some nonnegative
- * integer <i>k</i> less than <tt>len</tt> such that:
- * <blockquote><pre>
- * Character.toLowerCase(this.charAt(toffset+k)) !=
- Character.toLowerCase(other.charAt(ooffset+k))
- * </pre></blockquote>
- * and:
- * <blockquote><pre>
- * Character.toUpperCase(this.charAt(toffset+k)) !=
- * Character.toUpperCase(other.charAt(ooffset+k))
- * </pre></blockquote>
- * </ul>
- *
- * @param ignoreCase if <code>true</code>, ignore case when comparing
- * characters.
- * @param toffset the starting offset of the subregion in this
- * string.
- * @param other the string argument.
- * @param ooffset the starting offset of the subregion in the string
- * argument.
- * @param len the number of characters to compare.
- * @return <code>true</code> if the specified subregion of this string
- * matches the specified subregion of the string argument;
- * <code>false</code> otherwise. Whether the matching is exact
- * or case insensitive depends on the <code>ignoreCase</code>
- * argument.
- */
- static boolean regionMatches(String _this, boolean ignoreCase, int toffset,
- String other, int ooffset, int len) {
- int to = toffset;
- int po = ooffset;
- // Note: toffset, ooffset, or len might be near -1>>>1.
- if ((ooffset < 0) || (toffset < 0)
- || (toffset > (long)_this.length() - len)
- || (ooffset > (long)other.length() - len)) {
- return false;
- }
- while (len-- > 0) {
- char c1 = _this.charAt(to++);
- char c2 = other.charAt(po++);
- if (c1 == c2) {
- continue;
- }
- if (ignoreCase) {
- // If characters don't match but case may be ignored,
- // try converting both characters to uppercase.
- // If the results match, then the comparison scan should
- // continue.
- char u1 = Character.toUpperCase(c1);
- char u2 = Character.toUpperCase(c2);
- if (u1 == u2) {
- continue;
- }
- // Unfortunately, conversion to uppercase does not work properly
- // for the Georgian alphabet, which has strange rules about case
- // conversion. So we need to make one last check before
- // exiting.
- if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
- continue;
- }
- }
- return false;
- }
- return true;
- }
-
- /**
- * Returns a hash code for this string. The hash code for a
- * <code>String</code> object is computed as
- * <blockquote><pre>
- * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
- * </pre></blockquote>
- * using <code>int</code> arithmetic, where <code>s[i]</code> is the
- * <i>i</i>th character of the string, <code>n</code> is the length of
- * the string, and <code>^</code> indicates exponentiation.
- * (The hash value of the empty string is zero.)
- *
- * @return a hash code value for this object.
- */
- static int hashCode(cli.System.String _this) {
- int h = 0;
- // NOTE having the get_Length in the for condition is actually faster than hoisting it,
- // the CLR JIT recognizes this pattern and optimizes the array bounds check in get_Chars.
- for (int i = 0; i < _this.get_Length(); i++)
- {
- h = h * 31 + _this.get_Chars(i);
- }
- return h;
- }
-
- /**
- * Returns the index within this string of the first occurrence of
- * the specified character. If a character with value
- * <code>ch</code> occurs in the character sequence represented by
- * this <code>String</code> object, then the index (in Unicode
- * code units) of the first such occurrence is returned. For
- * values of <code>ch</code> in the range from 0 to 0xFFFF
- * (inclusive), this is the smallest value <i>k</i> such that:
- * <blockquote><pre>
- * this.charAt(<i>k</i>) == ch
- * </pre></blockquote>
- * is true. For other values of <code>ch</code>, it is the
- * smallest value <i>k</i> such that:
- * <blockquote><pre>
- * this.codePointAt(<i>k</i>) == ch
- * </pre></blockquote>
- * is true. In either case, if no such character occurs in this
- * string, then <code>-1</code> is returned.
- *
- * @param ch a character (Unicode code point).
- * @return the index of the first occurrence of the character in the
- * character sequence represented by this object, or
- * <code>-1</code> if the character does not occur.
- */
- static int indexOf(cli.System.String _this, int ch) {
- return indexOf(_this, ch, 0);
- }
-
- /**
- * Returns the index within this string of the first occurrence of the
- * specified character, starting the search at the specified index.
- * <p>
- * If a character with value <code>ch</code> occurs in the
- * character sequence represented by this <code>String</code>
- * object at an index no smaller than <code>fromIndex</code>, then
- * the index of the first such occurrence is returned. For values
- * of <code>ch</code> in the range from 0 to 0xFFFF (inclusive),
- * this is the smallest value <i>k</i> such that:
- * <blockquote><pre>
- * (this.charAt(<i>k</i>) == ch) && (<i>k</i> &gt;= fromIndex)
- * </pre></blockquote>
- * is true. For other values of <code>ch</code>, it is the
- * smallest value <i>k</i> such that:
- * <blockquote><pre>
- * (this.codePointAt(<i>k</i>) == ch) && (<i>k</i> &gt;= fromIndex)
- * </pre></blockquote>
- * is true. In either case, if no such character occurs in this
- * string at or after position <code>fromIndex</code>, then
- * <code>-1</code> is returned.
- *
- * <p>
- * There is no restriction on the value of <code>fromIndex</code>. If it
- * is negative, it has the same effect as if it were zero: this entire
- * string may be searched. If it is greater than the length of this
- * string, it has the same effect as if it were equal to the length of
- * this string: <code>-1</code> is returned.
- *
- * <p>All indices are specified in <code>char</code> values
- * (Unicode code units).
- *
- * @param ch a character (Unicode code point).
- * @param fromIndex the index to start the search from.
- * @return the index of the first occurrence of the character in the
- * character sequence represented by this object that is greater
- * than or equal to <code>fromIndex</code>, or <code>-1</code>
- * if the character does not occur.
- */
- static int indexOf(cli.System.String _this, int ch, int fromIndex) {
- int max = _this.get_Length();
-
- if (fromIndex < 0) {
- fromIndex = 0;
- } else if (fromIndex >= max) {
- // Note: fromIndex might be near -1>>>1.
- return -1;
- }
-
- int i = fromIndex;
- if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
- // handle most cases here (ch is a BMP code point or a
- // negative value (invalid code point))
- for (; i < max ; i++) {
- if (_this.get_Chars(i) == ch) {
- return i;
- }
- }
- return -1;
- } else {
- return indexOfSupplementary(_this, ch, fromIndex);
- }
- }
-
- /**
- * Handles (rare) calls of indexOf with a supplementary character.
- */
- private static int indexOfSupplementary(cli.System.String _this, int ch, int fromIndex) {
- if (Character.isValidCodePoint(ch)) {
- final char hi = Character.highSurrogate(ch);
- final char lo = Character.lowSurrogate(ch);
- final int max = _this.get_Length() - 1;
- for (int i = fromIndex; i < max; i++) {
- if (_this.get_Chars(i) == hi && _this.get_Chars(i+1) == lo) {
- return i;
- }
- }
- }
- return -1;
- }
-
- /**
- * Returns the index within this string of the last occurrence of
- * the specified character. For values of <code>ch</code> in the
- * range from 0 to 0xFFFF (inclusive), the index (in Unicode code
- * units) returned is the largest value <i>k</i> such that:
- * <blockquote><pre>
- * this.charAt(<i>k</i>) == ch
- * </pre></blockquote>
- * is true. For other values of <code>ch</code>, it is the
- * largest value <i>k</i> such that:
- * <blockquote><pre>
- * this.codePointAt(<i>k</i>) == ch
- * </pre></blockquote>
- * is true. In either case, if no such character occurs in this
- * string, then <code>-1</code> is returned. The
- * <code>String</code> is searched backwards starting at the last
- * character.
- *
- * @param ch a character (Unicode code point).
- * @return the index of the last occurrence of the character in the
- * character sequence represented by this object, or
- * <code>-1</code> if the character does not occur.
- */
- static int lastIndexOf(cli.System.String _this, int ch) {
- return lastIndexOf(_this, ch, _this.get_Length() - 1);
- }
-
- /**
- * Returns the index within this string of the last occurrence of
- * the specified character, searching backward starting at the
- * specified index. For values of <code>ch</code> in the range
- * from 0 to 0xFFFF (inclusive), the index returned is the largest
- * value <i>k</i> such that:
- * <blockquote><pre>
- * (this.charAt(<i>k</i>) == ch) && (<i>k</i> &lt;= fromIndex)
- * </pre></blockquote>
- * is true. For other values of <code>ch</code>, it is the
- * largest value <i>k</i> such that:
- * <blockquote><pre>
- * (this.codePointAt(<i>k</i>) == ch) && (<i>k</i> &lt;= fromIndex)
- * </pre></blockquote>
- * is true. In either case, if no such character occurs in this
- * string at or before position <code>fromIndex</code>, then
- * <code>-1</code> is returned.
- *
- * <p>All indices are specified in <code>char</code> values
- * (Unicode code units).
- *
- * @param ch a character (Unicode code point).
- * @param fromIndex the index to start the search from. There is no
- * restriction on the value of <code>fromIndex</code>. If it is
- * greater than or equal to the length of this string, it has
- * the same effect as if it were equal to one less than the
- * length of this string: this entire string may be searched.
- * If it is negative, it has the same effect as if it were -1:
- * -1 is returned.
- * @return the index of the last occurrence of the character in the
- * character sequence represented by this object that is less
- * than or equal to <code>fromIndex</code>, or <code>-1</code>
- * if the character does not occur before that point.
- */
- static int lastIndexOf(cli.System.String _this, int ch, int fromIndex) {
- if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
- // handle most cases here (ch is a BMP code point or a
- // negative value (invalid code point))
- int i = Math.min(fromIndex, _this.get_Length() - 1);
- for (; i >= 0; i--) {
- if (_this.get_Chars(i) == ch) {
- return i;
- }
- }
- return -1;
- } else {
- return lastIndexOfSupplementary(_this, ch, fromIndex);
- }
- }
-
- /**
- * Handles (rare) calls of lastIndexOf with a supplementary character.
- */
- private static int lastIndexOfSupplementary(cli.System.String _this, int ch, int fromIndex) {
- if (Character.isValidCodePoint(ch)) {
- char hi = Character.highSurrogate(ch);
- char lo = Character.lowSurrogate(ch);
- int i = Math.min(fromIndex, _this.get_Length() - 2);
- for (; i >= 0; i--) {
- if (_this.get_Chars(i) == hi && _this.get_Chars(i+1) == lo) {
- return i;
- }
- }
- }
- return -1;
- }
-
- /**
- * Returns the index within this string of the first occurrence of the
- * specified substring.
- *
- * <p>The returned index is the smallest value <i>k</i> for which:
- * <blockquote><pre>
- * this.startsWith(str, <i>k</i>)
- * </pre></blockquote>
- * If no such value of <i>k</i> exists, then {@code -1} is returned.
- *
- * @param str the substring to search for.
- * @return the index of the first occurrence of the specified substring,
- * or {@code -1} if there is no such occurrence.
- */
- static int indexOf(String _this, String str) {
- return indexOf(_this, str, 0);
- }
-
- /**
- * Returns the index within this string of the first occurrence of the
- * specified substring, starting at the specified index.
- *
- * <p>The returned index is the smallest value <i>k</i> for which:
- * <blockquote><pre>
- * <i>k</i> &gt;= fromIndex && this.startsWith(str, <i>k</i>)
- * </pre></blockquote>
- * If no such value of <i>k</i> exists, then {@code -1} is returned.
- *
- * @param str the substring to search for.
- * @param fromIndex the index from which to start the search.
- * @return the index of the first occurrence of the specified substring,
- * starting at the specified index,
- * or {@code -1} if there is no such occurrence.
- */
- static int indexOf(String _this, String str, int fromIndex) {
- // start by dereferencing _this, to make sure we throw a NullPointerException if _this is null
- int slen = _this.length();
- int olen = str.length();
- if (olen == 0)
- {
- return Math.max(0, Math.min(fromIndex, slen));
- }
- if (olen > slen)
- {
- return -1;
- }
- char firstChar = str.charAt(0);
- // Java allows fromIndex to both below zero or above the length of the string, .NET doesn't
- int index = Math.max(0, Math.min(slen, fromIndex));
- int end = slen - olen;
- while (index >= 0 && index <= end)
- {
- if (cli.System.String.CompareOrdinal(_this, index, str, 0, olen) == 0)
- {
- return index;
- }
- index = _this.indexOf(firstChar, index + 1);
- }
- return -1;
- }
-
- /**
- * Code shared by String and StringBuffer to do searches. The
- * source is the character array being searched, and the target
- * is the string being searched for.
- *
- * @param source the characters being searched.
- * @param sourceOffset offset of the source string.
- * @param sourceCount count of the source string.
- * @param target the characters being searched for.
- * @param targetOffset offset of the target string.
- * @param targetCount count of the target string.
- * @param fromIndex the index to begin searching from.
- */
- static int indexOf(char[] source, int sourceOffset, int sourceCount,
- char[] target, int targetOffset, int targetCount,
- int fromIndex) {
- if (fromIndex >= sourceCount) {
- return (targetCount == 0 ? sourceCount : -1);
- }
- if (fromIndex < 0) {
- fromIndex = 0;
- }
- if (targetCount == 0) {
- return fromIndex;
- }
-
- char first = target[targetOffset];
- int max = sourceOffset + (sourceCount - targetCount);
-
- for (int i = sourceOffset + fromIndex; i <= max; i++) {
- /* Look for first character. */
- if (source[i] != first) {
- while (++i <= max && source[i] != first);
- }
-
- /* Found first character, now look at the rest of v2 */
- if (i <= max) {
- int j = i + 1;
- int end = j + targetCount - 1;
- for (int k = targetOffset + 1; j < end && source[j]
- == target[k]; j++, k++);
-
- if (j == end) {
- /* Found whole string. */
- return i - sourceOffset;
- }
- }
- }
- return -1;
- }
-
- /**
- * Returns the index within this string of the last occurrence of the
- * specified substring. The last occurrence of the empty string ""
- * is considered to occur at the index value {@code this.length()}.
- *
- * <p>The returned index is the largest value <i>k</i> for which:
- * <blockquote><pre>
- * this.startsWith(str, <i>k</i>)
- * </pre></blockquote>
- * If no such value of <i>k</i> exists, then {@code -1} is returned.
- *
- * @param str the substring to search for.
- * @return the index of the last occurrence of the specified substring,
- * or {@code -1} if there is no such occurrence.
- */
- static int lastIndexOf(String _this, String str) {
- return lastIndexOf(_this, str, _this.length());
- }
-
- /**
- * Returns the index within this string of the last occurrence of the
- * specified substring, searching backward starting at the specified index.
- *
- * <p>The returned index is the largest value <i>k</i> for which:
- * <blockquote><pre>
- * <i>k</i> &lt;= fromIndex && this.startsWith(str, <i>k</i>)
- * </pre></blockquote>
- * If no such value of <i>k</i> exists, then {@code -1} is returned.
- *
- * @param str the substring to search for.
- * @param fromIndex the index to start the search from.
- * @return the index of the last occurrence of the specified substring,
- * searching backward from the specified index,
- * or {@code -1} if there is no such occurrence.
- */
- static int lastIndexOf(String _this, String str, int fromIndex) {
- // start by dereferencing s, to make sure we throw a NullPointerException if s is null
- int slen = _this.length();
- if (fromIndex < 0)
- {
- return -1;
- }
- int olen = str.length();
- if (olen == 0)
- {
- return Math.min(slen, fromIndex);
- }
- if (olen > slen)
- {
- return -1;
- }
- cli.System.String cliStr = (cli.System.String)(Object)_this;
- char firstChar = str.charAt(0);
- // Java allows fromIndex to both below zero or above the length of the string, .NET doesn't
- int index = Math.max(0, Math.min(slen - olen, fromIndex));
- while (index > 0)
- {
- if (cli.System.String.CompareOrdinal(_this, index, str, 0, olen) == 0)
- {
- return index;
- }
- index = cliStr.LastIndexOf(firstChar, index - 1);
- }
- return cli.System.String.CompareOrdinal(_this, 0, str, 0, olen) == 0 ? 0 : -1;
- }
-
- /**
- * Code shared by String and StringBuffer to do searches. The
- * source is the character array being searched, and the target
- * is the string being searched for.
- *
- * @param source the characters being searched.
- * @param sourceOffset offset of the source string.
- * @param sourceCount count of the source string.
- * @param target the characters being searched for.
- * @param targetOffset offset of the target string.
- * @param targetCount count of the target string.
- * @param fromIndex the index to begin searching from.
- */
- static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
- char[] target, int targetOffset, int targetCount,
- int fromIndex) {
- /*
- * Check arguments; return immediately where possible. For
- * consistency, don't check for null str.
- */
- int rightIndex = sourceCount - targetCount;
- if (fromIndex < 0) {
- return -1;
- }
- if (fromIndex > rightIndex) {
- fromIndex = rightIndex;
- }
- /* Empty string always matches. */
- if (targetCount == 0) {
- return fromIndex;
- }
-
- int strLastIndex = targetOffset + targetCount - 1;
- char strLastChar = target[strLastIndex];
- int min = sourceOffset + targetCount - 1;
- int i = min + fromIndex;
-
- startSearchForLastChar:
- while (true) {
- while (i >= min && source[i] != strLastChar) {
- i--;
- }
- if (i < min) {
- return -1;
- }
- int j = i - 1;
- int start = j - (targetCount - 1);
- int k = strLastIndex - 1;
-
- while (j > start) {
- if (source[j--] != target[k--]) {
- i--;
- continue startSearchForLastChar;
- }
- }
- return start - sourceOffset + 1;
- }
- }
-
- /**
- * Returns a new string that is a substring of this string. The
- * substring begins at the specified <code>beginIndex</code> and
- * extends to the character at index <code>endIndex - 1</code>.
- * Thus the length of the substring is <code>endIndex-beginIndex</code>.
- * <p>
- * Examples:
- * <blockquote><pre>
- * "hamburger".substring(4, 8) returns "urge"
- * "smiles".substring(1, 5) returns "mile"
- * </pre></blockquote>
- *
- * @param beginIndex the beginning index, inclusive.
- * @param endIndex the ending index, exclusive.
- * @return the specified substring.
- * @exception IndexOutOfBoundsException if the
- * <code>beginIndex</code> is negative, or
- * <code>endIndex</code> is larger than the length of
- * this <code>String</code> object, or
- * <code>beginIndex</code> is larger than
- * <code>endIndex</code>.
- */
- static String substring(cli.System.String _this, int beginIndex, int endIndex) {
- if (beginIndex < 0) {
- throw new StringIndexOutOfBoundsException(beginIndex);
- }
- if (endIndex > _this.get_Length()) {
- throw new StringIndexOutOfBoundsException(endIndex);
- }
- int subLen = endIndex - beginIndex;
- if (subLen < 0) {
- throw new StringIndexOutOfBoundsException(subLen);
- }
- return ((beginIndex == 0) && (endIndex == _this.get_Length())) ? (String)(Object)_this
- : _this.Substring(beginIndex, subLen);
- }
-
- /**
- * Concatenates the specified string to the end of this string.
- * <p>
- * If the length of the argument string is <code>0</code>, then this
- * <code>String</code> object is returned. Otherwise, a new
- * <code>String</code> object is created, representing a character
- * sequence that is the concatenation of the character sequence
- * represented by this <code>String</code> object and the character
- * sequence represented by the argument string.<p>
- * Examples:
- * <blockquote><pre>
- * "cares".concat("s") returns "caress"
- * "to".concat("get").concat("her") returns "together"
- * </pre></blockquote>
- *
- * @param str the <code>String</code> that is concatenated to the end
- * of this <code>String</code>.
- * @return a string that represents the concatenation of this object's
- * characters followed by the string argument's characters.
- */
- static String concat(String _this, String str) {
- int otherLen = str.length();
- if (otherLen == 0) {
- return _this;
- }
- return cli.System.String.Concat(_this, str);
- }
-
- /**
- * Returns a new string resulting from replacing all occurrences of
- * <code>oldChar</code> in this string with <code>newChar</code>.
- * <p>
- * If the character <code>oldChar</code> does not occur in the
- * character sequence represented by this <code>String</code> object,
- * then a reference to this <code>String</code> object is returned.
- * Otherwise, a new <code>String</code> object is created that
- * represents a character sequence identical to the character sequence
- * represented by this <code>String</code> object, except that every
- * occurrence of <code>oldChar</code> is replaced by an occurrence
- * of <code>newChar</code>.
- * <p>
- * Examples:
- * <blockquote><pre>
- * "mesquite in your cellar".replace('e', 'o')
- * returns "mosquito in your collar"
- * "the war of baronets".replace('r', 'y')
- * returns "the way of bayonets"
- * "sparring with a purple porpoise".replace('p', 't')
- * returns "starring with a turtle tortoise"
- * "JonL".replace('q', 'x') returns "JonL" (no change)
- * </pre></blockquote>
- *
- * @param oldChar the old character.
- * @param newChar the new character.
- * @return a string derived from this string by replacing every
- * occurrence of <code>oldChar</code> with <code>newChar</code>.
- */
- static String replace(String _this, char oldChar, char newChar) {
- if (oldChar != newChar) {
- int len = _this.length();
- int i = -1;
-
- while (++i < len) {
- if (_this.charAt(i) == oldChar) {
- break;
- }
- }
- if (i < len) {
- char buf[] = new char[len];
- for (int j = 0 ; j < i ; j++) {
- buf[j] = _this.charAt(j);
- }
- while (i < len) {
- char c = _this.charAt(i);
- buf[i] = (c == oldChar) ? newChar : c;
- i++;
- }
- return new String(buf, true);
- }
- }
- return _this;
- }
-
- /**
- * Returns true if and only if this string contains the specified
- * sequence of char values.
- *
- * @param s the sequence to search for
- * @return true if this string contains <code>s</code>, false otherwise
- * @throws NullPointerException if <code>s</code> is <code>null</code>
- * @since 1.5
- */
- static boolean contains(String _this, CharSequence s) {
- return indexOf(_this, s.toString()) > -1;
- }
-
- /**
- * Replaces each substring of this string that matches the literal target
- * sequence with the specified literal replacement sequence. The
- * replacement proceeds from the beginning of the string to the end, for
- * example, replacing "aa" with "b" in the string "aaa" will result in
- * "ba" rather than "ab".
- *
- * @param target The sequence of char values to be replaced
- * @param replacement The replacement sequence of char values
- * @return The resulting string
- * @throws NullPointerException if <code>target</code> or
- * <code>replacement</code> is <code>null</code>.
- * @since 1.5
- */
- static String replace(String _this, CharSequence target, CharSequence replacement) {
- return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
- _this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
- }
-
- /**
- * Splits this string around matches of the given
- * <a href="../util/regex/Pattern.html#sum">regular expression</a>.
- *
- * <p> The array returned by this method contains each substring of this
- * string that is terminated by another substring that matches the given
- * expression or is terminated by the end of the string. The substrings in
- * the array are in the order in which they occur in this string. If the
- * expression does not match any part of the input then the resulting array
- * has just one element, namely this string.
- *
- * <p> The <tt>limit</tt> parameter controls the number of times the
- * pattern is applied and therefore affects the length of the resulting
- * array. If the limit <i>n</i> is greater than zero then the pattern
- * will be applied at most <i>n</i>&nbsp;-&nbsp;1 times, the array's
- * length will be no greater than <i>n</i>, and the array's last entry
- * will contain all input beyond the last matched delimiter. If <i>n</i>
- * is non-positive then the pattern will be applied as many times as
- * possible and the array can have any length. If <i>n</i> is zero then
- * the pattern will be applied as many times as possible, the array can
- * have any length, and trailing empty strings will be discarded.
- *
- * <p> The string <tt>"boo:and:foo"</tt>, for example, yields the
- * following results with these parameters:
- *
- * <blockquote><table cellpadding=1 cellspacing=0 summary="Split example showing regex, limit, and result">
- * <tr>
- * <th>Regex</th>
- * <th>Limit</th>
- * <th>Result</th>
- * </tr>
- * <tr><td align=center>:</td>
- * <td align=center>2</td>
- * <td><tt>{ "boo", "and:foo" }</tt></td></tr>
- * <tr><td align=center>:</td>
- * <td align=center>5</td>
- * <td><tt>{ "boo", "and", "foo" }</tt></td></tr>
- * <tr><td align=center>:</td>
- * <td align=center>-2</td>
- * <td><tt>{ "boo", "and", "foo" }</tt></td></tr>
- * <tr><td align=center>o</td>
- * <td align=center>5</td>
- * <td><tt>{ "b", "", ":and:f", "", "" }</tt></td></tr>
- * <tr><td align=center>o</td>
- * <td align=center>-2</td>
- * <td><tt>{ "b", "", ":and:f", "", "" }</tt></td></tr>
- * <tr><td align=center>o</td>
- * <td align=center>0</td>
- * <td><tt>{ "b", "", ":and:f" }</tt></td></tr>
- * </table></blockquote>
- *
- * <p> An invocation of this method of the form
- * <i>str.</i><tt>split(</tt><i>regex</i><tt>,</tt>&nbsp;<i>n</i><tt>)</tt>
- * yields the same result as the expression
- *
- * <blockquote>
- * {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile
- * compile}<tt>(</tt><i>regex</i><tt>)</tt>.{@link
- * java.util.regex.Pattern#split(java.lang.CharSequence,int)
- * split}<tt>(</tt><i>str</i><tt>,</tt>&nbsp;<i>n</i><tt>)</tt>
- * </blockquote>
- *
- *
- * @param regex
- * the delimiting regular expression
- *
- * @param limit
- * the result threshold, as described above
- *
- * @return the array of strings computed by splitting this string
- * around matches of the given regular expression
- *
- * @throws PatternSyntaxException
- * if the regular expression's syntax is invalid
- *
- * @see java.util.regex.Pattern
- *
- * @since 1.4
- * @spec JSR-51
- */
- static String[] split(String _this, String regex, int limit) {
- /* fastpath if the regex is a
- (1)one-char String and this character is not one of the
- RegEx's meta characters ".$|()[{^?*+\\", or
- (2)two-char String and the first char is the backslash and
- the second is not the ascii digit or ascii letter.
- */
- char ch = 0;
- if (((regex.length() == 1 &&
- ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
- (regex.length() == 2 &&
- regex.charAt(0) == '\\' &&
- (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
- ((ch-'a')|('z'-ch)) < 0 &&
- ((ch-'A')|('Z'-ch)) < 0)) &&
- (ch < Character.MIN_HIGH_SURROGATE ||
- ch > Character.MAX_LOW_SURROGATE))
- {
- int off = 0;
- int next = 0;
- boolean limited = limit > 0;
- ArrayList<String> list = new ArrayList<>();
- while ((next = _this.indexOf(ch, off)) != -1) {
- if (!limited || list.size() < limit - 1) {
- list.add(_this.substring(off, next));
- off = next + 1;
- } else { // last one
- //assert (list.size() == limit - 1);
- list.add(_this.substring(off, _this.length()));
- off = _this.length();
- break;
- }
- }
- // If no match was found, return this
- if (off == 0)
- return new String[]{_this};
-
- // Add remaining segment
- if (!limited || list.size() < limit)
- list.add(_this.substring(off, _this.length()));
-
- // Construct result
- int resultSize = list.size();
- if (limit == 0)
- while (resultSize > 0 && list.get(resultSize - 1).length() == 0)
- resultSize--;
- String[] result = new String[resultSize];
- return list.subList(0, resultSize).toArray(result);
- }
- return Pattern.compile(regex).split(_this, limit);
- }
-
- /**
- * Converts all of the characters in this <code>String</code> to lower
- * case using the rules of the given <code>Locale</code>. Case mapping is based
- * on the Unicode Standard version specified by the {@link java.lang.Character Character}
- * class. Since case mappings are not always 1:1 char mappings, the resulting
- * <code>String</code> may be a different length than the original <code>String</code>.
- * <p>
- * Examples of lowercase mappings are in the following table:
- * <table border="1" summary="Lowercase mapping examples showing language code of locale, upper case, lower case, and description">
- * <tr>
- * <th>Language Code of Locale</th>
- * <th>Upper Case</th>
- * <th>Lower Case</th>
- * <th>Description</th>
- * </tr>
- * <tr>
- * <td>tr (Turkish)</td>
- * <td>&#92;u0130</td>
- * <td>&#92;u0069</td>
- * <td>capital letter I with dot above -&gt; small letter i</td>
- * </tr>
- * <tr>
- * <td>tr (Turkish)</td>
- * <td>&#92;u0049</td>
- * <td>&#92;u0131</td>
- * <td>capital letter I -&gt; small letter dotless i </td>
- * </tr>
- * <tr>
- * <td>(all)</td>
- * <td>French Fries</td>
- * <td>french fries</td>
- * <td>lowercased all chars in String</td>
- * </tr>
- * <tr>
- * <td>(all)</td>
- * <td><img src="doc-files/capiota.gif" alt="capiota"><img src="doc-files/capchi.gif" alt="capchi">
- * <img src="doc-files/captheta.gif" alt="captheta"><img src="doc-files/capupsil.gif" alt="capupsil">
- * <img src="doc-files/capsigma.gif" alt="capsigma"></td>
- * <td><img src="doc-files/iota.gif" alt="iota"><img src="doc-files/chi.gif" alt="chi">
- * <img src="doc-files/theta.gif" alt="theta"><img src="doc-files/upsilon.gif" alt="upsilon">
- * <img src="doc-files/sigma1.gif" alt="sigma"></td>
- * <td>lowercased all chars in String</td>
- * </tr>
- * </table>
- *
- * @param locale use the case transformation rules for this locale
- * @return the <code>String</code>, converted to lowercase.
- * @see java.lang.String#toLowerCase()
- * @see java.lang.String#toUpperCase()
- * @see java.lang.String#toUpperCase(Locale)
- * @since 1.1
- */
- static String toLowerCase(String _this, Locale locale) {
- if (locale == null) {
- throw new NullPointerException();
- }
-
- int firstUpper;
- final int len = _this.length();
-
- /* Now check if there are any characters that need to be changed. */
- scan: {
- for (firstUpper = 0 ; firstUpper < len; ) {
- char c = _this.charAt(firstUpper);
- if ((c >= Character.MIN_HIGH_SURROGATE)
- && (c <= Character.MAX_HIGH_SURROGATE)) {
- int supplChar = _this.codePointAt(firstUpper);
- if (supplChar != Character.toLowerCase(supplChar)) {
- break scan;
- }
- firstUpper += Character.charCount(supplChar);
- } else {
- if (c != Character.toLowerCase(c)) {
- break scan;
- }
- firstUpper++;
- }
- }
- return _this;
- }
-
- char[] result = new char[len];
- int resultOffset = 0; /* result may grow, so i+resultOffset
- * is the write location in result */
-
- /* Just copy the first few lowerCase characters. */
- _this.getChars(0, firstUpper, result, 0);
-
- String lang = locale.getLanguage();
- boolean localeDependent =
- (lang == "tr" || lang == "az" || lang == "lt");
- char[] lowerCharArray;
- int lowerChar;
- int srcChar;
- int srcCount;
- for (int i = firstUpper; i < len; i += srcCount) {
- srcChar = (int)_this.charAt(i);
- if ((char)srcChar >= Character.MIN_HIGH_SURROGATE
- && (char)srcChar <= Character.MAX_HIGH_SURROGATE) {
- srcChar = _this.codePointAt(i);
- srcCount = Character.charCount(srcChar);
- } else {
- srcCount = 1;
- }
- if (localeDependent || srcChar == '\u03A3') { // GREEK CAPITAL LETTER SIGMA
- lowerChar = ConditionalSpecialCasing.toLowerCaseEx(_this, i, locale);
- } else if (srcChar == '\u0130') { // LATIN CAPITAL LETTER I DOT
- lowerChar = Character.ERROR;
- } else {
- lowerChar = Character.toLowerCase(srcChar);
- }
- if ((lowerChar == Character.ERROR)
- || (lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
- if (lowerChar == Character.ERROR) {
- if (!localeDependent && srcChar == '\u0130') {
- lowerCharArray =
- ConditionalSpecialCasing.toLowerCaseCharArray(_this, i, Locale.ENGLISH);
- } else {
- lowerCharArray =
- ConditionalSpecialCasing.toLowerCaseCharArray(_this, i, locale);
- }
- } else if (srcCount == 2) {
- resultOffset += Character.toChars(lowerChar, result, i + resultOffset) - srcCount;
- continue;
- } else {
- lowerCharArray = Character.toChars(lowerChar);
- }
-
- /* Grow result if needed */
- int mapLen = lowerCharArray.length;
- if (mapLen > srcCount) {
- char[] result2 = new char[result.length + mapLen - srcCount];
- System.arraycopy(result, 0, result2, 0, i + resultOffset);
- result = result2;
- }
- for (int x = 0; x < mapLen; ++x) {
- result[i + resultOffset + x] = lowerCharArray[x];
- }
- resultOffset += (mapLen - srcCount);
- } else {
- result[i + resultOffset] = (char)lowerChar;
- }
- }
- return new String(result, 0, len + resultOffset);
- }
-
- /**
- * Converts all of the characters in this <code>String</code> to lower
- * case using the rules of the default locale. This is equivalent to calling
- * <code>toLowerCase(Locale.getDefault())</code>.
- * <p>
- * <b>Note:</b> This method is locale sensitive, and may produce unexpected
- * results if used for strings that are intended to be interpreted locale
- * independently.
- * Examples are programming language identifiers, protocol keys, and HTML
- * tags.
- * For instance, <code>"TITLE".toLowerCase()</code> in a Turkish locale
- * returns <code>"t\u005Cu0131tle"</code>, where '\u005Cu0131' is the
- * LATIN SMALL LETTER DOTLESS I character.
- * To obtain correct results for locale insensitive strings, use
- * <code>toLowerCase(Locale.ENGLISH)</code>.
- * <p>
- * @return the <code>String</code>, converted to lowercase.
- * @see java.lang.String#toLowerCase(Locale)
- */
- static String toLowerCase(String _this) {
- return toLowerCase(_this, Locale.getDefault());
- }
-
- /**
- * Converts all of the characters in this <code>String</code> to upper
- * case using the rules of the given <code>Locale</code>. Case mapping is based
- * on the Unicode Standard version specified by the {@link java.lang.Character Character}
- * class. Since case mappings are not always 1:1 char mappings, the resulting
- * <code>String</code> may be a different length than the original <code>String</code>.
- * <p>
- * Examples of locale-sensitive and 1:M case mappings are in the following table.
- * <p>
- * <table border="1" summary="Examples of locale-sensitive and 1:M case mappings. Shows Language code of locale, lower case, upper case, and description.">
- * <tr>
- * <th>Language Code of Locale</th>
- * <th>Lower Case</th>
- * <th>Upper Case</th>
- * <th>Description</th>
- * </tr>
- * <tr>
- * <td>tr (Turkish)</td>
- * <td>&#92;u0069</td>
- * <td>&#92;u0130</td>
- * <td>small letter i -&gt; capital letter I with dot above</td>
- * </tr>
- * <tr>
- * <td>tr (Turkish)</td>
- * <td>&#92;u0131</td>
- * <td>&#92;u0049</td>
- * <td>small letter dotless i -&gt; capital letter I</td>
- * </tr>
- * <tr>
- * <td>(all)</td>
- * <td>&#92;u00df</td>
- * <td>&#92;u0053 &#92;u0053</td>
- * <td>small letter sharp s -&gt; two letters: SS</td>
- * </tr>
- * <tr>
- * <td>(all)</td>
- * <td>Fahrvergn&uuml;gen</td>
- * <td>FAHRVERGN&Uuml;GEN</td>
- * <td></td>
- * </tr>
- * </table>
- * @param locale use the case transformation rules for this locale
- * @return the <code>String</code>, converted to uppercase.
- * @see java.lang.String#toUpperCase()
- * @see java.lang.String#toLowerCase()
- * @see java.lang.String#toLowerCase(Locale)
- * @since 1.1
- */
- static String toUpperCase(String _this, Locale locale) {
- if (locale == null) {
- throw new NullPointerException();
- }
-
- int firstLower;
- final int len = _this.length();
-
- /* Now check if there are any characters that need to be changed. */
- scan: {
- for (firstLower = 0 ; firstLower < len; ) {
- int c = (int)_this.charAt(firstLower);
- int srcCount;
- if ((c >= Character.MIN_HIGH_SURROGATE)
- && (c <= Character.MAX_HIGH_SURROGATE)) {
- c = _this.codePointAt(firstLower);
- srcCount = Character.charCount(c);
- } else {
- srcCount = 1;
- }
- int upperCaseChar = Character.toUpperCaseEx(c);
- if ((upperCaseChar == Character.ERROR)
- || (c != upperCaseChar)) {
- break scan;
- }
- firstLower += srcCount;
- }
- return _this;
- }
-
- char[] result = new char[len]; /* may grow */
- int resultOffset = 0; /* result may grow, so i+resultOffset
- * is the write location in result */
-
- /* Just copy the first few upperCase characters. */
- _this.getChars(0, firstLower, result, 0);
-
- String lang = locale.getLanguage();
- boolean localeDependent =
- (lang == "tr" || lang == "az" || lang == "lt");
- char[] upperCharArray;
- int upperChar;
- int srcChar;
- int srcCount;
- for (int i = firstLower; i < len; i += srcCount) {
- srcChar = (int)_this.charAt(i);
- if ((char)srcChar >= Character.MIN_HIGH_SURROGATE &&
- (char)srcChar <= Character.MAX_HIGH_SURROGATE) {
- srcChar = _this.codePointAt(i);
- srcCount = Character.charCount(srcChar);
- } else {
- srcCount = 1;
- }
- if (localeDependent) {
- upperChar = ConditionalSpecialCasing.toUpperCaseEx(_this, i, locale);
- } else {
- upperChar = Character.toUpperCaseEx(srcChar);
- }
- if ((upperChar == Character.ERROR)
- || (upperChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
- if (upperChar == Character.ERROR) {
- if (localeDependent) {
- upperCharArray =
- ConditionalSpecialCasing.toUpperCaseCharArray(_this, i, locale);
- } else {
- upperCharArray = Character.toUpperCaseCharArray(srcChar);
- }
- } else if (srcCount == 2) {
- resultOffset += Character.toChars(upperChar, result, i + resultOffset) - srcCount;
- continue;
- } else {
- upperCharArray = Character.toChars(upperChar);
- }
-
- /* Grow result if needed */
- int mapLen = upperCharArray.length;
- if (mapLen > srcCount) {
- char[] result2 = new char[result.length + mapLen - srcCount];
- System.arraycopy(result, 0, result2, 0, i + resultOffset);
- result = result2;
- }
- for (int x = 0; x < mapLen; ++x) {
- result[i + resultOffset + x] = upperCharArray[x];
- }
- resultOffset += (mapLen - srcCount);
- } else {
- result[i + resultOffset] = (char)upperChar;
- }
- }
- return new String(result, 0, len + resultOffset);
- }
-
- /**
- * Converts all of the characters in this <code>String</code> to upper
- * case using the rules of the default locale. This method is equivalent to
- * <code>toUpperCase(Locale.getDefault())</code>.
- * <p>
- * <b>Note:</b> This method is locale sensitive, and may produce unexpected
- * results if used for strings that are intended to be interpreted locale
- * independently.
- * Examples are programming language identifiers, protocol keys, and HTML
- * tags.
- * For instance, <code>"title".toUpperCase()</code> in a Turkish locale
- * returns <code>"T\u005Cu0130TLE"</code>, where '\u005Cu0130' is the
- * LATIN CAPITAL LETTER I WITH DOT ABOVE character.
- * To obtain correct results for locale insensitive strings, use
- * <code>toUpperCase(Locale.ENGLISH)</code>.
- * <p>
- * @return the <code>String</code>, converted to uppercase.
- * @see java.lang.String#toUpperCase(Locale)
- */
- static String toUpperCase(String _this) {
- return toUpperCase(_this, Locale.getDefault());
- }
-
- /**
- * Returns a copy of the string, with leading and trailing whitespace
- * omitted.
- * <p>
- * If this <code>String</code> object represents an empty character
- * sequence, or the first and last characters of character sequence
- * represented by this <code>String</code> object both have codes
- * greater than <code>'&#92;u0020'</code> (the space character), then a
- * reference to this <code>String</code> object is returned.
- * <p>
- * Otherwise, if there is no character with a code greater than
- * <code>'&#92;u0020'</code> in the string, then a new
- * <code>String</code> object representing an empty string is created
- * and returned.
- * <p>
- * Otherwise, let <i>k</i> be the index of the first character in the
- * string whose code is greater than <code>'&#92;u0020'</code>, and let
- * <i>m</i> be the index of the last character in the string whose code
- * is greater than <code>'&#92;u0020'</code>. A new <code>String</code>
- * object is created, representing the substring of this string that
- * begins with the character at index <i>k</i> and ends with the
- * character at index <i>m</i>-that is, the result of
- * <code>this.substring(<i>k</i>,&nbsp;<i>m</i>+1)</code>.
- * <p>
- * This method may be used to trim whitespace (as defined above) from
- * the beginning and end of a string.
- *
- * @return A copy of this string with leading and trailing white
- * space removed, or this string if it has no leading or
- * trailing white space.
- */
- static String trim(String _this) {
- int len = _this.length();
- int st = 0;
-
- while ((st < len) && (_this.charAt(st) <= ' ')) {
- st++;
- }
- while ((st < len) && (_this.charAt(len - 1) <= ' ')) {
- len--;
- }
- return ((st > 0) || (len < _this.length())) ? _this.substring(st, len) : _this;
- }
-
- /**
- * Returns a formatted string using the specified format string and
- * arguments.
- *
- * <p> The locale always used is the one returned by {@link
- * java.util.Locale#getDefault() Locale.getDefault()}.
- *
- * @param format
- * A <a href="../util/Formatter.html#syntax">format string</a>
- *
- * @param args
- * Arguments referenced by the format specifiers in the format
- * string. If there are more arguments than format specifiers, the
- * extra arguments are ignored. The number of arguments is
- * variable and may be zero. The maximum number of arguments is
- * limited by the maximum dimension of a Java array as defined by
- * <cite>The Java&trade; Virtual Machine Specification</cite>.
- * The behaviour on a
- * <tt>null</tt> argument depends on the <a
- * href="../util/Formatter.html#syntax">conversion</a>.
- *
- * @throws IllegalFormatException
- * If a format string contains an illegal syntax, a format
- * specifier that is incompatible with the given arguments,
- * insufficient arguments given the format string, or other
- * illegal conditions. For specification of all possible
- * formatting errors, see the <a
- * href="../util/Formatter.html#detail">Details</a> section of the
- * formatter class specification.
- *
- * @throws NullPointerException
- * If the <tt>format</tt> is <tt>null</tt>
- *
- * @return A formatted string
- *
- * @see java.util.Formatter
- * @since 1.5
- */
- public static String format(String format, Object... args) {
- return new Formatter().format(format, args).toString();
- }
-
- /**
- * Returns a formatted string using the specified locale, format string,
- * and arguments.
- *
- * @param l
- * The {@linkplain java.util.Locale locale} to apply during
- * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
- * is applied.
- *
- * @param format
- * A <a href="../util/Formatter.html#syntax">format string</a>
- *
- * @param args
- * Arguments referenced by the format specifiers in the format
- * string. If there are more arguments than format specifiers, the
- * extra arguments are ignored. The number of arguments is
- * variable and may be zero. The maximum number of arguments is
- * limited by the maximum dimension of a Java array as defined by
- * <cite>The Java&trade; Virtual Machine Specification</cite>.
- * The behaviour on a
- * <tt>null</tt> argument depends on the <a
- * href="../util/Formatter.html#syntax">conversion</a>.
- *
- * @throws IllegalFormatException
- * If a format string contains an illegal syntax, a format
- * specifier that is incompatible with the given arguments,
- * insufficient arguments given the format string, or other
- * illegal conditions. For specification of all possible
- * formatting errors, see the <a
- * href="../util/Formatter.html#detail">Details</a> section of the
- * formatter class specification
- *
- * @throws NullPointerException
- * If the <tt>format</tt> is <tt>null</tt>
- *
- * @return A formatted string
- *
- * @see java.util.Formatter
- * @since 1.5
- */
- public static String format(Locale l, String format, Object... args) {
- return new Formatter(l).format(format, args).toString();
- }
-
- /**
- * Returns the string representation of the <code>Object</code> argument.
- *
- * @param obj an <code>Object</code>.
- * @return if the argument is <code>null</code>, then a string equal to
- * <code>"null"</code>; otherwise, the value of
- * <code>obj.toString()</code> is returned.
- * @see java.lang.Object#toString()
- */
- public static String valueOf(Object obj) {
- return (obj == null) ? "null" : obj.toString();
- }
-
- /**
- * Returns the string representation of the <code>char</code> array
- * argument. The contents of the character array are copied; subsequent
- * modification of the character array does not affect the newly
- * created string.
- *
- * @param data a <code>char</code> array.
- * @return a newly allocated string representing the same sequence of
- * characters contained in the character array argument.
- */
- public static String valueOf(char data[]) {
- return new String(data);
- }
-
- /**
- * Returns the string representation of a specific subarray of the
- * <code>char</code> array argument.
- * <p>
- * The <code>offset</code> argument is the index of the first
- * character of the subarray. The <code>count</code> argument
- * specifies the length of the subarray. The contents of the subarray
- * are copied; subsequent modification of the character array does not
- * affect the newly created string.
- *
- * @param data the character array.
- * @param offset the initial offset into the value of the
- * <code>String</code>.
- * @param count the length of the value of the <code>String</code>.
- * @return a string representing the sequence of characters contained
- * in the subarray of the character array argument.
- * @exception IndexOutOfBoundsException if <code>offset</code> is
- * negative, or <code>count</code> is negative, or
- * <code>offset+count</code> is larger than
- * <code>data.length</code>.
- */
- public static String valueOf(char data[], int offset, int count) {
- return new String(data, offset, count);
- }
-
- /**
- * Returns a String that represents the character sequence in the
- * array specified.
- *
- * @param data the character array.
- * @param offset initial offset of the subarray.
- * @param count length of the subarray.
- * @return a <code>String</code> that contains the characters of the
- * specified subarray of the character array.
- */
- public static String copyValueOf(char data[], int offset, int count) {
- // All public String constructors now copy the data.
- return new String(data, offset, count);
- }
-
- /**
- * Returns a String that represents the character sequence in the
- * array specified.
- *
- * @param data the character array.
- * @return a <code>String</code> that contains the characters of the
- * character array.
- */
- public static String copyValueOf(char data[]) {
- return new String(data);
- }
-
- /**
- * Returns the string representation of the <code>boolean</code> argument.
- *
- * @param b a <code>boolean</code>.
- * @return if the argument is <code>true</code>, a string equal to
- * <code>"true"</code> is returned; otherwise, a string equal to
- * <code>"false"</code> is returned.
- */
- public static String valueOf(boolean b) {
- return b ? "true" : "false";
- }
-
- /**
- * Returns the string representation of the <code>int</code> argument.
- * <p>
- * The representation is exactly the one returned by the
- * <code>Integer.toString</code> method of one argument.
- *
- * @param i an <code>int</code>.
- * @return a string representation of the <code>int</code> argument.
- * @see java.lang.Integer#toString(int, int)
- */
- public static String valueOf(int i) {
- return Integer.toString(i);
- }
-
- /**
- * Returns the string representation of the <code>long</code> argument.
- * <p>
- * The representation is exactly the one returned by the
- * <code>Long.toString</code> method of one argument.
- *
- * @param l a <code>long</code>.
- * @return a string representation of the <code>long</code> argument.
- * @see java.lang.Long#toString(long)
- */
- public static String valueOf(long l) {
- return Long.toString(l);
- }
-
- /**
- * Returns the string representation of the <code>float</code> argument.
- * <p>
- * The representation is exactly the one returned by the
- * <code>Float.toString</code> method of one argument.
- *
- * @param f a <code>float</code>.
- * @return a string representation of the <code>float</code> argument.
- * @see java.lang.Float#toString(float)
- */
- public static String valueOf(float f) {
- return Float.toString(f);
- }
-
- /**
- * Returns the string representation of the <code>double</code> argument.
- * <p>
- * The representation is exactly the one returned by the
- * <code>Double.toString</code> method of one argument.
- *
- * @param d a <code>double</code>.
- * @return a string representation of the <code>double</code> argument.
- * @see java.lang.Double#toString(double)
- */
- public static String valueOf(double d) {
- return Double.toString(d);
- }
-
- /**
- * Seed value used for each alternative hash calculated.
- */
- private static final int HASHING_SEED;
-
- static {
- long nanos = System.nanoTime();
- long now = System.currentTimeMillis();
- int SEED_MATERIAL[] = {
- System.identityHashCode(String.class),
- System.identityHashCode(System.class),
- (int) (nanos >>> 32),
- (int) nanos,
- (int) (now >>> 32),
- (int) now,
- (int) (System.nanoTime() >>> 2)
- };
-
- // Use murmur3 to scramble the seeding material.
- // Inline implementation to avoid loading classes
- int h1 = 0;
-
- // body
- for (int k1 : SEED_MATERIAL) {
- k1 *= 0xcc9e2d51;
- k1 = (k1 << 15) | (k1 >>> 17);
- k1 *= 0x1b873593;
-
- h1 ^= k1;
- h1 = (h1 << 13) | (h1 >>> 19);
- h1 = h1 * 5 + 0xe6546b64;
- }
-
- // tail (always empty, as body is always 32-bit chunks)
-
- // finalization
-
- h1 ^= SEED_MATERIAL.length * 4;
-
- // finalization mix force all bits of a hash block to avalanche
- h1 ^= h1 >>> 16;
- h1 *= 0x85ebca6b;
- h1 ^= h1 >>> 13;
- h1 *= 0xc2b2ae35;
- h1 ^= h1 >>> 16;
-
- HASHING_SEED = h1;
- }
-
- /**
- * Calculates a 32-bit hash value for this string.
- *
- * @return a 32-bit hash value for this string.
- */
- static int hash32(String _this) {
- // [IKVM] We don't bother with murmur32 and just use the .NET hash code
- // and hope that it is good enough. We xor with HASHING_SEED to avoid
- // returning predictable values (this does not help against DoS attacks,
- // but it will surface constant hash code dependencies).
- // If truly randomized string hashes are required (to protect against
- // DoS) the .NET 4.5 <UseRandomizedStringHashAlgorithm enabled="1" />
- // app.config setting can be used.
- return HASHING_SEED ^ ((cli.System.String)(Object)_this).GetHashCode();
- }
-
-}
diff --git a/openjdk/java/lang/System.java b/openjdk/java/lang/System.java
deleted file mode 100644
index e74187b9..00000000
--- a/openjdk/java/lang/System.java
+++ /dev/null
@@ -1,1168 +0,0 @@
-/*
- * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.lang;
-
-import java.io.*;
-import java.util.Properties;
-import java.util.PropertyPermission;
-import java.util.StringTokenizer;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.AllPermission;
-import java.nio.channels.Channel;
-import java.nio.channels.spi.SelectorProvider;
-import sun.reflect.CallerSensitive;
-import sun.reflect.Reflection;
-import sun.security.util.SecurityConstants;
-
-final class StdIO
-{
- private StdIO() { }
- static InputStream in = new BufferedInputStream(new FileInputStream(FileDescriptor.in));
- static PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out), 128), true);
- static PrintStream err = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.err), 128), true);
-}
-
-final class Props
-{
- private Props() { }
-
- static Properties props;
- static String lineSeparator;
-
- static
- {
- props = new Properties();
- VMSystemProperties.initProperties(props);
- lineSeparator = props.getProperty("line.separator");
-
- // after we've initialized the system properties, we need to fixate certain
- // results that depend on system properties, because we don't want Java code to
- // be able to change the behavior by setting these system properties.
- ClassLoader.initializeLibraryPaths(props);
- sun.misc.VM.saveAndRemoveProperties(props);
-
- // now that we've initialized the system properties (which are our only
- // notion of "booting" the VM) we set the booted flag.
- sun.misc.VM.booted();
- }
-}
-
-/**
- * The <code>System</code> class contains several useful class fields
- * and methods. It cannot be instantiated.
- *
- * <p>Among the facilities provided by the <code>System</code> class
- * are standard input, standard output, and error output streams;
- * access to externally defined properties and environment
- * variables; a means of loading files and libraries; and a utility
- * method for quickly copying a portion of an array.
- *
- * @author unascribed
- * @since JDK1.0
- */
-public final class System {
-
- /** Don't let anyone instantiate this class */
- private System() {
- }
-
- /**
- * The "standard" input stream. This stream is already
- * open and ready to supply input data. Typically this stream
- * corresponds to keyboard input or another input source specified by
- * the host environment or user.
- */
- @ikvm.lang.Property(get="get_in")
- public final static InputStream in;
-
- static { in = null; }
-
- private static InputStream get_in()
- {
- return StdIO.in;
- }
-
- /**
- * The "standard" output stream. This stream is already
- * open and ready to accept output data. Typically this stream
- * corresponds to display output or another output destination
- * specified by the host environment or user.
- * <p>
- * For simple stand-alone Java applications, a typical way to write
- * a line of output data is:
- * <blockquote><pre>
- * System.out.println(data)
- * </pre></blockquote>
- * <p>
- * See the <code>println</code> methods in class <code>PrintStream</code>.
- *
- * @see java.io.PrintStream#println()
- * @see java.io.PrintStream#println(boolean)
- * @see java.io.PrintStream#println(char)
- * @see java.io.PrintStream#println(char[])
- * @see java.io.PrintStream#println(double)
- * @see java.io.PrintStream#println(float)
- * @see java.io.PrintStream#println(int)
- * @see java.io.PrintStream#println(long)
- * @see java.io.PrintStream#println(java.lang.Object)
- * @see java.io.PrintStream#println(java.lang.String)
- */
- @ikvm.lang.Property(get="get_out")
- public final static PrintStream out;
-
- static { out = null; }
-
- private static PrintStream get_out()
- {
- return StdIO.out;
- }
-
- /**
- * The "standard" error output stream. This stream is already
- * open and ready to accept output data.
- * <p>
- * Typically this stream corresponds to display output or another
- * output destination specified by the host environment or user. By
- * convention, this output stream is used to display error messages
- * or other information that should come to the immediate attention
- * of a user even if the principal output stream, the value of the
- * variable <code>out</code>, has been redirected to a file or other
- * destination that is typically not continuously monitored.
- */
- @ikvm.lang.Property(get="get_err")
- public final static PrintStream err;
-
- static { err = null ; }
-
- private static PrintStream get_err()
- {
- return StdIO.err;
- }
-
- /* The security manager for the system.
- */
- private static volatile SecurityManager security;
-
- /**
- * Reassigns the "standard" input stream.
- *
- * <p>First, if there is a security manager, its <code>checkPermission</code>
- * method is called with a <code>RuntimePermission("setIO")</code> permission
- * to see if it's ok to reassign the "standard" input stream.
- * <p>
- *
- * @param in the new standard input stream.
- *
- * @throws SecurityException
- * if a security manager exists and its
- * <code>checkPermission</code> method doesn't allow
- * reassigning of the standard input stream.
- *
- * @see SecurityManager#checkPermission
- * @see java.lang.RuntimePermission
- *
- * @since JDK1.1
- */
- public static void setIn(InputStream in) {
- checkIO();
- StdIO.in = in;
- }
-
- /**
- * Reassigns the "standard" output stream.
- *
- * <p>First, if there is a security manager, its <code>checkPermission</code>
- * method is called with a <code>RuntimePermission("setIO")</code> permission
- * to see if it's ok to reassign the "standard" output stream.
- *
- * @param out the new standard output stream
- *
- * @throws SecurityException
- * if a security manager exists and its
- * <code>checkPermission</code> method doesn't allow
- * reassigning of the standard output stream.
- *
- * @see SecurityManager#checkPermission
- * @see java.lang.RuntimePermission
- *
- * @since JDK1.1
- */
- public static void setOut(PrintStream out) {
- checkIO();
- StdIO.out = out;
- }
-
- /**
- * Reassigns the "standard" error output stream.
- *
- * <p>First, if there is a security manager, its <code>checkPermission</code>
- * method is called with a <code>RuntimePermission("setIO")</code> permission
- * to see if it's ok to reassign the "standard" error output stream.
- *
- * @param err the new standard error output stream.
- *
- * @throws SecurityException
- * if a security manager exists and its
- * <code>checkPermission</code> method doesn't allow
- * reassigning of the standard error output stream.
- *
- * @see SecurityManager#checkPermission
- * @see java.lang.RuntimePermission
- *
- * @since JDK1.1
- */
- public static void setErr(PrintStream err) {
- checkIO();
- StdIO.err = err;
- }
-
- private static volatile Console cons;
- /**
- * Returns the unique {@link java.io.Console Console} object associated
- * with the current Java virtual machine, if any.
- *
- * @return The system console, if any, otherwise <tt>null</tt>.
- *
- * @since 1.6
- */
- public static Console console() {
- if (cons == null) {
- synchronized (System.class) {
- cons = sun.misc.SharedSecrets.getJavaIOAccess().console();
- }
- }
- return cons;
- }
-
- /**
- * Returns the channel inherited from the entity that created this
- * Java virtual machine.
- *
- * <p> This method returns the channel obtained by invoking the
- * {@link java.nio.channels.spi.SelectorProvider#inheritedChannel
- * inheritedChannel} method of the system-wide default
- * {@link java.nio.channels.spi.SelectorProvider} object. </p>
- *
- * <p> In addition to the network-oriented channels described in
- * {@link java.nio.channels.spi.SelectorProvider#inheritedChannel
- * inheritedChannel}, this method may return other kinds of
- * channels in the future.
- *
- * @return The inherited channel, if any, otherwise <tt>null</tt>.
- *
- * @throws IOException
- * If an I/O error occurs
- *
- * @throws SecurityException
- * If a security manager is present and it does not
- * permit access to the channel.
- *
- * @since 1.5
- */
- public static Channel inheritedChannel() throws IOException {
- return SelectorProvider.provider().inheritedChannel();
- }
-
- private static void checkIO() {
- SecurityManager sm = getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new RuntimePermission("setIO"));
- }
- }
-
- /**
- * Sets the System security.
- *
- * <p> If there is a security manager already installed, this method first
- * calls the security manager's <code>checkPermission</code> method
- * with a <code>RuntimePermission("setSecurityManager")</code>
- * permission to ensure it's ok to replace the existing
- * security manager.
- * This may result in throwing a <code>SecurityException</code>.
- *
- * <p> Otherwise, the argument is established as the current
- * security manager. If the argument is <code>null</code> and no
- * security manager has been established, then no action is taken and
- * the method simply returns.
- *
- * @param s the security manager.
- * @exception SecurityException if the security manager has already
- * been set and its <code>checkPermission</code> method
- * doesn't allow it to be replaced.
- * @see #getSecurityManager
- * @see SecurityManager#checkPermission
- * @see java.lang.RuntimePermission
- */
- public static
- void setSecurityManager(final SecurityManager s) {
- try {
- s.checkPackageAccess("java.lang");
- } catch (Exception e) {
- // no-op
- }
- setSecurityManager0(s);
- }
-
- private static synchronized
- void setSecurityManager0(final SecurityManager s) {
- // [IKVM] force sun.misc.Launcher to initialize, because it assumes that it runs without a SecurityManager
- sun.misc.Launcher.getLauncher();
-
- SecurityManager sm = getSecurityManager();
- if (sm != null) {
- // ask the currently installed security manager if we
- // can replace it.
- sm.checkPermission(new RuntimePermission
- ("setSecurityManager"));
- }
-
- if ((s != null) && (s.getClass().getClassLoader() != null)) {
- // New security manager class is not on bootstrap classpath.
- // Cause policy to get initialized before we install the new
- // security manager, in order to prevent infinite loops when
- // trying to initialize the policy (which usually involves
- // accessing some security and/or system properties, which in turn
- // calls the installed security manager's checkPermission method
- // which will loop infinitely if there is a non-system class
- // (in this case: the new security manager class) on the stack).
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- s.getClass().getProtectionDomain().implies
- (SecurityConstants.ALL_PERMISSION);
- return null;
- }
- });
- }
-
- security = s;
- }
-
- /**
- * Gets the system security interface.
- *
- * @return if a security manager has already been established for the
- * current application, then that security manager is returned;
- * otherwise, <code>null</code> is returned.
- * @see #setSecurityManager
- */
- public static SecurityManager getSecurityManager() {
- return security;
- }
-
- /**
- * Returns the current time in milliseconds. Note that
- * while the unit of time of the return value is a millisecond,
- * the granularity of the value depends on the underlying
- * operating system and may be larger. For example, many
- * operating systems measure time in units of tens of
- * milliseconds.
- *
- * <p> See the description of the class <code>Date</code> for
- * a discussion of slight discrepancies that may arise between
- * "computer time" and coordinated universal time (UTC).
- *
- * @return the difference, measured in milliseconds, between
- * the current time and midnight, January 1, 1970 UTC.
- * @see java.util.Date
- */
- public static long currentTimeMillis() {
- long january_1st_1970 = 62135596800000L;
- return cli.System.DateTime.get_UtcNow().get_Ticks() / 10000L - january_1st_1970;
- }
-
- /**
- * Returns the current value of the running Java Virtual Machine's
- * high-resolution time source, in nanoseconds.
- *
- * <p>This method can only be used to measure elapsed time and is
- * not related to any other notion of system or wall-clock time.
- * The value returned represents nanoseconds since some fixed but
- * arbitrary <i>origin</i> time (perhaps in the future, so values
- * may be negative). The same origin is used by all invocations of
- * this method in an instance of a Java virtual machine; other
- * virtual machine instances are likely to use a different origin.
- *
- * <p>This method provides nanosecond precision, but not necessarily
- * nanosecond resolution (that is, how frequently the value changes)
- * - no guarantees are made except that the resolution is at least as
- * good as that of {@link #currentTimeMillis()}.
- *
- * <p>Differences in successive calls that span greater than
- * approximately 292 years (2<sup>63</sup> nanoseconds) will not
- * correctly compute elapsed time due to numerical overflow.
- *
- * <p>The values returned by this method become meaningful only when
- * the difference between two such values, obtained within the same
- * instance of a Java virtual machine, is computed.
- *
- * <p> For example, to measure how long some code takes to execute:
- * <pre> {@code
- * long startTime = System.nanoTime();
- * // ... the code being measured ...
- * long estimatedTime = System.nanoTime() - startTime;}</pre>
- *
- * <p>To compare two nanoTime values
- * <pre> {@code
- * long t0 = System.nanoTime();
- * ...
- * long t1 = System.nanoTime();}</pre>
- *
- * one should use {@code t1 - t0 < 0}, not {@code t1 < t0},
- * because of the possibility of numerical overflow.
- *
- * @return the current value of the running Java Virtual Machine's
- * high-resolution time source, in nanoseconds
- * @since 1.5
- */
- public static long nanoTime() {
- long NANOS_PER_SEC = 1000000000;
- double current = cli.System.Diagnostics.Stopwatch.GetTimestamp();
- double freq = cli.System.Diagnostics.Stopwatch.Frequency;
- return (long)((current / freq) * NANOS_PER_SEC);
- }
-
- /**
- * Copies an array from the specified source array, beginning at the
- * specified position, to the specified position of the destination array.
- * A subsequence of array components are copied from the source
- * array referenced by <code>src</code> to the destination array
- * referenced by <code>dest</code>. The number of components copied is
- * equal to the <code>length</code> argument. The components at
- * positions <code>srcPos</code> through
- * <code>srcPos+length-1</code> in the source array are copied into
- * positions <code>destPos</code> through
- * <code>destPos+length-1</code>, respectively, of the destination
- * array.
- * <p>
- * If the <code>src</code> and <code>dest</code> arguments refer to the
- * same array object, then the copying is performed as if the
- * components at positions <code>srcPos</code> through
- * <code>srcPos+length-1</code> were first copied to a temporary
- * array with <code>length</code> components and then the contents of
- * the temporary array were copied into positions
- * <code>destPos</code> through <code>destPos+length-1</code> of the
- * destination array.
- * <p>
- * If <code>dest</code> is <code>null</code>, then a
- * <code>NullPointerException</code> is thrown.
- * <p>
- * If <code>src</code> is <code>null</code>, then a
- * <code>NullPointerException</code> is thrown and the destination
- * array is not modified.
- * <p>
- * Otherwise, if any of the following is true, an
- * <code>ArrayStoreException</code> is thrown and the destination is
- * not modified:
- * <ul>
- * <li>The <code>src</code> argument refers to an object that is not an
- * array.
- * <li>The <code>dest</code> argument refers to an object that is not an
- * array.
- * <li>The <code>src</code> argument and <code>dest</code> argument refer
- * to arrays whose component types are different primitive types.
- * <li>The <code>src</code> argument refers to an array with a primitive
- * component type and the <code>dest</code> argument refers to an array
- * with a reference component type.
- * <li>The <code>src</code> argument refers to an array with a reference
- * component type and the <code>dest</code> argument refers to an array
- * with a primitive component type.
- * </ul>
- * <p>
- * Otherwise, if any of the following is true, an
- * <code>IndexOutOfBoundsException</code> is
- * thrown and the destination is not modified:
- * <ul>
- * <li>The <code>srcPos</code> argument is negative.
- * <li>The <code>destPos</code> argument is negative.
- * <li>The <code>length</code> argument is negative.
- * <li><code>srcPos+length</code> is greater than
- * <code>src.length</code>, the length of the source array.
- * <li><code>destPos+length</code> is greater than
- * <code>dest.length</code>, the length of the destination array.
- * </ul>
- * <p>
- * Otherwise, if any actual component of the source array from
- * position <code>srcPos</code> through
- * <code>srcPos+length-1</code> cannot be converted to the component
- * type of the destination array by assignment conversion, an
- * <code>ArrayStoreException</code> is thrown. In this case, let
- * <b><i>k</i></b> be the smallest nonnegative integer less than
- * length such that <code>src[srcPos+</code><i>k</i><code>]</code>
- * cannot be converted to the component type of the destination
- * array; when the exception is thrown, source array components from
- * positions <code>srcPos</code> through
- * <code>srcPos+</code><i>k</i><code>-1</code>
- * will already have been copied to destination array positions
- * <code>destPos</code> through
- * <code>destPos+</code><i>k</I><code>-1</code> and no other
- * positions of the destination array will have been modified.
- * (Because of the restrictions already itemized, this
- * paragraph effectively applies only to the situation where both
- * arrays have component types that are reference types.)
- *
- * @param src the source array.
- * @param srcPos starting position in the source array.
- * @param dest the destination array.
- * @param destPos starting position in the destination data.
- * @param length the number of array elements to be copied.
- * @exception IndexOutOfBoundsException if copying would cause
- * access of data outside array bounds.
- * @exception ArrayStoreException if an element in the <code>src</code>
- * array could not be stored into the <code>dest</code> array
- * because of a type mismatch.
- * @exception NullPointerException if either <code>src</code> or
- * <code>dest</code> is <code>null</code>.
- */
- public static native void arraycopy(Object src, int srcPos,
- Object dest, int destPos,
- int length);
-
- /**
- * Returns the same hash code for the given object as
- * would be returned by the default method hashCode(),
- * whether or not the given object's class overrides
- * hashCode().
- * The hash code for the null reference is zero.
- *
- * @param x object for which the hashCode is to be calculated
- * @return the hashCode
- * @since JDK1.1
- */
- public static int identityHashCode(Object x) {
- return cli.System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(x);
- }
-
- /**
- * System properties. The following properties are guaranteed to be defined:
- * <dl>
- * <dt>java.version <dd>Java version number
- * <dt>java.vendor <dd>Java vendor specific string
- * <dt>java.vendor.url <dd>Java vendor URL
- * <dt>java.home <dd>Java installation directory
- * <dt>java.class.version <dd>Java class version number
- * <dt>java.class.path <dd>Java classpath
- * <dt>os.name <dd>Operating System Name
- * <dt>os.arch <dd>Operating System Architecture
- * <dt>os.version <dd>Operating System Version
- * <dt>file.separator <dd>File separator ("/" on Unix)
- * <dt>path.separator <dd>Path separator (":" on Unix)
- * <dt>line.separator <dd>Line separator ("\n" on Unix)
- * <dt>user.name <dd>User account name
- * <dt>user.home <dd>User home directory
- * <dt>user.dir <dd>User's current working directory
- * </dl>
- */
-
- //private static native Properties initProperties(Properties props);
-
- /**
- * Determines the current system properties.
- * <p>
- * First, if there is a security manager, its
- * <code>checkPropertiesAccess</code> method is called with no
- * arguments. This may result in a security exception.
- * <p>
- * The current set of system properties for use by the
- * {@link #getProperty(String)} method is returned as a
- * <code>Properties</code> object. If there is no current set of
- * system properties, a set of system properties is first created and
- * initialized. This set of system properties always includes values
- * for the following keys:
- * <table summary="Shows property keys and associated values">
- * <tr><th>Key</th>
- * <th>Description of Associated Value</th></tr>
- * <tr><td><code>java.version</code></td>
- * <td>Java Runtime Environment version</td></tr>
- * <tr><td><code>java.vendor</code></td>
- * <td>Java Runtime Environment vendor</td></tr
- * <tr><td><code>java.vendor.url</code></td>
- * <td>Java vendor URL</td></tr>
- * <tr><td><code>java.home</code></td>
- * <td>Java installation directory</td></tr>
- * <tr><td><code>java.vm.specification.version</code></td>
- * <td>Java Virtual Machine specification version</td></tr>
- * <tr><td><code>java.vm.specification.vendor</code></td>
- * <td>Java Virtual Machine specification vendor</td></tr>
- * <tr><td><code>java.vm.specification.name</code></td>
- * <td>Java Virtual Machine specification name</td></tr>
- * <tr><td><code>java.vm.version</code></td>
- * <td>Java Virtual Machine implementation version</td></tr>
- * <tr><td><code>java.vm.vendor</code></td>
- * <td>Java Virtual Machine implementation vendor</td></tr>
- * <tr><td><code>java.vm.name</code></td>
- * <td>Java Virtual Machine implementation name</td></tr>
- * <tr><td><code>java.specification.version</code></td>
- * <td>Java Runtime Environment specification version</td></tr>
- * <tr><td><code>java.specification.vendor</code></td>
- * <td>Java Runtime Environment specification vendor</td></tr>
- * <tr><td><code>java.specification.name</code></td>
- * <td>Java Runtime Environment specification name</td></tr>
- * <tr><td><code>java.class.version</code></td>
- * <td>Java class format version number</td></tr>
- * <tr><td><code>java.class.path</code></td>
- * <td>Java class path</td></tr>
- * <tr><td><code>java.library.path</code></td>
- * <td>List of paths to search when loading libraries</td></tr>
- * <tr><td><code>java.io.tmpdir</code></td>
- * <td>Default temp file path</td></tr>
- * <tr><td><code>java.compiler</code></td>
- * <td>Name of JIT compiler to use</td></tr>
- * <tr><td><code>java.ext.dirs</code></td>
- * <td>Path of extension directory or directories</td></tr>
- * <tr><td><code>os.name</code></td>
- * <td>Operating system name</td></tr>
- * <tr><td><code>os.arch</code></td>
- * <td>Operating system architecture</td></tr>
- * <tr><td><code>os.version</code></td>
- * <td>Operating system version</td></tr>
- * <tr><td><code>file.separator</code></td>
- * <td>File separator ("/" on UNIX)</td></tr>
- * <tr><td><code>path.separator</code></td>
- * <td>Path separator (":" on UNIX)</td></tr>
- * <tr><td><code>line.separator</code></td>
- * <td>Line separator ("\n" on UNIX)</td></tr>
- * <tr><td><code>user.name</code></td>
- * <td>User's account name</td></tr>
- * <tr><td><code>user.home</code></td>
- * <td>User's home directory</td></tr>
- * <tr><td><code>user.dir</code></td>
- * <td>User's current working directory</td></tr>
- * </table>
- * <p>
- * Multiple paths in a system property value are separated by the path
- * separator character of the platform.
- * <p>
- * Note that even if the security manager does not permit the
- * <code>getProperties</code> operation, it may choose to permit the
- * {@link #getProperty(String)} operation.
- *
- * @return the system properties
- * @exception SecurityException if a security manager exists and its
- * <code>checkPropertiesAccess</code> method doesn't allow access
- * to the system properties.
- * @see #setProperties
- * @see java.lang.SecurityException
- * @see java.lang.SecurityManager#checkPropertiesAccess()
- * @see java.util.Properties
- */
- public static Properties getProperties() {
- SecurityManager sm = getSecurityManager();
- if (sm != null) {
- sm.checkPropertiesAccess();
- }
-
- return Props.props;
- }
-
- /**
- * Returns the system-dependent line separator string. It always
- * returns the same value - the initial value of the {@linkplain
- * #getProperty(String) system property} {@code line.separator}.
- *
- * <p>On UNIX systems, it returns {@code "\n"}; on Microsoft
- * Windows systems it returns {@code "\r\n"}.
- */
- public static String lineSeparator() {
- return Props.lineSeparator;
- }
-
- /**
- * Sets the system properties to the <code>Properties</code>
- * argument.
- * <p>
- * First, if there is a security manager, its
- * <code>checkPropertiesAccess</code> method is called with no
- * arguments. This may result in a security exception.
- * <p>
- * The argument becomes the current set of system properties for use
- * by the {@link #getProperty(String)} method. If the argument is
- * <code>null</code>, then the current set of system properties is
- * forgotten.
- *
- * @param props the new system properties.
- * @exception SecurityException if a security manager exists and its
- * <code>checkPropertiesAccess</code> method doesn't allow access
- * to the system properties.
- * @see #getProperties
- * @see java.util.Properties
- * @see java.lang.SecurityException
- * @see java.lang.SecurityManager#checkPropertiesAccess()
- */
- public static void setProperties(Properties props) {
- SecurityManager sm = getSecurityManager();
- if (sm != null) {
- sm.checkPropertiesAccess();
- }
- if (props == null) {
- props = new Properties();
- VMSystemProperties.initProperties(props);
- }
- Props.props = props;
- }
-
- /**
- * Gets the system property indicated by the specified key.
- * <p>
- * First, if there is a security manager, its
- * <code>checkPropertyAccess</code> method is called with the key as
- * its argument. This may result in a SecurityException.
- * <p>
- * If there is no current set of system properties, a set of system
- * properties is first created and initialized in the same manner as
- * for the <code>getProperties</code> method.
- *
- * @param key the name of the system property.
- * @return the string value of the system property,
- * or <code>null</code> if there is no property with that key.
- *
- * @exception SecurityException if a security manager exists and its
- * <code>checkPropertyAccess</code> method doesn't allow
- * access to the specified system property.
- * @exception NullPointerException if <code>key</code> is
- * <code>null</code>.
- * @exception IllegalArgumentException if <code>key</code> is empty.
- * @see #setProperty
- * @see java.lang.SecurityException
- * @see java.lang.SecurityManager#checkPropertyAccess(java.lang.String)
- * @see java.lang.System#getProperties()
- */
- public static String getProperty(String key) {
- checkKey(key);
- SecurityManager sm = getSecurityManager();
- if (sm != null) {
- sm.checkPropertyAccess(key);
- }
-
- return Props.props.getProperty(key);
- }
-
- /**
- * Gets the system property indicated by the specified key.
- * <p>
- * First, if there is a security manager, its
- * <code>checkPropertyAccess</code> method is called with the
- * <code>key</code> as its argument.
- * <p>
- * If there is no current set of system properties, a set of system
- * properties is first created and initialized in the same manner as
- * for the <code>getProperties</code> method.
- *
- * @param key the name of the system property.
- * @param def a default value.
- * @return the string value of the system property,
- * or the default value if there is no property with that key.
- *
- * @exception SecurityException if a security manager exists and its
- * <code>checkPropertyAccess</code> method doesn't allow
- * access to the specified system property.
- * @exception NullPointerException if <code>key</code> is
- * <code>null</code>.
- * @exception IllegalArgumentException if <code>key</code> is empty.
- * @see #setProperty
- * @see java.lang.SecurityManager#checkPropertyAccess(java.lang.String)
- * @see java.lang.System#getProperties()
- */
- public static String getProperty(String key, String def) {
- checkKey(key);
- SecurityManager sm = getSecurityManager();
- if (sm != null) {
- sm.checkPropertyAccess(key);
- }
-
- return Props.props.getProperty(key, def);
- }
-
- /**
- * Sets the system property indicated by the specified key.
- * <p>
- * First, if a security manager exists, its
- * <code>SecurityManager.checkPermission</code> method
- * is called with a <code>PropertyPermission(key, "write")</code>
- * permission. This may result in a SecurityException being thrown.
- * If no exception is thrown, the specified property is set to the given
- * value.
- * <p>
- *
- * @param key the name of the system property.
- * @param value the value of the system property.
- * @return the previous value of the system property,
- * or <code>null</code> if it did not have one.
- *
- * @exception SecurityException if a security manager exists and its
- * <code>checkPermission</code> method doesn't allow
- * setting of the specified property.
- * @exception NullPointerException if <code>key</code> or
- * <code>value</code> is <code>null</code>.
- * @exception IllegalArgumentException if <code>key</code> is empty.
- * @see #getProperty
- * @see java.lang.System#getProperty(java.lang.String)
- * @see java.lang.System#getProperty(java.lang.String, java.lang.String)
- * @see java.util.PropertyPermission
- * @see SecurityManager#checkPermission
- * @since 1.2
- */
- public static String setProperty(String key, String value) {
- checkKey(key);
- SecurityManager sm = getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new PropertyPermission(key,
- SecurityConstants.PROPERTY_WRITE_ACTION));
- }
-
- return (String) Props.props.setProperty(key, value);
- }
-
- /**
- * Removes the system property indicated by the specified key.
- * <p>
- * First, if a security manager exists, its
- * <code>SecurityManager.checkPermission</code> method
- * is called with a <code>PropertyPermission(key, "write")</code>
- * permission. This may result in a SecurityException being thrown.
- * If no exception is thrown, the specified property is removed.
- * <p>
- *
- * @param key the name of the system property to be removed.
- * @return the previous string value of the system property,
- * or <code>null</code> if there was no property with that key.
- *
- * @exception SecurityException if a security manager exists and its
- * <code>checkPropertyAccess</code> method doesn't allow
- * access to the specified system property.
- * @exception NullPointerException if <code>key</code> is
- * <code>null</code>.
- * @exception IllegalArgumentException if <code>key</code> is empty.
- * @see #getProperty
- * @see #setProperty
- * @see java.util.Properties
- * @see java.lang.SecurityException
- * @see java.lang.SecurityManager#checkPropertiesAccess()
- * @since 1.5
- */
- public static String clearProperty(String key) {
- checkKey(key);
- SecurityManager sm = getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new PropertyPermission(key, "write"));
- }
-
- return (String) Props.props.remove(key);
- }
-
- private static void checkKey(String key) {
- if (key == null) {
- throw new NullPointerException("key can't be null");
- }
- if (key.equals("")) {
- throw new IllegalArgumentException("key can't be empty");
- }
- }
-
- /**
- * Gets the value of the specified environment variable. An
- * environment variable is a system-dependent external named
- * value.
- *
- * <p>If a security manager exists, its
- * {@link SecurityManager#checkPermission checkPermission}
- * method is called with a
- * <code>{@link RuntimePermission}("getenv."+name)</code>
- * permission. This may result in a {@link SecurityException}
- * being thrown. If no exception is thrown the value of the
- * variable <code>name</code> is returned.
- *
- * <p><a name="EnvironmentVSSystemProperties"><i>System
- * properties</i> and <i>environment variables</i></a> are both
- * conceptually mappings between names and values. Both
- * mechanisms can be used to pass user-defined information to a
- * Java process. Environment variables have a more global effect,
- * because they are visible to all descendants of the process
- * which defines them, not just the immediate Java subprocess.
- * They can have subtly different semantics, such as case
- * insensitivity, on different operating systems. For these
- * reasons, environment variables are more likely to have
- * unintended side effects. It is best to use system properties
- * where possible. Environment variables should be used when a
- * global effect is desired, or when an external system interface
- * requires an environment variable (such as <code>PATH</code>).
- *
- * <p>On UNIX systems the alphabetic case of <code>name</code> is
- * typically significant, while on Microsoft Windows systems it is
- * typically not. For example, the expression
- * <code>System.getenv("FOO").equals(System.getenv("foo"))</code>
- * is likely to be true on Microsoft Windows.
- *
- * @param name the name of the environment variable
- * @return the string value of the variable, or <code>null</code>
- * if the variable is not defined in the system environment
- * @throws NullPointerException if <code>name</code> is <code>null</code>
- * @throws SecurityException
- * if a security manager exists and its
- * {@link SecurityManager#checkPermission checkPermission}
- * method doesn't allow access to the environment variable
- * <code>name</code>
- * @see #getenv()
- * @see ProcessBuilder#environment()
- */
- public static String getenv(String name) {
- SecurityManager sm = getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new RuntimePermission("getenv."+name));
- }
-
- return ProcessEnvironment.getenv(name);
- }
-
-
- /**
- * Returns an unmodifiable string map view of the current system environment.
- * The environment is a system-dependent mapping from names to
- * values which is passed from parent to child processes.
- *
- * <p>If the system does not support environment variables, an
- * empty map is returned.
- *
- * <p>The returned map will never contain null keys or values.
- * Attempting to query the presence of a null key or value will
- * throw a {@link NullPointerException}. Attempting to query
- * the presence of a key or value which is not of type
- * {@link String} will throw a {@link ClassCastException}.
- *
- * <p>The returned map and its collection views may not obey the
- * general contract of the {@link Object#equals} and
- * {@link Object#hashCode} methods.
- *
- * <p>The returned map is typically case-sensitive on all platforms.
- *
- * <p>If a security manager exists, its
- * {@link SecurityManager#checkPermission checkPermission}
- * method is called with a
- * <code>{@link RuntimePermission}("getenv.*")</code>
- * permission. This may result in a {@link SecurityException} being
- * thrown.
- *
- * <p>When passing information to a Java subprocess,
- * <a href=#EnvironmentVSSystemProperties>system properties</a>
- * are generally preferred over environment variables.
- *
- * @return the environment as a map of variable names to values
- * @throws SecurityException
- * if a security manager exists and its
- * {@link SecurityManager#checkPermission checkPermission}
- * method doesn't allow access to the process environment
- * @see #getenv(String)
- * @see ProcessBuilder#environment()
- * @since 1.5
- */
- public static java.util.Map<String,String> getenv() {
- SecurityManager sm = getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new RuntimePermission("getenv.*"));
- }
-
- return ProcessEnvironment.getenv();
- }
-
- /**
- * Terminates the currently running Java Virtual Machine. The
- * argument serves as a status code; by convention, a nonzero status
- * code indicates abnormal termination.
- * <p>
- * This method calls the <code>exit</code> method in class
- * <code>Runtime</code>. This method never returns normally.
- * <p>
- * The call <code>System.exit(n)</code> is effectively equivalent to
- * the call:
- * <blockquote><pre>
- * Runtime.getRuntime().exit(n)
- * </pre></blockquote>
- *
- * @param status exit status.
- * @throws SecurityException
- * if a security manager exists and its <code>checkExit</code>
- * method doesn't allow exit with the specified status.
- * @see java.lang.Runtime#exit(int)
- */
- public static void exit(int status) {
- Runtime.getRuntime().exit(status);
- }
-
- /**
- * Runs the garbage collector.
- * <p>
- * Calling the <code>gc</code> method suggests that the Java Virtual
- * Machine expend effort toward recycling unused objects in order to
- * make the memory they currently occupy available for quick reuse.
- * When control returns from the method call, the Java Virtual
- * Machine has made a best effort to reclaim space from all discarded
- * objects.
- * <p>
- * The call <code>System.gc()</code> is effectively equivalent to the
- * call:
- * <blockquote><pre>
- * Runtime.getRuntime().gc()
- * </pre></blockquote>
- *
- * @see java.lang.Runtime#gc()
- */
- public static void gc() {
- Runtime.getRuntime().gc();
- }
-
- /**
- * Runs the finalization methods of any objects pending finalization.
- * <p>
- * Calling this method suggests that the Java Virtual Machine expend
- * effort toward running the <code>finalize</code> methods of objects
- * that have been found to be discarded but whose <code>finalize</code>
- * methods have not yet been run. When control returns from the
- * method call, the Java Virtual Machine has made a best effort to
- * complete all outstanding finalizations.
- * <p>
- * The call <code>System.runFinalization()</code> is effectively
- * equivalent to the call:
- * <blockquote><pre>
- * Runtime.getRuntime().runFinalization()
- * </pre></blockquote>
- *
- * @see java.lang.Runtime#runFinalization()
- */
- public static void runFinalization() {
- Runtime.getRuntime().runFinalization();
- }
-
- /**
- * Enable or disable finalization on exit; doing so specifies that the
- * finalizers of all objects that have finalizers that have not yet been
- * automatically invoked are to be run before the Java runtime exits.
- * By default, finalization on exit is disabled.
- *
- * <p>If there is a security manager,
- * its <code>checkExit</code> method is first called
- * with 0 as its argument to ensure the exit is allowed.
- * This could result in a SecurityException.
- *
- * @deprecated This method is inherently unsafe. It may result in
- * finalizers being called on live objects while other threads are
- * concurrently manipulating those objects, resulting in erratic
- * behavior or deadlock.
- * @param value indicating enabling or disabling of finalization
- * @throws SecurityException
- * if a security manager exists and its <code>checkExit</code>
- * method doesn't allow the exit.
- *
- * @see java.lang.Runtime#exit(int)
- * @see java.lang.Runtime#gc()
- * @see java.lang.SecurityManager#checkExit(int)
- * @since JDK1.1
- */
- @Deprecated
- public static void runFinalizersOnExit(boolean value) {
- Runtime.getRuntime().runFinalizersOnExit(value);
- }
-
- /**
- * Loads a code file with the specified filename from the local file
- * system as a dynamic library. The filename
- * argument must be a complete path name.
- * <p>
- * The call <code>System.load(name)</code> is effectively equivalent
- * to the call:
- * <blockquote><pre>
- * Runtime.getRuntime().load(name)
- * </pre></blockquote>
- *
- * @param filename the file to load.
- * @exception SecurityException if a security manager exists and its
- * <code>checkLink</code> method doesn't allow
- * loading of the specified dynamic library
- * @exception UnsatisfiedLinkError if the file does not exist.
- * @exception NullPointerException if <code>filename</code> is
- * <code>null</code>
- * @see java.lang.Runtime#load(java.lang.String)
- * @see java.lang.SecurityManager#checkLink(java.lang.String)
- */
- @CallerSensitive
- public static void load(String filename) {
- Runtime.getRuntime().load0(Reflection.getCallerClass(), filename);
- }
-
- /**
- * Loads the system library specified by the <code>libname</code>
- * argument. The manner in which a library name is mapped to the
- * actual system library is system dependent.
- * <p>
- * The call <code>System.loadLibrary(name)</code> is effectively
- * equivalent to the call
- * <blockquote><pre>
- * Runtime.getRuntime().loadLibrary(name)
- * </pre></blockquote>
- *
- * @param libname the name of the library.
- * @exception SecurityException if a security manager exists and its
- * <code>checkLink</code> method doesn't allow
- * loading of the specified dynamic library
- * @exception UnsatisfiedLinkError if the library does not exist.
- * @exception NullPointerException if <code>libname</code> is
- * <code>null</code>
- * @see java.lang.Runtime#loadLibrary(java.lang.String)
- * @see java.lang.SecurityManager#checkLink(java.lang.String)
- */
- @CallerSensitive
- public static void loadLibrary(String libname) {
- Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname);
- }
-
- /**
- * Maps a library name into a platform-specific string representing
- * a native library.
- *
- * @param libname the name of the library.
- * @return a platform-dependent native library name.
- * @exception NullPointerException if <code>libname</code> is
- * <code>null</code>
- * @see java.lang.System#loadLibrary(java.lang.String)
- * @see java.lang.ClassLoader#findLibrary(java.lang.String)
- * @since 1.2
- */
- public static String mapLibraryName(String libname) {
- if (libname == null) {
- throw new NullPointerException();
- }
- if (ikvm.internal.Util.WINDOWS) {
- return libname + ".dll";
- } else if (ikvm.internal.Util.MACOSX) {
- return "lib" + libname + ".jnilib";
- } else {
- return "lib" + libname + ".so";
- }
- }
- /* returns the class of the caller. */
- static Class<?> getCallerClass() {
- // NOTE use of more generic Reflection.getCallerClass()
- return Reflection.getCallerClass(3);
- }
-}
diff --git a/openjdk/java/lang/Thread.java b/openjdk/java/lang/Thread.java
deleted file mode 100644
index 0ed60578..00000000
--- a/openjdk/java/lang/Thread.java
+++ /dev/null
@@ -1,2598 +0,0 @@
-/*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang;
-
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
-import java.security.AccessController;
-import java.security.AccessControlContext;
-import java.security.PrivilegedAction;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.locks.LockSupport;
-import sun.nio.ch.Interruptible;
-import sun.reflect.CallerSensitive;
-import sun.reflect.Reflection;
-import sun.security.util.SecurityConstants;
-
-
-/**
- * A <i>thread</i> is a thread of execution in a program. The Java
- * Virtual Machine allows an application to have multiple threads of
- * execution running concurrently.
- * <p>
- * Every thread has a priority. Threads with higher priority are
- * executed in preference to threads with lower priority. Each thread
- * may or may not also be marked as a daemon. When code running in
- * some thread creates a new <code>Thread</code> object, the new
- * thread has its priority initially set equal to the priority of the
- * creating thread, and is a daemon thread if and only if the
- * creating thread is a daemon.
- * <p>
- * When a Java Virtual Machine starts up, there is usually a single
- * non-daemon thread (which typically calls the method named
- * <code>main</code> of some designated class). The Java Virtual
- * Machine continues to execute threads until either of the following
- * occurs:
- * <ul>
- * <li>The <code>exit</code> method of class <code>Runtime</code> has been
- * called and the security manager has permitted the exit operation
- * to take place.
- * <li>All threads that are not daemon threads have died, either by
- * returning from the call to the <code>run</code> method or by
- * throwing an exception that propagates beyond the <code>run</code>
- * method.
- * </ul>
- * <p>
- * There are two ways to create a new thread of execution. One is to
- * declare a class to be a subclass of <code>Thread</code>. This
- * subclass should override the <code>run</code> method of class
- * <code>Thread</code>. An instance of the subclass can then be
- * allocated and started. For example, a thread that computes primes
- * larger than a stated value could be written as follows:
- * <hr><blockquote><pre>
- * class PrimeThread extends Thread {
- * long minPrime;
- * PrimeThread(long minPrime) {
- * this.minPrime = minPrime;
- * }
- *
- * public void run() {
- * // compute primes larger than minPrime
- * &nbsp;.&nbsp;.&nbsp;.
- * }
- * }
- * </pre></blockquote><hr>
- * <p>
- * The following code would then create a thread and start it running:
- * <blockquote><pre>
- * PrimeThread p = new PrimeThread(143);
- * p.start();
- * </pre></blockquote>
- * <p>
- * The other way to create a thread is to declare a class that
- * implements the <code>Runnable</code> interface. That class then
- * implements the <code>run</code> method. An instance of the class can
- * then be allocated, passed as an argument when creating
- * <code>Thread</code>, and started. The same example in this other
- * style looks like the following:
- * <hr><blockquote><pre>
- * class PrimeRun implements Runnable {
- * long minPrime;
- * PrimeRun(long minPrime) {
- * this.minPrime = minPrime;
- * }
- *
- * public void run() {
- * // compute primes larger than minPrime
- * &nbsp;.&nbsp;.&nbsp;.
- * }
- * }
- * </pre></blockquote><hr>
- * <p>
- * The following code would then create a thread and start it running:
- * <blockquote><pre>
- * PrimeRun p = new PrimeRun(143);
- * new Thread(p).start();
- * </pre></blockquote>
- * <p>
- * Every thread has a name for identification purposes. More than
- * one thread may have the same name. If a name is not specified when
- * a thread is created, a new name is generated for it.
- * <p>
- * Unless otherwise noted, passing a {@code null} argument to a constructor
- * or method in this class will cause a {@link NullPointerException} to be
- * thrown.
- *
- * @author unascribed
- * @see Runnable
- * @see Runtime#exit(int)
- * @see #run()
- * @see #stop()
- * @since JDK1.0
- */
-public
-class Thread implements Runnable {
- // [IKVM]
- static {
- // force the set/getContextClassLoader methods to be JIT compiled, because isCCLOverridden(Thread) depends on it
- // (we don't want to use RuntimeHelpers.PrepareMethod() because it requires full trust)
- Thread dummy = new Thread((Void)null);
- dummy.getContextClassLoader();
- dummy.setContextClassLoader(ClassLoader.DUMMY);
- }
- private Thread(Void _) {
- // body replaced in map.xml
- }
- final class Cleanup {
- private final Thread thread;
-
- Cleanup(Thread thread) {
- this.thread = thread;
- }
-
- protected void finalize() {
- thread.die();
- }
- }
- /* --- start IKVM specific state --- */
- static final int[] nonDaemonCount = new int[1];
- @cli.System.ThreadStaticAttribute.Annotation
- static Thread current;
- @cli.System.ThreadStaticAttribute.Annotation
- private static Cleanup cleanup;
- private final Object lock = new Object();
- private cli.System.Threading.Thread nativeThread;
- private Throwable stillborn;
- private boolean running; // used only for coordination with stop0(), is never set to false
- private volatile boolean interruptPending;
- private volatile boolean nativeInterruptPending;
- private volatile boolean interruptableWait;
- private boolean timedWait;
- volatile Object parkLock; // used by get/setParkLock in map.xml
- int parkState; // used by cmpxchgParkState in map.xml
- /* --- end IKVM specific state --- */
-
- private volatile char name[];
- private int priority;
- private Thread threadQ;
- private long eetop;
-
- /* Whether or not to single_step this thread. */
- private boolean single_step;
-
- /* Whether or not the thread is a daemon thread. */
- private boolean daemon = false;
-
- /* What will be run. */
- private Runnable target;
-
- /* The group of this thread */
- private ThreadGroup group;
-
- /* The context ClassLoader for this thread */
- private volatile ClassLoader contextClassLoader;
-
- /* The inherited AccessControlContext of this thread */
- /* [IKVM] this contains either an AccessControlContext or an AccessController.LazyContext */
- Object inheritedAccessControlContext;
-
- /* For autonumbering anonymous threads. */
- private static int threadInitNumber;
- private static synchronized int nextThreadNum() {
- return threadInitNumber++;
- }
-
- /* ThreadLocal values pertaining to this thread. This map is maintained
- * by the ThreadLocal class. */
- ThreadLocal.ThreadLocalMap threadLocals = null;
-
- /*
- * InheritableThreadLocal values pertaining to this thread. This map is
- * maintained by the InheritableThreadLocal class.
- */
- ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
-
- /*
- * The requested stack size for this thread, or 0 if the creator did
- * not specify a stack size. It is up to the VM to do whatever it
- * likes with this number; some VMs will ignore it.
- */
- private long stackSize;
-
- /*
- * JVM-private state that persists after native thread termination.
- */
- private long nativeParkEventPointer;
-
- /*
- * Thread ID
- */
- private long tid;
-
- /* For generating thread ID */
- private static long threadSeqNumber;
-
- /* Java thread status for tools,
- * initialized to indicate thread 'not yet started'
- */
-
- private volatile int threadStatus = 0;
-
-
- private static synchronized long nextThreadID() {
- return ++threadSeqNumber;
- }
-
- /**
- * The argument supplied to the current call to
- * java.util.concurrent.locks.LockSupport.park.
- * Set by (private) java.util.concurrent.locks.LockSupport.setBlocker
- * Accessed using java.util.concurrent.locks.LockSupport.getBlocker
- */
- @ikvm.lang.Internal // [IKVM] accessed from java.util.concurrent
- public volatile Object parkBlocker;
-
- /* The object in which this thread is blocked in an interruptible I/O
- * operation, if any. The blocker's interrupt method should be invoked
- * after setting this thread's interrupt status.
- */
- private volatile Interruptible blocker;
- private final Object blockerLock = new Object();
-
- /* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
- */
- void blockedOn(Interruptible b) {
- synchronized (blockerLock) {
- blocker = b;
- }
- }
-
- /**
- * The minimum priority that a thread can have.
- */
- public final static int MIN_PRIORITY = 1;
-
- /**
- * The default priority that is assigned to a thread.
- */
- public final static int NORM_PRIORITY = 5;
-
- /**
- * The maximum priority that a thread can have.
- */
- public final static int MAX_PRIORITY = 10;
-
- /**
- * Returns a reference to the currently executing thread object.
- *
- * @return the currently executing thread.
- */
- public static Thread currentThread() {
- Thread c = current;
- if (c == null) {
- c = new Thread(getMainThreadGroup());
- }
- return c;
- }
-
- private static native ThreadGroup getMainThreadGroup();
-
- /**
- * A hint to the scheduler that the current thread is willing to yield
- * its current use of a processor. The scheduler is free to ignore this
- * hint.
- *
- * <p> Yield is a heuristic attempt to improve relative progression
- * between threads that would otherwise over-utilise a CPU. Its use
- * should be combined with detailed profiling and benchmarking to
- * ensure that it actually has the desired effect.
- *
- * <p> It is rarely appropriate to use this method. It may be useful
- * for debugging or testing purposes, where it may help to reproduce
- * bugs due to race conditions. It may also be useful when designing
- * concurrency control constructs such as the ones in the
- * {@link java.util.concurrent.locks} package.
- */
- public static void yield() {
- cli.System.Threading.Thread.Sleep(0);
- }
-
- private void enterInterruptableWait(boolean timedWait) throws InterruptedException {
- synchronized (lock) {
- if (interruptPending) {
- interruptPending = false;
- throw new InterruptedException();
- }
- interruptableWait = true;
- this.timedWait = timedWait;
- }
- }
-
- private void leaveInterruptableWait() throws InterruptedException {
- cli.System.Threading.ThreadInterruptedException dotnetInterrupt = null;
- interruptableWait = false;
- for (; ; ) {
- try {
- if (false) throw new cli.System.Threading.ThreadInterruptedException();
- synchronized (lock) {
- if (nativeInterruptPending) {
- nativeInterruptPending = false;
- // HACK if there is a pending Interrupt (on the .NET thread), we need to consume that
- // (if there was no contention on "lock (this)" above the interrupted state isn't checked)
- try {
- if (false) throw new cli.System.Threading.ThreadInterruptedException();
- cli.System.Threading.Thread t = cli.System.Threading.Thread.get_CurrentThread();
- // the obvious thing to do would be t.Interrupt() / t.Join(),
- // but for some reason that causes a regression in JSR166TestCase (probably a CLR bug)
- // so we waste a time slice... sigh.
- t.Join(1);
- }
- catch (cli.System.Threading.ThreadInterruptedException _) {
- }
- }
- if (interruptPending) {
- interruptPending = false;
- throw new InterruptedException();
- }
- }
- break;
- }
- catch (cli.System.Threading.ThreadInterruptedException x) {
- dotnetInterrupt = x;
- nativeInterruptPending = false;
- }
- }
- if (dotnetInterrupt != null) {
- ikvm.runtime.Util.throwException(dotnetInterrupt);
- }
- }
-
- /**
- * Causes the currently executing thread to sleep (temporarily cease
- * execution) for the specified number of milliseconds, subject to
- * the precision and accuracy of system timers and schedulers. The thread
- * does not lose ownership of any monitors.
- *
- * @param millis
- * the length of time to sleep in milliseconds
- *
- * @throws IllegalArgumentException
- * if the value of {@code millis} is negative
- *
- * @throws InterruptedException
- * if any thread has interrupted the current thread. The
- * <i>interrupted status</i> of the current thread is
- * cleared when this exception is thrown.
- */
- public static void sleep(long millis) throws InterruptedException {
- if (millis < 0) {
- throw new IllegalArgumentException("timeout value is negative");
- }
- Thread c = currentThread();
- c.enterInterruptableWait(true);
- try {
- if (false) throw new cli.System.Threading.ThreadInterruptedException();
- for (long iter = millis / Integer.MAX_VALUE; iter != 0; iter--)
- {
- cli.System.Threading.Thread.Sleep(Integer.MAX_VALUE);
- }
- cli.System.Threading.Thread.Sleep((int)(millis % Integer.MAX_VALUE));
- }
- catch (cli.System.Threading.ThreadInterruptedException _) {
- }
- finally {
- c.leaveInterruptableWait();
- }
- }
-
- /**
- * Causes the currently executing thread to sleep (temporarily cease
- * execution) for the specified number of milliseconds plus the specified
- * number of nanoseconds, subject to the precision and accuracy of system
- * timers and schedulers. The thread does not lose ownership of any
- * monitors.
- *
- * @param millis
- * the length of time to sleep in milliseconds
- *
- * @param nanos
- * {@code 0-999999} additional nanoseconds to sleep
- *
- * @throws IllegalArgumentException
- * if the value of {@code millis} is negative, or the value of
- * {@code nanos} is not in the range {@code 0-999999}
- *
- * @throws InterruptedException
- * if any thread has interrupted the current thread. The
- * <i>interrupted status</i> of the current thread is
- * cleared when this exception is thrown.
- */
- public static void sleep(long millis, int nanos)
- throws InterruptedException {
- if (millis < 0) {
- throw new IllegalArgumentException("timeout value is negative");
- }
-
- if (nanos < 0 || nanos > 999999) {
- throw new IllegalArgumentException(
- "nanosecond timeout value out of range");
- }
-
- if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
- millis++;
- }
-
- sleep(millis);
- }
-
- /**
- * Initializes a Thread with the current AccessControlContext.
- * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext)
- */
- private void init(ThreadGroup g, Runnable target, String name,
- long stackSize) {
- init(g, target, name, stackSize, null);
- }
-
- /**
- * Initializes a Thread.
- *
- * @param g the Thread group
- * @param target the object whose run() method gets called
- * @param name the name of the new Thread
- * @param stackSize the desired stack size for the new thread, or
- * zero to indicate that this parameter is to be ignored.
- * @param acc the AccessControlContext to inherit, or
- * AccessController.getContext() if null
- */
- private void init(ThreadGroup g, Runnable target, String name,
- long stackSize, AccessControlContext acc) {
- if (name == null) {
- throw new NullPointerException("name cannot be null");
- }
-
- this.name = name.toCharArray();
-
- Thread parent = currentThread();
- SecurityManager security = System.getSecurityManager();
- if (g == null) {
- /* Determine if it's an applet or not */
-
- /* If there is a security manager, ask the security manager
- what to do. */
- if (security != null) {
- g = security.getThreadGroup();
- }
-
- /* If the security doesn't have a strong opinion of the matter
- use the parent thread group. */
- if (g == null) {
- g = parent.getThreadGroup();
- }
- }
-
- /* checkAccess regardless of whether or not threadgroup is
- explicitly passed in. */
- g.checkAccess();
-
- /*
- * Do we have the required permissions?
- */
- if (security != null) {
- if (isCCLOverridden(this)) {
- security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
- }
- }
-
- g.addUnstarted();
-
- this.group = g;
- this.daemon = parent.isDaemon();
- this.priority = parent.getPriority();
- if (isCCLOverridden(parent))
- this.contextClassLoader = parent.getContextClassLoader();
- else
- this.contextClassLoader = parent.contextClassLoader;
- this.inheritedAccessControlContext =
- acc != null ? acc : AccessController.getLazyContext(parent.inheritedAccessControlContext);
- this.target = target;
- setPriority(priority);
- if (parent.inheritableThreadLocals != null)
- this.inheritableThreadLocals =
- ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
- /* Stash the specified stack size in case the VM cares */
- this.stackSize = stackSize;
-
- /* Set thread ID */
- tid = nextThreadID();
- }
-
- // [IKVM] constructor for attaching to a .NET thread
- Thread(ThreadGroup g) {
- this.running = true;
- cli.System.Threading.Thread thread = cli.System.Threading.Thread.get_CurrentThread();
- nativeThread = thread;
- String name = thread.get_Name();
- if (name == null) {
- name = "Thread-" + nextThreadNum();
- }
-
- this.group = g;
- this.daemon = thread.get_IsBackground();
- this.priority = mapClrPriorityToJava(thread.get_Priority().Value);
- this.name = name.toCharArray();
- this.contextClassLoader = ClassLoader.DUMMY;
- this.threadStatus = 0x0005; /* JVMTI_THREAD_STATE_ALIVE + JVMTI_THREAD_STATE_RUNNABLE */
-
- /* Set thread ID */
- tid = nextThreadID();
-
- synchronized (g) {
- g.addUnstarted();
- g.add(this);
- }
-
- current = this;
- cleanup = new Cleanup(this);
-
- if (!daemon) {
- cli.System.Threading.Interlocked.Increment(nonDaemonCount);
- }
- }
-
- private static int mapClrPriorityToJava(int priority) {
- // TODO consider supporting -XX:JavaPriorityX_To_OSPriority settings
- switch (priority) {
- case cli.System.Threading.ThreadPriority.Lowest:
- return MIN_PRIORITY;
- case cli.System.Threading.ThreadPriority.BelowNormal:
- return 3;
- default:
- case cli.System.Threading.ThreadPriority.Normal:
- return NORM_PRIORITY;
- case cli.System.Threading.ThreadPriority.AboveNormal:
- return 7;
- case cli.System.Threading.ThreadPriority.Highest:
- return MAX_PRIORITY;
- }
- }
-
- private static int mapJavaPriorityToClr(int priority) {
- // TODO consider supporting -XX:JavaPriorityX_To_OSPriority settings
- if (priority == MIN_PRIORITY) {
- return cli.System.Threading.ThreadPriority.Lowest;
- }
- else if (priority > Thread.MIN_PRIORITY && priority < Thread.NORM_PRIORITY) {
- return cli.System.Threading.ThreadPriority.BelowNormal;
- }
- else if (priority == Thread.NORM_PRIORITY) {
- return cli.System.Threading.ThreadPriority.Normal;
- }
- else if (priority > Thread.NORM_PRIORITY && priority < Thread.MAX_PRIORITY) {
- return cli.System.Threading.ThreadPriority.AboveNormal;
- }
- else if (priority == Thread.MAX_PRIORITY) {
- return cli.System.Threading.ThreadPriority.Highest;
- }
- else {
- // can't happen
- return cli.System.Threading.ThreadPriority.Normal;
- }
- }
-
- /**
- * Throws CloneNotSupportedException as a Thread can not be meaningfully
- * cloned. Construct a new Thread instead.
- *
- * @throws CloneNotSupportedException
- * always
- */
- @Override
- protected Object clone() throws CloneNotSupportedException {
- throw new CloneNotSupportedException();
- }
-
- /**
- * Allocates a new {@code Thread} object. This constructor has the same
- * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
- * {@code (null, null, gname)}, where {@code gname} is a newly generated
- * name. Automatically generated names are of the form
- * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
- */
- public Thread() {
- init(null, null, "Thread-" + nextThreadNum(), 0);
- }
-
- /**
- * Allocates a new {@code Thread} object. This constructor has the same
- * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
- * {@code (null, target, gname)}, where {@code gname} is a newly generated
- * name. Automatically generated names are of the form
- * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
- *
- * @param target
- * the object whose {@code run} method is invoked when this thread
- * is started. If {@code null}, this classes {@code run} method does
- * nothing.
- */
- public Thread(Runnable target) {
- init(null, target, "Thread-" + nextThreadNum(), 0);
- }
-
- /**
- * Creates a new Thread that inherits the given AccessControlContext.
- * This is not a public constructor.
- */
- Thread(Runnable target, AccessControlContext acc) {
- init(null, target, "Thread-" + nextThreadNum(), 0, acc);
- }
-
- /**
- * Allocates a new {@code Thread} object. This constructor has the same
- * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
- * {@code (group, target, gname)} ,where {@code gname} is a newly generated
- * name. Automatically generated names are of the form
- * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
- *
- * @param group
- * the thread group. If {@code null} and there is a security
- * manager, the group is determined by {@linkplain
- * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
- * If there is not a security manager or {@code
- * SecurityManager.getThreadGroup()} returns {@code null}, the group
- * is set to the current thread's thread group.
- *
- * @param target
- * the object whose {@code run} method is invoked when this thread
- * is started. If {@code null}, this thread's run method is invoked.
- *
- * @throws SecurityException
- * if the current thread cannot create a thread in the specified
- * thread group
- */
- public Thread(ThreadGroup group, Runnable target) {
- init(group, target, "Thread-" + nextThreadNum(), 0);
- }
-
- /**
- * Allocates a new {@code Thread} object. This constructor has the same
- * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
- * {@code (null, null, name)}.
- *
- * @param name
- * the name of the new thread
- */
- public Thread(String name) {
- init(null, null, name, 0);
- }
-
- /**
- * Allocates a new {@code Thread} object. This constructor has the same
- * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
- * {@code (group, null, name)}.
- *
- * @param group
- * the thread group. If {@code null} and there is a security
- * manager, the group is determined by {@linkplain
- * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
- * If there is not a security manager or {@code
- * SecurityManager.getThreadGroup()} returns {@code null}, the group
- * is set to the current thread's thread group.
- *
- * @param name
- * the name of the new thread
- *
- * @throws SecurityException
- * if the current thread cannot create a thread in the specified
- * thread group
- */
- public Thread(ThreadGroup group, String name) {
- init(group, null, name, 0);
- }
-
- /**
- * Allocates a new {@code Thread} object. This constructor has the same
- * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
- * {@code (null, target, name)}.
- *
- * @param target
- * the object whose {@code run} method is invoked when this thread
- * is started. If {@code null}, this thread's run method is invoked.
- *
- * @param name
- * the name of the new thread
- */
- public Thread(Runnable target, String name) {
- init(null, target, name, 0);
- }
-
- /**
- * Allocates a new {@code Thread} object so that it has {@code target}
- * as its run object, has the specified {@code name} as its name,
- * and belongs to the thread group referred to by {@code group}.
- *
- * <p>If there is a security manager, its
- * {@link SecurityManager#checkAccess(ThreadGroup) checkAccess}
- * method is invoked with the ThreadGroup as its argument.
- *
- * <p>In addition, its {@code checkPermission} method is invoked with
- * the {@code RuntimePermission("enableContextClassLoaderOverride")}
- * permission when invoked directly or indirectly by the constructor
- * of a subclass which overrides the {@code getContextClassLoader}
- * or {@code setContextClassLoader} methods.
- *
- * <p>The priority of the newly created thread is set equal to the
- * priority of the thread creating it, that is, the currently running
- * thread. The method {@linkplain #setPriority setPriority} may be
- * used to change the priority to a new value.
- *
- * <p>The newly created thread is initially marked as being a daemon
- * thread if and only if the thread creating it is currently marked
- * as a daemon thread. The method {@linkplain #setDaemon setDaemon}
- * may be used to change whether or not a thread is a daemon.
- *
- * @param group
- * the thread group. If {@code null} and there is a security
- * manager, the group is determined by {@linkplain
- * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
- * If there is not a security manager or {@code
- * SecurityManager.getThreadGroup()} returns {@code null}, the group
- * is set to the current thread's thread group.
- *
- * @param target
- * the object whose {@code run} method is invoked when this thread
- * is started. If {@code null}, this thread's run method is invoked.
- *
- * @param name
- * the name of the new thread
- *
- * @throws SecurityException
- * if the current thread cannot create a thread in the specified
- * thread group or cannot override the context class loader methods.
- */
- public Thread(ThreadGroup group, Runnable target, String name) {
- init(group, target, name, 0);
- }
-
- /**
- * Allocates a new {@code Thread} object so that it has {@code target}
- * as its run object, has the specified {@code name} as its name,
- * and belongs to the thread group referred to by {@code group}, and has
- * the specified <i>stack size</i>.
- *
- * <p>This constructor is identical to {@link
- * #Thread(ThreadGroup,Runnable,String)} with the exception of the fact
- * that it allows the thread stack size to be specified. The stack size
- * is the approximate number of bytes of address space that the virtual
- * machine is to allocate for this thread's stack. <b>The effect of the
- * {@code stackSize} parameter, if any, is highly platform dependent.</b>
- *
- * <p>On some platforms, specifying a higher value for the
- * {@code stackSize} parameter may allow a thread to achieve greater
- * recursion depth before throwing a {@link StackOverflowError}.
- * Similarly, specifying a lower value may allow a greater number of
- * threads to exist concurrently without throwing an {@link
- * OutOfMemoryError} (or other internal error). The details of
- * the relationship between the value of the <tt>stackSize</tt> parameter
- * and the maximum recursion depth and concurrency level are
- * platform-dependent. <b>On some platforms, the value of the
- * {@code stackSize} parameter may have no effect whatsoever.</b>
- *
- * <p>The virtual machine is free to treat the {@code stackSize}
- * parameter as a suggestion. If the specified value is unreasonably low
- * for the platform, the virtual machine may instead use some
- * platform-specific minimum value; if the specified value is unreasonably
- * high, the virtual machine may instead use some platform-specific
- * maximum. Likewise, the virtual machine is free to round the specified
- * value up or down as it sees fit (or to ignore it completely).
- *
- * <p>Specifying a value of zero for the {@code stackSize} parameter will
- * cause this constructor to behave exactly like the
- * {@code Thread(ThreadGroup, Runnable, String)} constructor.
- *
- * <p><i>Due to the platform-dependent nature of the behavior of this
- * constructor, extreme care should be exercised in its use.
- * The thread stack size necessary to perform a given computation will
- * likely vary from one JRE implementation to another. In light of this
- * variation, careful tuning of the stack size parameter may be required,
- * and the tuning may need to be repeated for each JRE implementation on
- * which an application is to run.</i>
- *
- * <p>Implementation note: Java platform implementers are encouraged to
- * document their implementation's behavior with respect to the
- * {@code stackSize} parameter.
- *
- *
- * @param group
- * the thread group. If {@code null} and there is a security
- * manager, the group is determined by {@linkplain
- * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
- * If there is not a security manager or {@code
- * SecurityManager.getThreadGroup()} returns {@code null}, the group
- * is set to the current thread's thread group.
- *
- * @param target
- * the object whose {@code run} method is invoked when this thread
- * is started. If {@code null}, this thread's run method is invoked.
- *
- * @param name
- * the name of the new thread
- *
- * @param stackSize
- * the desired stack size for the new thread, or zero to indicate
- * that this parameter is to be ignored.
- *
- * @throws SecurityException
- * if the current thread cannot create a thread in the specified
- * thread group
- *
- * @since 1.4
- */
- public Thread(ThreadGroup group, Runnable target, String name,
- long stackSize) {
- init(group, target, name, stackSize);
- }
-
- /**
- * Causes this thread to begin execution; the Java Virtual Machine
- * calls the <code>run</code> method of this thread.
- * <p>
- * The result is that two threads are running concurrently: the
- * current thread (which returns from the call to the
- * <code>start</code> method) and the other thread (which executes its
- * <code>run</code> method).
- * <p>
- * It is never legal to start a thread more than once.
- * In particular, a thread may not be restarted once it has completed
- * execution.
- *
- * @exception IllegalThreadStateException if the thread was already
- * started.
- * @see #run()
- * @see #stop()
- */
- public synchronized void start() {
- /**
- * This method is not invoked for the main method thread or "system"
- * group threads created/set up by the VM. Any new functionality added
- * to this method in the future may have to also be added to the VM.
- *
- * A zero status value corresponds to state "NEW".
- */
- if (threadStatus != 0)
- throw new IllegalThreadStateException();
-
- /* Notify the group that this thread is about to be started
- * so that it can be added to the group's list of threads
- * and the group's unstarted count can be decremented. */
- group.add(this);
-
- boolean started = false;
- try {
- start0();
- started = true;
- } finally {
- try {
- if (!started) {
- group.threadStartFailed(this);
- }
- } catch (Throwable ignore) {
- /* do nothing. If start0 threw a Throwable then
- it will be passed up the call stack */
- }
- }
- }
-
- private void start0() {
- cli.System.Threading.ThreadStart threadStart = new cli.System.Threading.ThreadStart(new cli.System.Threading.ThreadStart.Method() {
- @cli.IKVM.Attributes.HideFromJavaAttribute.Annotation
- public void Invoke() {
- threadProc();
- }
- });
- if (stackSize <= 0) {
- nativeThread = new cli.System.Threading.Thread(threadStart);
- }
- else {
- int maxStackSize = (int)Math.min(Math.max(128 * 1024, stackSize), Integer.MAX_VALUE);
- nativeThread = new cli.System.Threading.Thread(threadStart, maxStackSize);
- }
- nativeThread.set_Name(getName());
- nativeThread.set_IsBackground(daemon);
- nativeThread.set_Priority(cli.System.Threading.ThreadPriority.wrap(mapJavaPriorityToClr(priority)));
- String apartment = Props.props.getProperty("ikvm.apartmentstate", "").toLowerCase();
- if ("mta".equals(apartment)) {
- nativeThread.SetApartmentState(cli.System.Threading.ApartmentState.wrap(cli.System.Threading.ApartmentState.MTA));
- }
- else if ("sta".equals(apartment)) {
- nativeThread.SetApartmentState(cli.System.Threading.ApartmentState.wrap(cli.System.Threading.ApartmentState.STA));
- }
- threadStatus = 0x0005; // JVMTI_THREAD_STATE_ALIVE + JVMTI_THREAD_STATE_RUNNABLE
- nativeThread.Start();
- if (!daemon) {
- cli.System.Threading.Interlocked.Increment(nonDaemonCount);
- }
- }
-
- /**
- * If this thread was constructed using a separate
- * <code>Runnable</code> run object, then that
- * <code>Runnable</code> object's <code>run</code> method is called;
- * otherwise, this method does nothing and returns.
- * <p>
- * Subclasses of <code>Thread</code> should override this method.
- *
- * @see #start()
- * @see #stop()
- * @see #Thread(ThreadGroup, Runnable, String)
- */
- @Override
- public void run() {
- if (target != null) {
- target.run();
- }
- }
-
- // [IKVM] for threads started from Java, this method is called on the thread itself,
- // but for .NET threads it will be called by the finalizer of the Cleanup object.
- // NOTE there might be a race condition here (when the thread's Cleanup object
- // is finalized during AppDomain shutdown while the thread is also exiting on its own),
- // but that doesn't matter because Thread.exit() is safe to call multiple times.
- void die() {
- exit();
- synchronized (lock) {
- nativeThread = null;
- threadStatus = 0x0002; // JVMTI_THREAD_STATE_TERMINATED
- }
- wakeupJoinedThreads();
- if (!daemon) {
- // TODO there is a race condition in the non-daemon counting
- // (setDaemon() isn't synchronized so it may clear/set the daemon flag without the count being affected)
- cli.System.Threading.Interlocked.Decrement(nonDaemonCount);
- }
- if (current == this) {
- current = null;
- // check if we have a cleanup object, this happens if we attach and subsequently detach from JNI code
- if (cleanup != null) {
- cli.System.GC.SuppressFinalize(cleanup);
- cleanup = null;
- }
- }
- }
-
- private void wakeupJoinedThreads() {
- // HACK locking this here isn't ideal, because we might be invoked from
- // the Cleanup object's finalizer and some user code might own the lock and hence
- // block the finalizer thread.
- // A second scenario is that another thread is currently blocking inside stop()
- // (the Thread.Abort() call will block while we are running the finally block)
- // and that thread will own the lock on our thread object.
- boolean locked = false;
- try {
- locked = cli.System.Threading.Monitor.TryEnter(this);
- if (locked) {
- notifyAll();
- } else {
- // HACK schedule an asynchronous notification
- cli.System.Threading.ThreadPool.QueueUserWorkItem(
- new cli.System.Threading.WaitCallback(
- new cli.System.Threading.WaitCallback.Method() {
- public void Invoke(Object thread) {
- synchronized (thread) {
- thread.notifyAll();
- }
- }
- }), this);
- }
- }
- finally {
- if (locked)
- cli.System.Threading.Monitor.Exit(this);
- }
- }
-
- /**
- * This method is called by the system to give a Thread
- * a chance to clean up before it actually exits.
- */
- private void exit() {
- if (group != null) {
- group.threadTerminated(this);
- group = null;
- }
- /* Aggressively null out all reference fields: see bug 4006245 */
- target = null;
- /* Speed the release of some of these resources */
- threadLocals = null;
- inheritableThreadLocals = null;
- inheritedAccessControlContext = null;
- blocker = null;
- uncaughtExceptionHandler = null;
- }
-
- /**
- * Forces the thread to stop executing.
- * <p>
- * If there is a security manager installed, its <code>checkAccess</code>
- * method is called with <code>this</code>
- * as its argument. This may result in a
- * <code>SecurityException</code> being raised (in the current thread).
- * <p>
- * If this thread is different from the current thread (that is, the current
- * thread is trying to stop a thread other than itself), the
- * security manager's <code>checkPermission</code> method (with a
- * <code>RuntimePermission("stopThread")</code> argument) is called in
- * addition.
- * Again, this may result in throwing a
- * <code>SecurityException</code> (in the current thread).
- * <p>
- * The thread represented by this thread is forced to stop whatever
- * it is doing abnormally and to throw a newly created
- * <code>ThreadDeath</code> object as an exception.
- * <p>
- * It is permitted to stop a thread that has not yet been started.
- * If the thread is eventually started, it immediately terminates.
- * <p>
- * An application should not normally try to catch
- * <code>ThreadDeath</code> unless it must do some extraordinary
- * cleanup operation (note that the throwing of
- * <code>ThreadDeath</code> causes <code>finally</code> clauses of
- * <code>try</code> statements to be executed before the thread
- * officially dies). If a <code>catch</code> clause catches a
- * <code>ThreadDeath</code> object, it is important to rethrow the
- * object so that the thread actually dies.
- * <p>
- * The top-level error handler that reacts to otherwise uncaught
- * exceptions does not print out a message or otherwise notify the
- * application if the uncaught exception is an instance of
- * <code>ThreadDeath</code>.
- *
- * @exception SecurityException if the current thread cannot
- * modify this thread.
- * @see #interrupt()
- * @see #checkAccess()
- * @see #run()
- * @see #start()
- * @see ThreadDeath
- * @see ThreadGroup#uncaughtException(Thread,Throwable)
- * @see SecurityManager#checkAccess(Thread)
- * @see SecurityManager#checkPermission
- * @deprecated This method is inherently unsafe. Stopping a thread with
- * Thread.stop causes it to unlock all of the monitors that it
- * has locked (as a natural consequence of the unchecked
- * <code>ThreadDeath</code> exception propagating up the stack). If
- * any of the objects previously protected by these monitors were in
- * an inconsistent state, the damaged objects become visible to
- * other threads, potentially resulting in arbitrary behavior. Many
- * uses of <code>stop</code> should be replaced by code that simply
- * modifies some variable to indicate that the target thread should
- * stop running. The target thread should check this variable
- * regularly, and return from its run method in an orderly fashion
- * if the variable indicates that it is to stop running. If the
- * target thread waits for long periods (on a condition variable,
- * for example), the <code>interrupt</code> method should be used to
- * interrupt the wait.
- * For more information, see
- * <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
- * are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
- */
- @Deprecated
- public final void stop() {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- checkAccess();
- if (this != Thread.currentThread()) {
- security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
- }
- }
- // A zero status value corresponds to "NEW", it can't change to
- // not-NEW because we hold the lock.
- if (threadStatus != 0) {
- resume(); // Wake up thread if it was suspended; no-op otherwise
- }
-
- // The VM can handle all thread states
- stop0(new ThreadDeath());
- }
-
- /**
- * Throws {@code UnsupportedOperationException}.
- *
- * @param obj ignored
- *
- * @deprecated This method was originally designed to force a thread to stop
- * and throw a given {@code Throwable} as an exception. It was
- * inherently unsafe (see {@link #stop()} for details), and furthermore
- * could be used to generate exceptions that the target thread was
- * not prepared to handle.
- * For more information, see
- * <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
- * are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
- */
- @Deprecated
- public final synchronized void stop(Throwable obj) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Interrupts this thread.
- *
- * <p> Unless the current thread is interrupting itself, which is
- * always permitted, the {@link #checkAccess() checkAccess} method
- * of this thread is invoked, which may cause a {@link
- * SecurityException} to be thrown.
- *
- * <p> If this thread is blocked in an invocation of the {@link
- * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link
- * Object#wait(long, int) wait(long, int)} methods of the {@link Object}
- * class, or of the {@link #join()}, {@link #join(long)}, {@link
- * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},
- * methods of this class, then its interrupt status will be cleared and it
- * will receive an {@link InterruptedException}.
- *
- * <p> If this thread is blocked in an I/O operation upon an {@link
- * java.nio.channels.InterruptibleChannel InterruptibleChannel}
- * then the channel will be closed, the thread's interrupt
- * status will be set, and the thread will receive a {@link
- * java.nio.channels.ClosedByInterruptException}.
- *
- * <p> If this thread is blocked in a {@link java.nio.channels.Selector}
- * then the thread's interrupt status will be set and it will return
- * immediately from the selection operation, possibly with a non-zero
- * value, just as if the selector's {@link
- * java.nio.channels.Selector#wakeup wakeup} method were invoked.
- *
- * <p> If none of the previous conditions hold then this thread's interrupt
- * status will be set. </p>
- *
- * <p> Interrupting a thread that is not alive need not have any effect.
- *
- * @throws SecurityException
- * if the current thread cannot modify this thread
- *
- * @revised 6.0
- * @spec JSR-51
- */
- public void interrupt() {
- if (this != Thread.currentThread())
- checkAccess();
-
- synchronized (blockerLock) {
- Interruptible b = blocker;
- if (b != null) {
- interrupt0(); // Just to set the interrupt flag
- b.interrupt(this);
- return;
- }
- }
- interrupt0();
- }
-
- /**
- * Tests whether the current thread has been interrupted. The
- * <i>interrupted status</i> of the thread is cleared by this method. In
- * other words, if this method were to be called twice in succession, the
- * second call would return false (unless the current thread were
- * interrupted again, after the first call had cleared its interrupted
- * status and before the second call had examined it).
- *
- * <p>A thread interruption ignored because a thread was not alive
- * at the time of the interrupt will be reflected by this method
- * returning false.
- *
- * @return <code>true</code> if the current thread has been interrupted;
- * <code>false</code> otherwise.
- * @see #isInterrupted()
- * @revised 6.0
- */
- public static boolean interrupted() {
- Thread current = currentThread();
- if (!current.interruptPending) {
- return false;
- }
- current.interruptPending = false;
- return true;
- }
-
- /**
- * Tests whether this thread has been interrupted. The <i>interrupted
- * status</i> of the thread is unaffected by this method.
- *
- * <p>A thread interruption ignored because a thread was not alive
- * at the time of the interrupt will be reflected by this method
- * returning false.
- *
- * @return <code>true</code> if this thread has been interrupted;
- * <code>false</code> otherwise.
- * @see #interrupted()
- * @revised 6.0
- */
- public boolean isInterrupted() {
- return interruptPending;
- }
-
- /**
- * Throws {@link NoSuchMethodError}.
- *
- * @deprecated This method was originally designed to destroy this
- * thread without any cleanup. Any monitors it held would have
- * remained locked. However, the method was never implemented.
- * If if were to be implemented, it would be deadlock-prone in
- * much the manner of {@link #suspend}. If the target thread held
- * a lock protecting a critical system resource when it was
- * destroyed, no thread could ever access this resource again.
- * If another thread ever attempted to lock this resource, deadlock
- * would result. Such deadlocks typically manifest themselves as
- * "frozen" processes. For more information, see
- * <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">
- * Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
- * @throws NoSuchMethodError always
- */
- @Deprecated
- public void destroy() {
- throw new NoSuchMethodError();
- }
-
- /**
- * Tests if this thread is alive. A thread is alive if it has
- * been started and has not yet died.
- *
- * @return <code>true</code> if this thread is alive;
- * <code>false</code> otherwise.
- */
- public final boolean isAlive() {
- return (threadStatus & 0x0001) != 0;
- }
-
- /**
- * Suspends this thread.
- * <p>
- * First, the <code>checkAccess</code> method of this thread is called
- * with no arguments. This may result in throwing a
- * <code>SecurityException </code>(in the current thread).
- * <p>
- * If the thread is alive, it is suspended and makes no further
- * progress unless and until it is resumed.
- *
- * @exception SecurityException if the current thread cannot modify
- * this thread.
- * @see #checkAccess
- * @deprecated This method has been deprecated, as it is
- * inherently deadlock-prone. If the target thread holds a lock on the
- * monitor protecting a critical system resource when it is suspended, no
- * thread can access this resource until the target thread is resumed. If
- * the thread that would resume the target thread attempts to lock this
- * monitor prior to calling <code>resume</code>, deadlock results. Such
- * deadlocks typically manifest themselves as "frozen" processes.
- * For more information, see
- * <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
- * are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
- */
- @Deprecated
- public final void suspend() {
- checkAccess();
- suspend0();
- }
-
- /**
- * Resumes a suspended thread.
- * <p>
- * First, the <code>checkAccess</code> method of this thread is called
- * with no arguments. This may result in throwing a
- * <code>SecurityException</code> (in the current thread).
- * <p>
- * If the thread is alive but suspended, it is resumed and is
- * permitted to make progress in its execution.
- *
- * @exception SecurityException if the current thread cannot modify this
- * thread.
- * @see #checkAccess
- * @see #suspend()
- * @deprecated This method exists solely for use with {@link #suspend},
- * which has been deprecated because it is deadlock-prone.
- * For more information, see
- * <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
- * are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
- */
- @Deprecated
- public final void resume() {
- checkAccess();
- resume0();
- }
-
- /**
- * Changes the priority of this thread.
- * <p>
- * First the <code>checkAccess</code> method of this thread is called
- * with no arguments. This may result in throwing a
- * <code>SecurityException</code>.
- * <p>
- * Otherwise, the priority of this thread is set to the smaller of
- * the specified <code>newPriority</code> and the maximum permitted
- * priority of the thread's thread group.
- *
- * @param newPriority priority to set this thread to
- * @exception IllegalArgumentException If the priority is not in the
- * range <code>MIN_PRIORITY</code> to
- * <code>MAX_PRIORITY</code>.
- * @exception SecurityException if the current thread cannot modify
- * this thread.
- * @see #getPriority
- * @see #checkAccess()
- * @see #getThreadGroup()
- * @see #MAX_PRIORITY
- * @see #MIN_PRIORITY
- * @see ThreadGroup#getMaxPriority()
- */
- public final void setPriority(int newPriority) {
- ThreadGroup g;
- checkAccess();
- if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
- throw new IllegalArgumentException();
- }
- if((g = getThreadGroup()) != null) {
- if (newPriority > g.getMaxPriority()) {
- newPriority = g.getMaxPriority();
- }
- setPriority0(priority = newPriority);
- }
- }
-
- /**
- * Returns this thread's priority.
- *
- * @return this thread's priority.
- * @see #setPriority
- */
- public final int getPriority() {
- return priority;
- }
-
- /**
- * Changes the name of this thread to be equal to the argument
- * <code>name</code>.
- * <p>
- * First the <code>checkAccess</code> method of this thread is called
- * with no arguments. This may result in throwing a
- * <code>SecurityException</code>.
- *
- * @param name the new name for this thread.
- * @exception SecurityException if the current thread cannot modify this
- * thread.
- * @see #getName
- * @see #checkAccess()
- */
- public final synchronized void setName(String name) {
- checkAccess();
- this.name = name.toCharArray();
- if (threadStatus != 0) {
- setNativeName(name);
- }
- }
-
- /**
- * Returns this thread's name.
- *
- * @return this thread's name.
- * @see #setName(String)
- */
- public final String getName() {
- return String.valueOf(name);
- }
-
- /**
- * Returns the thread group to which this thread belongs.
- * This method returns null if this thread has died
- * (been stopped).
- *
- * @return this thread's thread group.
- */
- public final ThreadGroup getThreadGroup() {
- return group;
- }
-
- /**
- * Returns an estimate of the number of active threads in the current
- * thread's {@linkplain java.lang.ThreadGroup thread group} and its
- * subgroups. Recursively iterates over all subgroups in the current
- * thread's thread group.
- *
- * <p> The value returned is only an estimate because the number of
- * threads may change dynamically while this method traverses internal
- * data structures, and might be affected by the presence of certain
- * system threads. This method is intended primarily for debugging
- * and monitoring purposes.
- *
- * @return an estimate of the number of active threads in the current
- * thread's thread group and in any other thread group that
- * has the current thread's thread group as an ancestor
- */
- public static int activeCount() {
- return currentThread().getThreadGroup().activeCount();
- }
-
- /**
- * Copies into the specified array every active thread in the current
- * thread's thread group and its subgroups. This method simply
- * invokes the {@link java.lang.ThreadGroup#enumerate(Thread[])}
- * method of the current thread's thread group.
- *
- * <p> An application might use the {@linkplain #activeCount activeCount}
- * method to get an estimate of how big the array should be, however
- * <i>if the array is too short to hold all the threads, the extra threads
- * are silently ignored.</i> If it is critical to obtain every active
- * thread in the current thread's thread group and its subgroups, the
- * invoker should verify that the returned int value is strictly less
- * than the length of {@code tarray}.
- *
- * <p> Due to the inherent race condition in this method, it is recommended
- * that the method only be used for debugging and monitoring purposes.
- *
- * @param tarray
- * an array into which to put the list of threads
- *
- * @return the number of threads put into the array
- *
- * @throws SecurityException
- * if {@link java.lang.ThreadGroup#checkAccess} determines that
- * the current thread cannot access its thread group
- */
- public static int enumerate(Thread tarray[]) {
- return currentThread().getThreadGroup().enumerate(tarray);
- }
-
- /**
- * Counts the number of stack frames in this thread. The thread must
- * be suspended.
- *
- * @return the number of stack frames in this thread.
- * @exception IllegalThreadStateException if this thread is not
- * suspended.
- * @deprecated The definition of this call depends on {@link #suspend},
- * which is deprecated. Further, the results of this call
- * were never well-defined.
- */
- @Deprecated
- public int countStackFrames() {
- return 0;
- }
-
- /**
- * Waits at most {@code millis} milliseconds for this thread to
- * die. A timeout of {@code 0} means to wait forever.
- *
- * <p> This implementation uses a loop of {@code this.wait} calls
- * conditioned on {@code this.isAlive}. As a thread terminates the
- * {@code this.notifyAll} method is invoked. It is recommended that
- * applications not use {@code wait}, {@code notify}, or
- * {@code notifyAll} on {@code Thread} instances.
- *
- * @param millis
- * the time to wait in milliseconds
- *
- * @throws IllegalArgumentException
- * if the value of {@code millis} is negative
- *
- * @throws InterruptedException
- * if any thread has interrupted the current thread. The
- * <i>interrupted status</i> of the current thread is
- * cleared when this exception is thrown.
- */
- public final synchronized void join(long millis)
- throws InterruptedException {
- long base = System.currentTimeMillis();
- long now = 0;
-
- if (millis < 0) {
- throw new IllegalArgumentException("timeout value is negative");
- }
-
- if (millis == 0) {
- while (isAlive()) {
- wait(0);
- }
- } else {
- while (isAlive()) {
- long delay = millis - now;
- if (delay <= 0) {
- break;
- }
- wait(delay);
- now = System.currentTimeMillis() - base;
- }
- }
- }
-
- /**
- * Waits at most {@code millis} milliseconds plus
- * {@code nanos} nanoseconds for this thread to die.
- *
- * <p> This implementation uses a loop of {@code this.wait} calls
- * conditioned on {@code this.isAlive}. As a thread terminates the
- * {@code this.notifyAll} method is invoked. It is recommended that
- * applications not use {@code wait}, {@code notify}, or
- * {@code notifyAll} on {@code Thread} instances.
- *
- * @param millis
- * the time to wait in milliseconds
- *
- * @param nanos
- * {@code 0-999999} additional nanoseconds to wait
- *
- * @throws IllegalArgumentException
- * if the value of {@code millis} is negative, or the value
- * of {@code nanos} is not in the range {@code 0-999999}
- *
- * @throws InterruptedException
- * if any thread has interrupted the current thread. The
- * <i>interrupted status</i> of the current thread is
- * cleared when this exception is thrown.
- */
- public final synchronized void join(long millis, int nanos)
- throws InterruptedException {
-
- if (millis < 0) {
- throw new IllegalArgumentException("timeout value is negative");
- }
-
- if (nanos < 0 || nanos > 999999) {
- throw new IllegalArgumentException(
- "nanosecond timeout value out of range");
- }
-
- if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
- millis++;
- }
-
- join(millis);
- }
-
- /**
- * Waits for this thread to die.
- *
- * <p> An invocation of this method behaves in exactly the same
- * way as the invocation
- *
- * <blockquote>
- * {@linkplain #join(long) join}{@code (0)}
- * </blockquote>
- *
- * @throws InterruptedException
- * if any thread has interrupted the current thread. The
- * <i>interrupted status</i> of the current thread is
- * cleared when this exception is thrown.
- */
- public final void join() throws InterruptedException {
- join(0);
- }
-
- /**
- * Prints a stack trace of the current thread to the standard error stream.
- * This method is used only for debugging.
- *
- * @see Throwable#printStackTrace()
- */
- public static void dumpStack() {
- new Exception("Stack trace").printStackTrace();
- }
-
- /**
- * Marks this thread as either a {@linkplain #isDaemon daemon} thread
- * or a user thread. The Java Virtual Machine exits when the only
- * threads running are all daemon threads.
- *
- * <p> This method must be invoked before the thread is started.
- *
- * @param on
- * if {@code true}, marks this thread as a daemon thread
- *
- * @throws IllegalThreadStateException
- * if this thread is {@linkplain #isAlive alive}
- *
- * @throws SecurityException
- * if {@link #checkAccess} determines that the current
- * thread cannot modify this thread
- */
- public final void setDaemon(boolean on) {
- checkAccess();
- if (isAlive()) {
- throw new IllegalThreadStateException();
- }
- daemon = on;
- }
-
- /**
- * Tests if this thread is a daemon thread.
- *
- * @return <code>true</code> if this thread is a daemon thread;
- * <code>false</code> otherwise.
- * @see #setDaemon(boolean)
- */
- public final boolean isDaemon() {
- return daemon;
- }
-
- /**
- * Determines if the currently running thread has permission to
- * modify this thread.
- * <p>
- * If there is a security manager, its <code>checkAccess</code> method
- * is called with this thread as its argument. This may result in
- * throwing a <code>SecurityException</code>.
- *
- * @exception SecurityException if the current thread is not allowed to
- * access this thread.
- * @see SecurityManager#checkAccess(Thread)
- */
- public final void checkAccess() {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkAccess(this);
- }
- }
-
- /**
- * Returns a string representation of this thread, including the
- * thread's name, priority, and thread group.
- *
- * @return a string representation of this thread.
- */
- public String toString() {
- ThreadGroup group = getThreadGroup();
- if (group != null) {
- return "Thread[" + getName() + "," + getPriority() + "," +
- group.getName() + "]";
- } else {
- return "Thread[" + getName() + "," + getPriority() + "," +
- "" + "]";
- }
- }
-
- /**
- * Returns the context ClassLoader for this Thread. The context
- * ClassLoader is provided by the creator of the thread for use
- * by code running in this thread when loading classes and resources.
- * If not {@linkplain #setContextClassLoader set}, the default is the
- * ClassLoader context of the parent Thread. The context ClassLoader of the
- * primordial thread is typically set to the class loader used to load the
- * application.
- *
- * <p>If a security manager is present, and the invoker's class loader is not
- * {@code null} and is not the same as or an ancestor of the context class
- * loader, then this method invokes the security manager's {@link
- * SecurityManager#checkPermission(java.security.Permission) checkPermission}
- * method with a {@link RuntimePermission RuntimePermission}{@code
- * ("getClassLoader")} permission to verify that retrieval of the context
- * class loader is permitted.
- *
- * @return the context ClassLoader for this Thread, or {@code null}
- * indicating the system class loader (or, failing that, the
- * bootstrap class loader)
- *
- * @throws SecurityException
- * if the current thread cannot get the context ClassLoader
- *
- * @since 1.2
- */
- @CallerSensitive
- public ClassLoader getContextClassLoader() {
- if (contextClassLoader == ClassLoader.DUMMY) {
- contextClassLoader = ClassLoader.getSystemClassLoader();
- }
- if (contextClassLoader == null)
- return null;
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- ClassLoader.checkClassLoaderPermission(contextClassLoader,
- Reflection.getCallerClass());
- }
- return contextClassLoader;
- }
-
- /**
- * Sets the context ClassLoader for this Thread. The context
- * ClassLoader can be set when a thread is created, and allows
- * the creator of the thread to provide the appropriate class loader,
- * through {@code getContextClassLoader}, to code running in the thread
- * when loading classes and resources.
- *
- * <p>If a security manager is present, its {@link
- * SecurityManager#checkPermission(java.security.Permission) checkPermission}
- * method is invoked with a {@link RuntimePermission RuntimePermission}{@code
- * ("setContextClassLoader")} permission to see if setting the context
- * ClassLoader is permitted.
- *
- * @param cl
- * the context ClassLoader for this Thread, or null indicating the
- * system class loader (or, failing that, the bootstrap class loader)
- *
- * @throws SecurityException
- * if the current thread cannot set the context ClassLoader
- *
- * @since 1.2
- */
- public void setContextClassLoader(ClassLoader cl) {
- if (cl == ClassLoader.DUMMY) {
- // we're being called by Thread.<clinit> to force this method to be JIT compiled
- return;
- }
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new RuntimePermission("setContextClassLoader"));
- }
- contextClassLoader = cl;
- }
-
- // [IKVM] called by sun.misc.Launcher (via map.xml patch) to initialize the context class loader
- final void initContextClassLoader(ClassLoader cl) {
- // we only set contextClassLoader if it hasn't been set (by user code) previously
- java.util.concurrent.atomic.AtomicReferenceFieldUpdater
- .newUpdater(Thread.class, ClassLoader.class, "contextClassLoader")
- .compareAndSet(this, ClassLoader.DUMMY, cl);
- }
-
- /**
- * Returns <tt>true</tt> if and only if the current thread holds the
- * monitor lock on the specified object.
- *
- * <p>This method is designed to allow a program to assert that
- * the current thread already holds a specified lock:
- * <pre>
- * assert Thread.holdsLock(obj);
- * </pre>
- *
- * @param obj the object on which to test lock ownership
- * @throws NullPointerException if obj is <tt>null</tt>
- * @return <tt>true</tt> if the current thread holds the monitor lock on
- * the specified object.
- * @since 1.4
- */
- public static boolean holdsLock(Object obj) {
- if (obj == null) {
- throw new NullPointerException();
- }
- try {
- if (false) throw new cli.System.Threading.SynchronizationLockException();
- // The 1.5 memory model (JSR133) explicitly allows spurious wake-ups from Object.wait,
- // so we abuse Pulse to check if we own the monitor.
- cli.System.Threading.Monitor.Pulse(obj);
- return true;
- }
- catch (cli.System.Threading.SynchronizationLockException _) {
- return false;
- }
- }
-
- private static final StackTraceElement[] EMPTY_STACK_TRACE
- = new StackTraceElement[0];
-
- /**
- * Returns an array of stack trace elements representing the stack dump
- * of this thread. This method will return a zero-length array if
- * this thread has not started, has started but has not yet been
- * scheduled to run by the system, or has terminated.
- * If the returned array is of non-zero length then the first element of
- * the array represents the top of the stack, which is the most recent
- * method invocation in the sequence. The last element of the array
- * represents the bottom of the stack, which is the least recent method
- * invocation in the sequence.
- *
- * <p>If there is a security manager, and this thread is not
- * the current thread, then the security manager's
- * <tt>checkPermission</tt> method is called with a
- * <tt>RuntimePermission("getStackTrace")</tt> permission
- * to see if it's ok to get the stack trace.
- *
- * <p>Some virtual machines may, under some circumstances, omit one
- * or more stack frames from the stack trace. In the extreme case,
- * a virtual machine that has no stack trace information concerning
- * this thread is permitted to return a zero-length array from this
- * method.
- *
- * @return an array of <tt>StackTraceElement</tt>,
- * each represents one stack frame.
- *
- * @throws SecurityException
- * if a security manager exists and its
- * <tt>checkPermission</tt> method doesn't allow
- * getting the stack trace of thread.
- * @see SecurityManager#checkPermission
- * @see RuntimePermission
- * @see Throwable#getStackTrace
- *
- * @since 1.5
- */
- public StackTraceElement[] getStackTrace() {
- if (this != Thread.currentThread()) {
- // check for getStackTrace permission
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkPermission(
- SecurityConstants.GET_STACK_TRACE_PERMISSION);
- }
- // optimization so we do not call into the vm for threads that
- // have not yet started or have terminated
- if (!isAlive()) {
- return EMPTY_STACK_TRACE;
- }
- StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});
- StackTraceElement[] stackTrace = stackTraceArray[0];
- // a thread that was alive during the previous isAlive call may have
- // since terminated, therefore not having a stacktrace.
- if (stackTrace == null) {
- stackTrace = EMPTY_STACK_TRACE;
- }
- return stackTrace;
- } else {
- // Don't need JVM help for current thread
- return (new Exception()).getStackTrace();
- }
- }
-
- /**
- * Returns a map of stack traces for all live threads.
- * The map keys are threads and each map value is an array of
- * <tt>StackTraceElement</tt> that represents the stack dump
- * of the corresponding <tt>Thread</tt>.
- * The returned stack traces are in the format specified for
- * the {@link #getStackTrace getStackTrace} method.
- *
- * <p>The threads may be executing while this method is called.
- * The stack trace of each thread only represents a snapshot and
- * each stack trace may be obtained at different time. A zero-length
- * array will be returned in the map value if the virtual machine has
- * no stack trace information about a thread.
- *
- * <p>If there is a security manager, then the security manager's
- * <tt>checkPermission</tt> method is called with a
- * <tt>RuntimePermission("getStackTrace")</tt> permission as well as
- * <tt>RuntimePermission("modifyThreadGroup")</tt> permission
- * to see if it is ok to get the stack trace of all threads.
- *
- * @return a <tt>Map</tt> from <tt>Thread</tt> to an array of
- * <tt>StackTraceElement</tt> that represents the stack trace of
- * the corresponding thread.
- *
- * @throws SecurityException
- * if a security manager exists and its
- * <tt>checkPermission</tt> method doesn't allow
- * getting the stack trace of thread.
- * @see #getStackTrace
- * @see SecurityManager#checkPermission
- * @see RuntimePermission
- * @see Throwable#getStackTrace
- *
- * @since 1.5
- */
- public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
- // check for getStackTrace permission
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkPermission(
- SecurityConstants.GET_STACK_TRACE_PERMISSION);
- security.checkPermission(
- SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
- }
-
- // Get a snapshot of the list of all threads
- Thread[] threads = getThreads();
- StackTraceElement[][] traces = dumpThreads(threads);
- Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
- for (int i = 0; i < threads.length; i++) {
- StackTraceElement[] stackTrace = traces[i];
- if (stackTrace != null) {
- m.put(threads[i], stackTrace);
- }
- // else terminated so we don't put it in the map
- }
- return m;
- }
-
-
- private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
- new RuntimePermission("enableContextClassLoaderOverride");
-
- /** cache of subclass security audit results */
- /* Replace with ConcurrentReferenceHashMap when/if it appears in a future
- * release */
- private static class Caches {
- /** cache of subclass security audit results */
- static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
- new ConcurrentHashMap<>();
-
- /** queue for WeakReferences to audited subclasses */
- static final ReferenceQueue<Class<?>> subclassAuditsQueue =
- new ReferenceQueue<>();
- }
-
- /**
- * Verifies that this (possibly subclass) instance can be constructed
- * without violating security constraints: the subclass must not override
- * security-sensitive non-final methods, or else the
- * "enableContextClassLoaderOverride" RuntimePermission is checked.
- */
- @cli.System.Runtime.CompilerServices.MethodImplAttribute.Annotation(value = cli.System.Runtime.CompilerServices.MethodImplOptions.__Enum.NoInlining)
- private static native boolean isCCLOverridden(Thread thread); // [IKVM] implemented in map.xml
-
- private static boolean isCCLOverridden(Class<?> cl) {
- if (cl == Thread.class)
- return false;
-
- processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
- WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
- Boolean result = Caches.subclassAudits.get(key);
- if (result == null) {
- result = Boolean.valueOf(auditSubclass(cl));
- Caches.subclassAudits.putIfAbsent(key, result);
- }
-
- return result.booleanValue();
- }
-
- /**
- * Performs reflective checks on given subclass to verify that it doesn't
- * override security-sensitive non-final methods. Returns true if the
- * subclass overrides any of the methods, false otherwise.
- */
- private static boolean auditSubclass(final Class<?> subcl) {
- Boolean result = AccessController.doPrivileged(
- new PrivilegedAction<Boolean>() {
- public Boolean run() {
- for (Class<?> cl = subcl;
- cl != Thread.class;
- cl = cl.getSuperclass())
- {
- try {
- cl.getDeclaredMethod("getContextClassLoader", new Class<?>[0]);
- return Boolean.TRUE;
- } catch (NoSuchMethodException ex) {
- }
- try {
- Class<?>[] params = {ClassLoader.class};
- cl.getDeclaredMethod("setContextClassLoader", params);
- return Boolean.TRUE;
- } catch (NoSuchMethodException ex) {
- }
- }
- return Boolean.FALSE;
- }
- }
- );
- return result.booleanValue();
- }
-
- private static StackTraceElement[][] dumpThreads(Thread[] threads) {
- StackTraceElement[][] stacks = new StackTraceElement[threads.length][];
- for (int i = 0; i < threads.length; i++) {
- cli.System.Threading.Thread nativeThread = threads[i].nativeThread;
- if (nativeThread == null) {
- stacks[i] = new StackTraceElement[0];
- } else {
- try {
- if (false) throw new cli.System.Threading.ThreadStateException();
- boolean suspended = false;
- if ((nativeThread.get_ThreadState().Value & cli.System.Threading.ThreadState.Suspended) == 0 && nativeThread != cli.System.Threading.Thread.get_CurrentThread()) {
- suspended = true;
- nativeThread.Suspend();
- }
- cli.System.Diagnostics.StackTrace stack;
- try {
- stack = new cli.System.Diagnostics.StackTrace(nativeThread, true);
- }
- finally {
- if (suspended) {
- nativeThread.Resume();
- }
- }
- stacks[i] = getStackTrace(stack);
- }
- catch (cli.System.Threading.ThreadStateException _) {
- stacks[i] = new StackTraceElement[0];
- }
- }
- }
- return stacks;
- }
-
- private static native StackTraceElement[] getStackTrace(cli.System.Diagnostics.StackTrace stack);
-
- private static native Thread[] getThreads();
-
- /**
- * Returns the identifier of this Thread. The thread ID is a positive
- * <tt>long</tt> number generated when this thread was created.
- * The thread ID is unique and remains unchanged during its lifetime.
- * When a thread is terminated, this thread ID may be reused.
- *
- * @return this thread's ID.
- * @since 1.5
- */
- public long getId() {
- return tid;
- }
-
- /**
- * A thread state. A thread can be in one of the following states:
- * <ul>
- * <li>{@link #NEW}<br>
- * A thread that has not yet started is in this state.
- * </li>
- * <li>{@link #RUNNABLE}<br>
- * A thread executing in the Java virtual machine is in this state.
- * </li>
- * <li>{@link #BLOCKED}<br>
- * A thread that is blocked waiting for a monitor lock
- * is in this state.
- * </li>
- * <li>{@link #WAITING}<br>
- * A thread that is waiting indefinitely for another thread to
- * perform a particular action is in this state.
- * </li>
- * <li>{@link #TIMED_WAITING}<br>
- * A thread that is waiting for another thread to perform an action
- * for up to a specified waiting time is in this state.
- * </li>
- * <li>{@link #TERMINATED}<br>
- * A thread that has exited is in this state.
- * </li>
- * </ul>
- *
- * <p>
- * A thread can be in only one state at a given point in time.
- * These states are virtual machine states which do not reflect
- * any operating system thread states.
- *
- * @since 1.5
- * @see #getState
- */
- public enum State {
- /**
- * Thread state for a thread which has not yet started.
- */
- NEW,
-
- /**
- * Thread state for a runnable thread. A thread in the runnable
- * state is executing in the Java virtual machine but it may
- * be waiting for other resources from the operating system
- * such as processor.
- */
- RUNNABLE,
-
- /**
- * Thread state for a thread blocked waiting for a monitor lock.
- * A thread in the blocked state is waiting for a monitor lock
- * to enter a synchronized block/method or
- * reenter a synchronized block/method after calling
- * {@link Object#wait() Object.wait}.
- */
- BLOCKED,
-
- /**
- * Thread state for a waiting thread.
- * A thread is in the waiting state due to calling one of the
- * following methods:
- * <ul>
- * <li>{@link Object#wait() Object.wait} with no timeout</li>
- * <li>{@link #join() Thread.join} with no timeout</li>
- * <li>{@link LockSupport#park() LockSupport.park}</li>
- * </ul>
- *
- * <p>A thread in the waiting state is waiting for another thread to
- * perform a particular action.
- *
- * For example, a thread that has called <tt>Object.wait()</tt>
- * on an object is waiting for another thread to call
- * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
- * that object. A thread that has called <tt>Thread.join()</tt>
- * is waiting for a specified thread to terminate.
- */
- WAITING,
-
- /**
- * Thread state for a waiting thread with a specified waiting time.
- * A thread is in the timed waiting state due to calling one of
- * the following methods with a specified positive waiting time:
- * <ul>
- * <li>{@link #sleep Thread.sleep}</li>
- * <li>{@link Object#wait(long) Object.wait} with timeout</li>
- * <li>{@link #join(long) Thread.join} with timeout</li>
- * <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
- * <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
- * </ul>
- */
- TIMED_WAITING,
-
- /**
- * Thread state for a terminated thread.
- * The thread has completed execution.
- */
- TERMINATED;
- }
-
- /**
- * Returns the state of this thread.
- * This method is designed for use in monitoring of the system state,
- * not for synchronization control.
- *
- * @return this thread's state.
- * @since 1.5
- */
- public State getState() {
- // get current thread state
- switch (threadStatus) {
- case 0:
- return State.NEW;
- case 0x0002:
- return State.TERMINATED;
- }
- synchronized (lock) {
- if (interruptableWait) {
- // NOTE if objectWait has satisfied the wait condition (or has been interrupted or has timed-out),
- // it can be blocking on the re-acquire of the monitor, but we have no way of detecting that.
- return timedWait ? State.TIMED_WAITING : State.WAITING;
- }
- }
- cli.System.Threading.Thread nativeThread = this.nativeThread;
- if (nativeThread == null) {
- return State.TERMINATED;
- }
- if ((nativeThread.get_ThreadState().Value & cli.System.Threading.ThreadState.WaitSleepJoin) != 0) {
- return State.BLOCKED;
- }
- return State.RUNNABLE;
- }
-
- // Added in JSR-166
-
- /**
- * Interface for handlers invoked when a <tt>Thread</tt> abruptly
- * terminates due to an uncaught exception.
- * <p>When a thread is about to terminate due to an uncaught exception
- * the Java Virtual Machine will query the thread for its
- * <tt>UncaughtExceptionHandler</tt> using
- * {@link #getUncaughtExceptionHandler} and will invoke the handler's
- * <tt>uncaughtException</tt> method, passing the thread and the
- * exception as arguments.
- * If a thread has not had its <tt>UncaughtExceptionHandler</tt>
- * explicitly set, then its <tt>ThreadGroup</tt> object acts as its
- * <tt>UncaughtExceptionHandler</tt>. If the <tt>ThreadGroup</tt> object
- * has no
- * special requirements for dealing with the exception, it can forward
- * the invocation to the {@linkplain #getDefaultUncaughtExceptionHandler
- * default uncaught exception handler}.
- *
- * @see #setDefaultUncaughtExceptionHandler
- * @see #setUncaughtExceptionHandler
- * @see ThreadGroup#uncaughtException
- * @since 1.5
- */
- @FunctionalInterface
- public interface UncaughtExceptionHandler {
- /**
- * Method invoked when the given thread terminates due to the
- * given uncaught exception.
- * <p>Any exception thrown by this method will be ignored by the
- * Java Virtual Machine.
- * @param t the thread
- * @param e the exception
- */
- void uncaughtException(Thread t, Throwable e);
- }
-
- // null unless explicitly set
- private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
-
- // null unless explicitly set
- private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
-
- /**
- * Set the default handler invoked when a thread abruptly terminates
- * due to an uncaught exception, and no other handler has been defined
- * for that thread.
- *
- * <p>Uncaught exception handling is controlled first by the thread, then
- * by the thread's {@link ThreadGroup} object and finally by the default
- * uncaught exception handler. If the thread does not have an explicit
- * uncaught exception handler set, and the thread's thread group
- * (including parent thread groups) does not specialize its
- * <tt>uncaughtException</tt> method, then the default handler's
- * <tt>uncaughtException</tt> method will be invoked.
- * <p>By setting the default uncaught exception handler, an application
- * can change the way in which uncaught exceptions are handled (such as
- * logging to a specific device, or file) for those threads that would
- * already accept whatever &quot;default&quot; behavior the system
- * provided.
- *
- * <p>Note that the default uncaught exception handler should not usually
- * defer to the thread's <tt>ThreadGroup</tt> object, as that could cause
- * infinite recursion.
- *
- * @param eh the object to use as the default uncaught exception handler.
- * If <tt>null</tt> then there is no default handler.
- *
- * @throws SecurityException if a security manager is present and it
- * denies <tt>{@link RuntimePermission}
- * (&quot;setDefaultUncaughtExceptionHandler&quot;)</tt>
- *
- * @see #setUncaughtExceptionHandler
- * @see #getUncaughtExceptionHandler
- * @see ThreadGroup#uncaughtException
- * @since 1.5
- */
- public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(
- new RuntimePermission("setDefaultUncaughtExceptionHandler")
- );
- }
-
- defaultUncaughtExceptionHandler = eh;
- }
-
- /**
- * Returns the default handler invoked when a thread abruptly terminates
- * due to an uncaught exception. If the returned value is <tt>null</tt>,
- * there is no default.
- * @since 1.5
- * @see #setDefaultUncaughtExceptionHandler
- * @return the default uncaught exception handler for all threads
- */
- public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){
- return defaultUncaughtExceptionHandler;
- }
-
- /**
- * Returns the handler invoked when this thread abruptly terminates
- * due to an uncaught exception. If this thread has not had an
- * uncaught exception handler explicitly set then this thread's
- * <tt>ThreadGroup</tt> object is returned, unless this thread
- * has terminated, in which case <tt>null</tt> is returned.
- * @since 1.5
- * @return the uncaught exception handler for this thread
- */
- public UncaughtExceptionHandler getUncaughtExceptionHandler() {
- return uncaughtExceptionHandler != null ?
- uncaughtExceptionHandler : group;
- }
-
- /**
- * Set the handler invoked when this thread abruptly terminates
- * due to an uncaught exception.
- * <p>A thread can take full control of how it responds to uncaught
- * exceptions by having its uncaught exception handler explicitly set.
- * If no such handler is set then the thread's <tt>ThreadGroup</tt>
- * object acts as its handler.
- * @param eh the object to use as this thread's uncaught exception
- * handler. If <tt>null</tt> then this thread has no explicit handler.
- * @throws SecurityException if the current thread is not allowed to
- * modify this thread.
- * @see #setDefaultUncaughtExceptionHandler
- * @see ThreadGroup#uncaughtException
- * @since 1.5
- */
- public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
- checkAccess();
- uncaughtExceptionHandler = eh;
- }
-
- /**
- * Dispatch an uncaught exception to the handler. This method is
- * intended to be called only by the JVM.
- */
- private void dispatchUncaughtException(Throwable e) {
- getUncaughtExceptionHandler().uncaughtException(this, e);
- }
-
- /**
- * Removes from the specified map any keys that have been enqueued
- * on the specified reference queue.
- */
- static void processQueue(ReferenceQueue<Class<?>> queue,
- ConcurrentMap<? extends
- WeakReference<Class<?>>, ?> map)
- {
- Reference<? extends Class<?>> ref;
- while((ref = queue.poll()) != null) {
- map.remove(ref);
- }
- }
-
- /**
- * Weak key for Class objects.
- **/
- static class WeakClassKey extends WeakReference<Class<?>> {
- /**
- * saved value of the referent's identity hash code, to maintain
- * a consistent hash code after the referent has been cleared
- */
- private final int hash;
-
- /**
- * Create a new WeakClassKey to the given object, registered
- * with a queue.
- */
- WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
- super(cl, refQueue);
- hash = System.identityHashCode(cl);
- }
-
- /**
- * Returns the identity hash code of the original referent.
- */
- @Override
- public int hashCode() {
- return hash;
- }
-
- /**
- * Returns true if the given object is this identical
- * WeakClassKey instance, or, if this object's referent has not
- * been cleared, if the given object is another WeakClassKey
- * instance with the identical non-null referent as this one.
- */
- @Override
- public boolean equals(Object obj) {
- if (obj == this)
- return true;
-
- if (obj instanceof WeakClassKey) {
- Object referent = get();
- return (referent != null) &&
- (referent == ((WeakClassKey) obj).get());
- } else {
- return false;
- }
- }
- }
-
-
- // The following three initially uninitialized fields are exclusively
- // managed by class java.util.concurrent.ThreadLocalRandom. These
- // fields are used to build the high-performance PRNGs in the
- // concurrent code, and we can not risk accidental false sharing.
- // Hence, the fields are isolated with @Contended.
-
- /** The current seed for a ThreadLocalRandom */
- @sun.misc.Contended("tlr")
- long threadLocalRandomSeed;
-
- /** Probe hash value; nonzero if threadLocalRandomSeed initialized */
- @sun.misc.Contended("tlr")
- @ikvm.lang.Internal // [IKVM] accessed from java.util.concurrent.atomic.Striped64
- public int threadLocalRandomProbe;
-
- /** Secondary seed isolated from public ThreadLocalRandom sequence */
- @sun.misc.Contended("tlr")
- @ikvm.lang.Internal // [IKVM] accessed from java.util.concurrent.locks.LockSupport
- public int threadLocalRandomSecondarySeed;
-
- /* Some private helper methods */
- private synchronized void setPriority0(int newPriority) {
- cli.System.Threading.Thread nativeThread = this.nativeThread;
- if (nativeThread != null) {
- try {
- if (false) throw new cli.System.Threading.ThreadStateException();
- nativeThread.set_Priority(cli.System.Threading.ThreadPriority.wrap(mapJavaPriorityToClr(newPriority)));
- }
- catch (cli.System.Threading.ThreadStateException _) {
- }
- }
- }
-
- private void stop0(Throwable x) {
- synchronized (lock) {
- if (!running) {
- stillborn = x;
- x = null;
- }
- }
- if (x != null) {
- // NOTE we allow ThreadDeath (and its subclasses) to be thrown on every thread, but any
- // other exception is ignored, except if we're throwing it on the current Thread. This
- // is done to allow exception handlers to be type specific, otherwise every exception
- // handler would have to catch ThreadAbortException and look inside it to see if it
- // contains the real exception that we wish to handle.
- // I hope we can get away with this behavior, because Thread.stop() is deprecated
- // anyway. Note that we do allow arbitrary exceptions to be thrown on the current
- // thread, since this is harmless (because they aren't wrapped) and also because it
- // provides some real value, because it is one of the ways you can throw arbitrary checked
- // exceptions from Java.
- if (this == current) {
- sun.misc.Unsafe.getUnsafe().throwException(x);
- }
- else if (x instanceof ThreadDeath) {
- cli.System.Threading.Thread nativeThread = this.nativeThread;
- if (nativeThread == null) {
- return;
- }
- try {
- if (false) throw new cli.System.Threading.ThreadStateException();
- nativeThread.Abort(x);
- }
- catch (cli.System.Threading.ThreadStateException _) {
- // .NET 2.0 throws a ThreadStateException if the target thread is currently suspended
- // (but it does record the Abort request)
- }
- try {
- if (false) throw new cli.System.Threading.ThreadStateException();
- int suspend = cli.System.Threading.ThreadState.Suspended | cli.System.Threading.ThreadState.SuspendRequested;
- while ((nativeThread.get_ThreadState().Value & suspend) != 0) {
- nativeThread.Resume();
- }
- }
- catch (cli.System.Threading.ThreadStateException _) {
- }
- }
- }
- }
-
- private void suspend0() {
- try {
- if (false) throw new cli.System.Threading.ThreadStateException();
- cli.System.Threading.Thread nativeThread = this.nativeThread;
- if (nativeThread != null) {
- nativeThread.Suspend();
- }
- }
- catch (cli.System.Threading.ThreadStateException _) {
- }
- }
-
- private void resume0() {
- try {
- if (false) throw new cli.System.Threading.ThreadStateException();
- cli.System.Threading.Thread nativeThread = this.nativeThread;
- if (nativeThread != null) {
- nativeThread.Resume();
- }
- }
- catch (cli.System.Threading.ThreadStateException _) {
- }
- }
-
- private void interrupt0() {
- synchronized (lock) {
- // if the thread hasn't been started yet or has been terminated, the interrupt is ignored
- // (like on the reference implementation)
- if (nativeThread == null) {
- return;
- }
- if (!interruptPending) {
- interruptPending = true;
- if (interruptableWait) {
- nativeInterruptPending = true;
- nativeThread.Interrupt();
- }
- }
- }
- }
-
- private void setRunningAndCheckStillborn() throws Throwable {
- Throwable x;
- synchronized (lock) {
- running = true;
- x = stillborn;
- stillborn = null;
- }
- if (x != null) {
- throw x;
- }
- }
-
- // [IKVM] this the entry point of thread started from Java
- @cli.IKVM.Attributes.HideFromJavaAttribute.Annotation
- void threadProc() {
- current = this;
- try {
- // the body of the try block is in another method to allow the (limited) try/finally optimizer
- // to properly recognize the try/finally block, because we want to make sure that die()
- // runs in a finally block to prevent it from being asynchronously aborted.
- threadProc2();
- }
- finally {
- die();
- }
- }
-
- @cli.IKVM.Attributes.HideFromJavaAttribute.Annotation
- private void threadProc2() {
- try {
- setRunningAndCheckStillborn();
- run();
- }
- catch (Throwable x) {
- try {
- getUncaughtExceptionHandler().uncaughtException(this, x);
- }
- catch (Throwable _) {
- }
- }
- }
-
- // [IKVM] this the implementation of Object.wait(long timeout, int nanos). It is hooked up in map.xml.
- static void objectWait(Object o, long timeout, int nanos) throws InterruptedException {
- if (o == null) {
- throw new NullPointerException();
- }
- if (timeout < 0) {
- throw new IllegalArgumentException("timeout value is negative");
- }
- if (nanos < 0 || nanos > 999999) {
- throw new IllegalArgumentException("nanosecond timeout value out of range");
- }
- if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
- timeout++;
- }
- objectWait(o, timeout);
- }
-
- // [IKVM] this the implementation of Object.wait(long timeout). It is hooked up in map.xml.
- static void objectWait(Object o, long timeout) throws InterruptedException {
- if (o == null) {
- throw new NullPointerException();
- }
- if (timeout < 0) {
- throw new IllegalArgumentException("timeout value is negative");
- }
- Thread t = currentThread();
- t.enterInterruptableWait(timeout != 0);
- try {
- if (false) throw new cli.System.Threading.ThreadInterruptedException();
- if (timeout == 0 || timeout > 922337203685476L) {
- cli.System.Threading.Monitor.Wait(o);
- }
- else {
- // We wait a maximum of Integer.MAX_VALUE milliseconds, because that is the maximum that Monitor.Wait will wait.
- // Note that the Object.wait() specification allows for spurious wakeups, so this isn't a problem. Trying to
- // emulate a longer wait with multiple Monitor.Wait() calls is not allowed, because that would mean that
- // we acquire and release the synchronization lock multiple times during the wait.
- cli.System.Threading.Monitor.Wait(o, (int)Math.min(timeout, Integer.MAX_VALUE));
- }
- }
- catch (cli.System.Threading.ThreadInterruptedException _) {
- }
- finally {
- t.leaveInterruptableWait();
- }
- }
-
- private void setNativeName(String name) {
- cli.System.Threading.Thread thread = nativeThread;
- if (thread != null) {
- try {
- if (false) throw new cli.System.InvalidOperationException();
- thread.set_Name(name);
- } catch (cli.System.InvalidOperationException _) {
- }
- }
- }
-}
diff --git a/openjdk/java/lang/ThrowableHelper.java b/openjdk/java/lang/ThrowableHelper.java
deleted file mode 100644
index 8a08a8fe..00000000
--- a/openjdk/java/lang/ThrowableHelper.java
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang;
-import java.io.*;
-import java.util.*;
-
-final class ThrowableHelper {
- /**
- * Holder class to defer initializing sentinel objects only used
- * for serialization.
- */
- private static class SentinelHolder {
- /**
- * {@linkplain #setStackTrace(StackTraceElement[]) Setting the
- * stack trace} to a one-element array containing this sentinel
- * value indicates future attempts to set the stack trace will be
- * ignored. The sentinal is equal to the result of calling:<br>
- * {@code new StackTraceElement("", "", null, Integer.MIN_VALUE)}
- */
- public static final StackTraceElement STACK_TRACE_ELEMENT_SENTINEL =
- new StackTraceElement("", "", null, Integer.MIN_VALUE);
-
- /**
- * Sentinel value used in the serial form to indicate an immutable
- * stack trace.
- */
- public static final StackTraceElement[] STACK_TRACE_SENTINEL =
- new StackTraceElement[] {STACK_TRACE_ELEMENT_SENTINEL};
- }
-
- /** Caption for labeling causative exception stack traces */
- private static final String CAUSE_CAPTION = "Caused by: ";
-
- /** Caption for labeling suppressed exception stack traces */
- private static final String SUPPRESSED_CAPTION = "Suppressed: ";
-
- /**
- * Prints this throwable and its backtrace to the
- * standard error stream. This method prints a stack trace for this
- * {@code Throwable} object on the error output stream that is
- * the value of the field {@code System.err}. The first line of
- * output contains the result of the {@link #toString()} method for
- * this object. Remaining lines represent data previously recorded by
- * the method {@link #fillInStackTrace()}. The format of this
- * information depends on the implementation, but the following
- * example may be regarded as typical:
- * <blockquote><pre>
- * java.lang.NullPointerException
- * at MyClass.mash(MyClass.java:9)
- * at MyClass.crunch(MyClass.java:6)
- * at MyClass.main(MyClass.java:3)
- * </pre></blockquote>
- * This example was produced by running the program:
- * <pre>
- * class MyClass {
- * public static void main(String[] args) {
- * crunch(null);
- * }
- * static void crunch(int[] a) {
- * mash(a);
- * }
- * static void mash(int[] b) {
- * System.out.println(b[0]);
- * }
- * }
- * </pre>
- * The backtrace for a throwable with an initialized, non-null cause
- * should generally include the backtrace for the cause. The format
- * of this information depends on the implementation, but the following
- * example may be regarded as typical:
- * <pre>
- * HighLevelException: MidLevelException: LowLevelException
- * at Junk.a(Junk.java:13)
- * at Junk.main(Junk.java:4)
- * Caused by: MidLevelException: LowLevelException
- * at Junk.c(Junk.java:23)
- * at Junk.b(Junk.java:17)
- * at Junk.a(Junk.java:11)
- * ... 1 more
- * Caused by: LowLevelException
- * at Junk.e(Junk.java:30)
- * at Junk.d(Junk.java:27)
- * at Junk.c(Junk.java:21)
- * ... 3 more
- * </pre>
- * Note the presence of lines containing the characters {@code "..."}.
- * These lines indicate that the remainder of the stack trace for this
- * exception matches the indicated number of frames from the bottom of the
- * stack trace of the exception that was caused by this exception (the
- * "enclosing" exception). This shorthand can greatly reduce the length
- * of the output in the common case where a wrapped exception is thrown
- * from same method as the "causative exception" is caught. The above
- * example was produced by running the program:
- * <pre>
- * public class Junk {
- * public static void main(String args[]) {
- * try {
- * a();
- * } catch(HighLevelException e) {
- * e.printStackTrace();
- * }
- * }
- * static void a() throws HighLevelException {
- * try {
- * b();
- * } catch(MidLevelException e) {
- * throw new HighLevelException(e);
- * }
- * }
- * static void b() throws MidLevelException {
- * c();
- * }
- * static void c() throws MidLevelException {
- * try {
- * d();
- * } catch(LowLevelException e) {
- * throw new MidLevelException(e);
- * }
- * }
- * static void d() throws LowLevelException {
- * e();
- * }
- * static void e() throws LowLevelException {
- * throw new LowLevelException();
- * }
- * }
- *
- * class HighLevelException extends Exception {
- * HighLevelException(Throwable cause) { super(cause); }
- * }
- *
- * class MidLevelException extends Exception {
- * MidLevelException(Throwable cause) { super(cause); }
- * }
- *
- * class LowLevelException extends Exception {
- * }
- * </pre>
- * As of release 7, the platform supports the notion of
- * <i>suppressed exceptions</i> (in conjunction with the {@code
- * try}-with-resources statement). Any exceptions that were
- * suppressed in order to deliver an exception are printed out
- * beneath the stack trace. The format of this information
- * depends on the implementation, but the following example may be
- * regarded as typical:
- *
- * <pre>
- * Exception in thread "main" java.lang.Exception: Something happened
- * at Foo.bar(Foo.java:10)
- * at Foo.main(Foo.java:5)
- * Suppressed: Resource$CloseFailException: Resource ID = 0
- * at Resource.close(Resource.java:26)
- * at Foo.bar(Foo.java:9)
- * ... 1 more
- * </pre>
- * Note that the "... n more" notation is used on suppressed exceptions
- * just at it is used on causes. Unlike causes, suppressed exceptions are
- * indented beyond their "containing exceptions."
- *
- * <p>An exception can have both a cause and one or more suppressed
- * exceptions:
- * <pre>
- * Exception in thread "main" java.lang.Exception: Main block
- * at Foo3.main(Foo3.java:7)
- * Suppressed: Resource$CloseFailException: Resource ID = 2
- * at Resource.close(Resource.java:26)
- * at Foo3.main(Foo3.java:5)
- * Suppressed: Resource$CloseFailException: Resource ID = 1
- * at Resource.close(Resource.java:26)
- * at Foo3.main(Foo3.java:5)
- * Caused by: java.lang.Exception: I did it
- * at Foo3.main(Foo3.java:8)
- * </pre>
- * Likewise, a suppressed exception can have a cause:
- * <pre>
- * Exception in thread "main" java.lang.Exception: Main block
- * at Foo4.main(Foo4.java:6)
- * Suppressed: Resource2$CloseFailException: Resource ID = 1
- * at Resource2.close(Resource2.java:20)
- * at Foo4.main(Foo4.java:5)
- * Caused by: java.lang.Exception: Rats, you caught me
- * at Resource2$CloseFailException.<init>(Resource2.java:45)
- * ... 2 more
- * </pre>
- */
- public static void printStackTrace(Throwable _this) {
- _this.printStackTrace(System.err);
- }
-
- /**
- * Prints this throwable and its backtrace to the specified print stream.
- *
- * @param s {@code PrintStream} to use for output
- */
- public static void printStackTrace(Throwable _this, PrintStream s) {
- printStackTrace(_this, new WrappedPrintStream(s));
- }
-
- private static void printStackTrace(Throwable _this, PrintStreamOrWriter s) {
- // Guard against malicious overrides of Throwable.equals by
- // using a Set with identity equality semantics.
- Set<Throwable> dejaVu =
- Collections.newSetFromMap(new IdentityHashMap<Throwable, Boolean>());
- dejaVu.add(_this);
-
- synchronized (s.lock()) {
- // Print our stack trace
- s.println(_this);
- StackTraceElement[] trace = getOurStackTrace(_this);
- for (StackTraceElement traceElement : trace)
- s.println("\tat " + traceElement);
-
- // Print suppressed exceptions, if any
- for (Throwable se : _this.getSuppressed())
- printEnclosedStackTrace(se, s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
-
- // Print cause, if any
- Throwable ourCause = _this.getCause();
- if (ourCause != null)
- printEnclosedStackTrace(ourCause, s, trace, CAUSE_CAPTION, "", dejaVu);
- }
- }
-
- /**
- * Print our stack trace as an enclosed exception for the specified
- * stack trace.
- */
- private static void printEnclosedStackTrace(Throwable _this, PrintStreamOrWriter s,
- StackTraceElement[] enclosingTrace,
- String caption,
- String prefix,
- Set<Throwable> dejaVu) {
- assert Thread.holdsLock(s.lock());
- if (dejaVu.contains(_this)) {
- s.println("\t[CIRCULAR REFERENCE:" + _this + "]");
- } else {
- dejaVu.add(_this);
- // Compute number of frames in common between this and enclosing trace
- StackTraceElement[] trace = getOurStackTrace(_this);
- int m = trace.length - 1;
- int n = enclosingTrace.length - 1;
- while (m >= 0 && n >=0 && trace[m].equals(enclosingTrace[n])) {
- m--; n--;
- }
- int framesInCommon = trace.length - 1 - m;
-
- // Print our stack trace
- s.println(prefix + caption + _this);
- for (int i = 0; i <= m; i++)
- s.println(prefix + "\tat " + trace[i]);
- if (framesInCommon != 0)
- s.println(prefix + "\t... " + framesInCommon + " more");
-
- // Print suppressed exceptions, if any
- for (Throwable se : _this.getSuppressed())
- printEnclosedStackTrace(se, s, trace, SUPPRESSED_CAPTION,
- prefix +"\t", dejaVu);
-
- // Print cause, if any
- Throwable ourCause = _this.getCause();
- if (ourCause != null)
- printEnclosedStackTrace(ourCause, s, trace, CAUSE_CAPTION, prefix, dejaVu);
- }
- }
-
- private static native StackTraceElement[] getOurStackTrace(Throwable _this);
-
- /**
- * Prints this throwable and its backtrace to the specified
- * print writer.
- *
- * @param s {@code PrintWriter} to use for output
- * @since JDK1.1
- */
- public static void printStackTrace(Throwable _this, PrintWriter s) {
- printStackTrace(_this, new WrappedPrintWriter(s));
- }
-
- /**
- * Wrapper class for PrintStream and PrintWriter to enable a single
- * implementation of printStackTrace.
- */
- private abstract static class PrintStreamOrWriter {
- /** Returns the object to be locked when using this StreamOrWriter */
- abstract Object lock();
-
- /** Prints the specified string as a line on this StreamOrWriter */
- abstract void println(Object o);
- }
-
- private static class WrappedPrintStream extends PrintStreamOrWriter {
- private final PrintStream printStream;
-
- WrappedPrintStream(PrintStream printStream) {
- this.printStream = printStream;
- }
-
- Object lock() {
- return printStream;
- }
-
- void println(Object o) {
- printStream.println(o);
- }
- }
-
- private static class WrappedPrintWriter extends PrintStreamOrWriter {
- private final PrintWriter printWriter;
-
- WrappedPrintWriter(PrintWriter printWriter) {
- this.printWriter = printWriter;
- }
-
- Object lock() {
- return printWriter;
- }
-
- void println(Object o) {
- printWriter.println(o);
- }
- }
-}
diff --git a/openjdk/java/lang/VMSystemProperties.java b/openjdk/java/lang/VMSystemProperties.java
deleted file mode 100644
index c982e2dd..00000000
--- a/openjdk/java/lang/VMSystemProperties.java
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- Copyright (C) 2004-2011 Jeroen Frijters
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jeroen Frijters
- jeroen@frijters.net
-
-*/
-package java.lang;
-
-import java.util.Properties;
-import static ikvm.internal.Util.SafeGetEnvironmentVariable;
-
-final class VMSystemProperties
-{
- private VMSystemProperties() { }
-
- public static final String SPEC_TITLE = "Java Platform API Specification";
- public static final String SPEC_VERSION = "1.7";
- public static final String SPEC_VENDOR = "Oracle Corporation";
-
- private static String getLibraryPath()
- {
- String libraryPath;
- if(ikvm.internal.Util.WINDOWS)
- {
- // see /hotspot/src/os/windows/vm/os_windows.cpp for the comment that describes how we build the path
- String windir = SafeGetEnvironmentVariable("SystemRoot");
- if(windir != null)
- {
- libraryPath = cli.System.IO.Path.PathSeparator + windir + "\\Sun\\Java\\bin";
- }
- else
- {
- libraryPath = null;
- }
- try
- {
- if(false) throw new cli.System.Security.SecurityException();
- if (libraryPath == null)
- {
- libraryPath = cli.System.Environment.get_SystemDirectory();
- }
- else
- {
- libraryPath += cli.System.IO.Path.PathSeparator + cli.System.Environment.get_SystemDirectory();
- }
- }
- catch(cli.System.Security.SecurityException _)
- {
- }
- if(windir != null)
- {
- libraryPath += cli.System.IO.Path.PathSeparator + windir;
- }
- String path = SafeGetEnvironmentVariable("PATH");
- if(path != null)
- {
- libraryPath += cli.System.IO.Path.PathSeparator + path;
- }
- }
- else if(ikvm.internal.Util.MACOSX)
- {
- libraryPath = ".";
- }
- else /* assume Linux, since that's the only other platform we support */
- {
- // on Linux we have some hardcoded paths (from /hotspot/src/os/linux/vm/os_linux.cpp)
- // and we can only guess the cpu arch based on bitness (that means only x86 and x64)
- String cpu_arch = cli.System.IntPtr.get_Size() == 4 ? "i386" : "amd64";
- libraryPath = "/usr/java/packages/lib/" + cpu_arch + ":/lib:/usr/lib";
- String ld_library_path = SafeGetEnvironmentVariable("LD_LIBRARY_PATH");
- if(ld_library_path != null)
- {
- libraryPath = ld_library_path + ":" + libraryPath;
- }
- }
- try
- {
- cli.System.Reflection.Assembly entryAsm = cli.System.Reflection.Assembly.GetEntryAssembly();
- // If the CLR was started by a native app (e.g. via COM interop) there is no entry assembly
- if (entryAsm != null)
- {
- // the application (or launcher) directory is prepended to the library path
- // (similar to how the JDK prepends its directory to the path)
- libraryPath = new cli.System.IO.FileInfo(entryAsm.get_Location()).get_DirectoryName() + cli.System.IO.Path.PathSeparator + libraryPath;
- }
- }
- catch(Throwable _)
- {
- // ignore
- }
- if(ikvm.internal.Util.WINDOWS)
- {
- libraryPath += cli.System.IO.Path.PathSeparator + ".";
- }
- return libraryPath;
- }
-
- private static void initCommonProperties(Properties p)
- {
- p.setProperty("java.version", "1.7.0");
- p.setProperty("java.vendor", "Jeroen Frijters");
- p.setProperty("java.vendor.url", "http://ikvm.net/");
- p.setProperty("java.vendor.url.bug", "http://www.ikvm.net/bugs");
- p.setProperty("java.vm.specification.version", "1.7");
- p.setProperty("java.vm.specification.vendor", "Oracle Corporation");
- p.setProperty("java.vm.specification.name", "Java Virtual Machine Specification");
- p.setProperty("java.vm.version", PropertyConstants.java_vm_version);
- p.setProperty("java.vm.vendor", "Jeroen Frijters");
- p.setProperty("java.vm.name", "IKVM.NET");
- p.setProperty("java.runtime.name", "IKVM.NET");
- p.setProperty("java.runtime.version", PropertyConstants.java_runtime_version);
- p.setProperty("java.specification.version", SPEC_VERSION);
- p.setProperty("java.specification.vendor", SPEC_VENDOR);
- p.setProperty("java.specification.name", SPEC_TITLE);
- p.setProperty("java.class.version", "51.0");
- p.setProperty("java.class.path", "");
- p.setProperty("java.library.path", getLibraryPath());
- try
- {
- if(false) throw new cli.System.Security.SecurityException();
- p.setProperty("java.io.tmpdir", cli.System.IO.Path.GetTempPath());
- }
- catch(cli.System.Security.SecurityException _)
- {
- // TODO should we set another value?
- p.setProperty("java.io.tmpdir", ".");
- }
- p.setProperty("java.ext.dirs", "");
- // NOTE os.name *must* contain "Windows" when running on Windows, because Classpath tests on that
- String osname = null;
- String osver = null;
- cli.System.OperatingSystem os = cli.System.Environment.get_OSVersion();
- int major = os.get_Version().get_Major();
- int minor = os.get_Version().get_Minor();
- switch(os.get_Platform().Value)
- {
- case cli.System.PlatformID.Win32NT:
- osname = "Windows NT (unknown)";
- switch(major)
- {
- case 3:
- case 4:
- osver = major + "." + minor;
- osname = "Windows NT";
- break;
- case 5:
- switch(minor)
- {
- case 0:
- osver = "5.0";
- osname = "Windows 2000";
- break;
- case 1:
- osver = "5.1";
- osname = "Windows XP";
- break;
- case 2:
- osver = "5.2";
- osname = "Windows 2003";
- break;
- }
- break;
- case 6:
- // since there appears to be no managed way to differentiate between Client/Server, we report client names
- switch(minor)
- {
- case 0:
- osver = "6.0";
- osname = "Windows Vista";
- break;
- case 1:
- osver = "6.1";
- osname = "Windows 7";
- break;
- }
- break;
- }
- break;
- case cli.System.PlatformID.Win32Windows:
- if(major == 4)
- {
- switch(minor)
- {
- case 0:
- osver = "4.0";
- osname = "Windows 95";
- break;
- case 10:
- osver = "4.10";
- osname = "Windows 98";
- break;
- case 90:
- osver = "4.90";
- osname = "Windows Me";
- break;
- }
- }
- break;
- case cli.System.PlatformID.Unix:
- if(ikvm.internal.Util.MACOSX)
- {
- // for back compat Mono will return PlatformID.Unix when running on the Mac,
- // so we handle that explicitly here
- osname = "Mac OS X";
- // HACK this tries to map the Darwin version to the OS X version
- // (based on http://en.wikipedia.org/wiki/Darwin_(operating_system)#Releases)
- cli.System.Version ver = cli.System.Environment.get_OSVersion().get_Version();
- osver = "10." + (ver.get_Major() - 4) + "." + ver.get_Minor();
- }
- break;
- }
- if(osname == null)
- {
- osname = cli.System.Environment.get_OSVersion().ToString();
- }
- if(osver == null)
- {
- osver = major + "." + minor;
- }
- p.setProperty("os.name", osname);
- p.setProperty("os.version", osver);
- String arch = SafeGetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
- if(arch == null)
- {
- // we don't know, so we make a guess
- if(cli.System.IntPtr.get_Size() == 4)
- {
- arch = ikvm.internal.Util.WINDOWS ? "x86" : "i386";
- }
- else
- {
- arch = "amd64";
- }
- }
- if(arch.equals("AMD64"))
- {
- arch = "amd64";
- }
- p.setProperty("os.arch", arch);
- p.setProperty("sun.arch.data.model", "" + (cli.System.IntPtr.get_Size() * 8));
- p.setProperty("file.separator", "" + cli.System.IO.Path.DirectorySeparatorChar);
- p.setProperty("file.encoding", cli.System.Text.Encoding.get_Default().get_WebName());
- p.setProperty("path.separator", "" + cli.System.IO.Path.PathSeparator);
- p.setProperty("line.separator", cli.System.Environment.get_NewLine());
- try
- {
- if(false) throw new cli.System.Security.SecurityException();
- p.setProperty("user.name", cli.System.Environment.get_UserName());
- }
- catch(cli.System.Security.SecurityException _)
- {
- p.setProperty("user.name", "(unknown)");
- }
- String home = SafeGetEnvironmentVariable("USERPROFILE");
- if(home == null)
- {
- // maybe we're on *nix
- home = SafeGetEnvironmentVariable("HOME");
- if(home == null)
- {
- // TODO maybe there is a better way
- // NOTE on MS .NET this doesn't return the correct path
- // (it returns "C:\\Documents and Settings\\username\\My Documents", but we really need
- // "C:\\Documents and Settings\\username" to be compatible with Sun, that's why we use %USERPROFILE% if it exists)
- try
- {
- if(false) throw new cli.System.Security.SecurityException();
- home = cli.System.Environment.GetFolderPath(cli.System.Environment.SpecialFolder.wrap(cli.System.Environment.SpecialFolder.Personal));
- }
- catch(cli.System.Security.SecurityException _)
- {
- home = ".";
- }
- }
- }
- p.setProperty("user.home", home);
- try
- {
- if(false) throw new cli.System.Security.SecurityException();
- p.setProperty("user.dir", cli.System.Environment.get_CurrentDirectory());
- }
- catch(cli.System.Security.SecurityException _)
- {
- p.setProperty("user.dir", ".");
- }
- p.setProperty("awt.toolkit", PropertyConstants.awt_toolkit);
- }
-
- public static void initProperties(Properties p)
- {
- p.setProperty("openjdk.version", PropertyConstants.openjdk_version);
- String vfsroot = getVirtualFileSystemRoot();
- p.setProperty("java.home", vfsroot.substring(0, vfsroot.length() - 1));
- // the %home%\lib\endorsed directory does not exist, but neither does it on JDK 1.7
- p.setProperty("java.endorsed.dirs", vfsroot + "lib" + cli.System.IO.Path.DirectorySeparatorChar + "endorsed");
- p.setProperty("sun.boot.library.path", vfsroot + "bin");
- p.setProperty("sun.boot.class.path", getBootClassPath());
- initCommonProperties(p);
- setupI18N(p);
- p.setProperty("sun.cpu.endian", cli.System.BitConverter.IsLittleEndian ? "little" : "big");
- p.setProperty("file.encoding.pkg", "sun.io");
- p.setProperty("user.timezone", "");
- p.setProperty("sun.os.patch.level", cli.System.Environment.get_OSVersion().get_ServicePack());
- p.setProperty("java.vm.info", "compiled mode");
- p.setProperty("sun.nio.MaxDirectMemorySize", "-1");
- p.setProperty("java.awt.graphicsenv", PropertyConstants.java_awt_graphicsenv);
- p.setProperty("java.awt.printerjob", "sun.awt.windows.WPrinterJob");
-
- // TODO
- // sun.cpu.isalist:=pentium_pro+mmx pentium_pro pentium+mmx pentium i486 i386 i86
- // sun.desktop:=windows
- // sun.io.unicode.encoding:=UnicodeLittle
- // sun.jnu.encoding:=Cp1252
- // sun.management.compiler:=HotSpot Client Compiler
- try
- {
- // read properties from app.config
- if(false) throw new cli.System.Configuration.ConfigurationException();
- cli.System.Collections.Specialized.NameValueCollection appSettings = cli.System.Configuration.ConfigurationSettings.get_AppSettings();
- cli.System.Collections.IEnumerator keys = appSettings.GetEnumerator();
- while(keys.MoveNext())
- {
- String key = (String)keys.get_Current();
- if(key.startsWith("ikvm:"))
- {
- p.setProperty(key.substring(5), appSettings.get_Item(key));
- }
- }
- }
- catch(cli.System.Configuration.ConfigurationException _)
- {
- // app.config is invalid, ignore
- }
- // set the properties that were specified with ikvm.runtime.Startup.setProperties()
- cli.System.Collections.IDictionary props = ikvm.runtime.Startup.props;
- if(props != null)
- {
- cli.System.Collections.IDictionaryEnumerator entries = props.GetEnumerator();
- while(entries.MoveNext())
- {
- p.setProperty((String)entries.get_Key(), (String)entries.get_Value());
- }
- }
- }
-
- private static void setupI18N(Properties p)
- {
- String[] culture = ((cli.System.String)(Object)cli.System.Globalization.CultureInfo.get_CurrentCulture().get_Name()).Split(new char[] { '-' });
- String language;
- String script;
- String region;
- String variant;
- if (culture.length == 2)
- {
- language = culture[0];
- if (culture[1].length() == 4)
- {
- script = culture[1];
- region = "";
- }
- else
- {
- script = "";
- region = culture[1];
- }
- }
- else if (culture.length == 3)
- {
- language = culture[0];
- script = culture[1];
- region = culture[2];
- }
- else
- {
- language = "en";
- script = "";
- region = "US";
- }
- // Norwegian
- if (language.equals("nb"))
- {
- language = "no";
- region = "NO";
- variant = "";
- }
- else if (language.equals("nn"))
- {
- language = "no";
- region = "NO";
- variant = "NY";
- }
- else
- {
- variant = "";
- }
- p.setProperty("user.language", language);
- p.setProperty("user.country", region);
- p.setProperty("user.variant", variant);
- p.setProperty("user.script", script);
- }
-
- private static native String getVirtualFileSystemRoot();
- private static native String getBootClassPath();
-}
diff --git a/openjdk/java/lang/invoke/AdapterMethodHandle.java b/openjdk/java/lang/invoke/AdapterMethodHandle.java
deleted file mode 100644
index b5686afa..00000000
--- a/openjdk/java/lang/invoke/AdapterMethodHandle.java
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * Extensively modified for IKVM.NET by Jeroen Frijters
- * Copyright (C) 2011 Jeroen Frijters
- */
-
-package java.lang.invoke;
-
-import sun.invoke.util.VerifyType;
-import sun.invoke.util.Wrapper;
-import sun.invoke.util.ValueConversions;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Collections;
-import static java.lang.invoke.MethodHandleStatics.*;
-import ikvm.internal.NotYetImplementedError;
-
-/**
- * This method handle performs simple conversion or checking of a single argument.
- * @author jrose
- */
-class AdapterMethodHandle extends BoundMethodHandle {
-
- AdapterMethodHandle(MethodType type) {
- super(type, null, -1);
- }
- AdapterMethodHandle(MethodType type, Object vmtarget) {
- super(type, null, -1);
- this.vmtarget = vmtarget;
- }
-
- /** Can a JVM-level adapter directly implement the proposed
- * argument conversion, as if by fixed-arity MethodHandle.asType?
- */
- static boolean canConvertArgument(Class<?> src, Class<?> dst, int level) {
- return true;
- }
-
- /**
- * Create a JVM-level adapter method handle to conform the given method
- * handle to the similar newType, using only pairwise argument conversions.
- * For each argument, convert incoming argument to the exact type needed.
- * The argument conversions allowed are casting, boxing and unboxing,
- * integral widening or narrowing, and floating point widening or narrowing.
- * @param newType required call type
- * @param target original method handle
- * @param level which strength of conversion is allowed
- * @return an adapter to the original handle with the desired new type,
- * or the original target if the types are already identical
- * or null if the adaptation cannot be made
- */
- static native MethodHandle makePairwiseConvert(MethodType newType, MethodHandle target, int level);
-
- /* Return one plus the position of the first non-trivial difference
- * between the given types. This is not a symmetric operation;
- * we are considering adapting the targetType to adapterType.
- * Trivial differences are those which could be ignored by the JVM
- * without subverting the verifier. Otherwise, adaptable differences
- * are ones for which we could create an adapter to make the type change.
- * Return zero if there are no differences (other than trivial ones).
- * Return 1+N if N is the only adaptable argument difference.
- * Return the -2-N where N is the first of several adaptable
- * argument differences.
- * Return -1 if there there are differences which are not adaptable.
- */
- private static int diffTypes(MethodType adapterType,
- MethodType targetType,
- boolean raw) {
- int diff;
- diff = diffReturnTypes(adapterType, targetType, raw);
- if (diff != 0) return diff;
- int nargs = adapterType.parameterCount();
- if (nargs != targetType.parameterCount())
- return -1;
- diff = diffParamTypes(adapterType, 0, targetType, 0, nargs, raw);
- //System.out.println("diff "+adapterType);
- //System.out.println(" "+diff+" "+targetType);
- return diff;
- }
- private static int diffReturnTypes(MethodType adapterType,
- MethodType targetType,
- boolean raw) {
- Class<?> src = targetType.returnType();
- Class<?> dst = adapterType.returnType();
- if ((!raw
- ? VerifyType.canPassUnchecked(src, dst)
- : VerifyType.canPassRaw(src, dst)
- ) > 0)
- return 0; // no significant difference
- if (raw && !src.isPrimitive() && !dst.isPrimitive())
- return 0; // can force a reference return (very carefully!)
- //if (false) return 1; // never adaptable!
- return -1; // some significant difference
- }
- private static int diffParamTypes(MethodType adapterType, int astart,
- MethodType targetType, int tstart,
- int nargs, boolean raw) {
- assert(nargs >= 0);
- int res = 0;
- for (int i = 0; i < nargs; i++) {
- Class<?> src = adapterType.parameterType(astart+i);
- Class<?> dest = targetType.parameterType(tstart+i);
- if ((!raw
- ? VerifyType.canPassUnchecked(src, dest)
- : VerifyType.canPassRaw(src, dest)
- ) <= 0) {
- // found a difference; is it the only one so far?
- if (res != 0)
- return -1-res; // return -2-i for prev. i
- res = 1+i;
- }
- }
- return res;
- }
-
- /** Can a retyping adapter (alone) validly convert the target to newType? */
- static boolean canRetypeOnly(MethodType newType, MethodType targetType) {
- return canRetype(newType, targetType, false);
- }
- /** Can a retyping adapter (alone) convert the target to newType?
- * It is allowed to widen subword types and void to int, to make bitwise
- * conversions between float/int and double/long, and to perform unchecked
- * reference conversions on return. This last feature requires that the
- * caller be trusted, and perform explicit cast conversions on return values.
- */
- static boolean canRetypeRaw(MethodType newType, MethodType targetType) {
- return canRetype(newType, targetType, true);
- }
- static boolean canRetype(MethodType newType, MethodType targetType, boolean raw) {
- int diff = diffTypes(newType, targetType, raw);
- // %%% This assert is too strong. Factor diff into VerifyType and reconcile.
- assert(raw || (diff == 0) == VerifyType.isNullConversion(newType, targetType));
- return diff == 0;
- }
-
- /** Factory method: Performs no conversions; simply retypes the adapter.
- * Allows unchecked argument conversions pairwise, if they are safe.
- * Returns null if not possible.
- */
- static MethodHandle makeRetypeOnly(MethodType newType, MethodHandle target) {
- return makeRetype(newType, target, false);
- }
- static MethodHandle makeRetypeRaw(MethodType newType, MethodHandle target) {
- return makeRetype(newType, target, true);
- }
- static native MethodHandle makeRetype(MethodType newType, MethodHandle target, boolean raw);
-
- static MethodHandle makeVarargsCollector(MethodHandle target, Class<?> arrayType) {
- MethodType type = target.type();
- int last = type.parameterCount() - 1;
- if (type.parameterType(last) != arrayType)
- target = target.asType(type.changeParameterType(last, arrayType));
- target = target.asFixedArity(); // make sure this attribute is turned off
- return new AsVarargsCollector(target, arrayType);
- }
-
- static class AsVarargsCollector extends AdapterMethodHandle {
- final MethodHandle target;
- final Class<?> arrayType;
- MethodHandle cache;
-
- AsVarargsCollector(MethodHandle target, Class<?> arrayType) {
- super(target.type());
- this.vmtarget = target.vmtarget;
- this.target = target;
- this.arrayType = arrayType;
- this.cache = target.asCollector(arrayType, 0);
- }
-
- @Override
- public boolean isVarargsCollector() {
- return true;
- }
-
- @Override
- public MethodHandle asFixedArity() {
- return target;
- }
-
- @Override
- public MethodHandle asType(MethodType newType) {
- MethodType type = this.type();
- int collectArg = type.parameterCount() - 1;
- int newArity = newType.parameterCount();
- if (newArity == collectArg+1 &&
- type.parameterType(collectArg).isAssignableFrom(newType.parameterType(collectArg))) {
- // if arity and trailing parameter are compatible, do normal thing
- return super.asType(newType);
- }
- // check cache
- if (cache.type().parameterCount() == newArity)
- return cache.asType(newType);
- // build and cache a collector
- int arrayLength = newArity - collectArg;
- MethodHandle collector;
- try {
- collector = target.asCollector(arrayType, arrayLength);
- } catch (IllegalArgumentException ex) {
- throw new WrongMethodTypeException("cannot build collector");
- }
- cache = collector;
- return collector.asType(newType);
- }
- }
-
- /** Can a checkcast adapter validly convert the target to newType?
- * The JVM supports all kind of reference casts, even silly ones.
- */
- static boolean canCheckCast(MethodType newType, MethodType targetType,
- int arg, Class<?> castType) {
- Class<?> src = newType.parameterType(arg);
- Class<?> dst = targetType.parameterType(arg);
- if (!canCheckCast(src, castType)
- || !VerifyType.isNullConversion(castType, dst))
- return false;
- int diff = diffTypes(newType, targetType, false);
- return (diff == arg+1) || (diff == 0); // arg is sole non-trivial diff
- }
- /** Can an primitive conversion adapter validly convert src to dst? */
- static boolean canCheckCast(Class<?> src, Class<?> dst) {
- return (!src.isPrimitive() && !dst.isPrimitive());
- }
-
- /** Factory method: Forces a cast at the given argument.
- * The castType is the target of the cast, and can be any type
- * with a null conversion to the corresponding target parameter.
- * Return null if this cannot be done.
- */
- static MethodHandle makeCheckCast(MethodType newType, MethodHandle target,
- int arg, Class<?> castType) {
- if (!canCheckCast(newType, target.type(), arg, castType))
- return null;
- throw new NotYetImplementedError();
- }
-
- /** Can an adapter simply drop arguments to convert the target to newType? */
- static boolean canDropArguments(MethodType newType, MethodType targetType,
- int dropArgPos, int dropArgCount) {
- if (dropArgCount == 0)
- return canRetypeOnly(newType, targetType);
- if (diffReturnTypes(newType, targetType, false) != 0)
- return false;
- int nptypes = newType.parameterCount();
- // parameter types must be the same up to the drop point
- if (dropArgPos != 0 && diffParamTypes(newType, 0, targetType, 0, dropArgPos, false) != 0)
- return false;
- int afterPos = dropArgPos + dropArgCount;
- int afterCount = nptypes - afterPos;
- if (dropArgPos < 0 || dropArgPos >= nptypes ||
- dropArgCount < 1 || afterPos > nptypes ||
- targetType.parameterCount() != nptypes - dropArgCount)
- return false;
- // parameter types after the drop point must also be the same
- if (afterCount != 0 && diffParamTypes(newType, afterPos, targetType, dropArgPos, afterCount, false) != 0)
- return false;
- return true;
- }
-
- /** Factory method: Drop selected arguments.
- * Allow unchecked retyping of remaining arguments, pairwise.
- * Return null if this is not possible.
- */
- static MethodHandle makeDropArguments(MethodType newType, MethodHandle target,
- int dropArgPos, int dropArgCount) {
- if (dropArgCount == 0)
- return makeRetypeOnly(newType, target);
- if (!canDropArguments(newType, target.type(), dropArgPos, dropArgCount))
- return null;
- int[] permute = new int[target.type().parameterCount()];
- for (int i = 0, arg = 0; i < permute.length; i++) {
- if (arg == dropArgPos)
- arg += dropArgCount;
- permute[i] = arg++;
- }
- return MethodHandleImpl.permuteArguments(target, newType, target.type(), permute);
- }
-
- /** Can an adapter duplicate an argument to convert the target to newType? */
- static boolean canDupArguments(MethodType newType, MethodType targetType,
- int dupArgPos, int dupArgCount) {
- if (diffReturnTypes(newType, targetType, false) != 0)
- return false;
- int nptypes = newType.parameterCount();
- if (dupArgCount < 0 || dupArgPos + dupArgCount > nptypes)
- return false;
- if (targetType.parameterCount() != nptypes + dupArgCount)
- return false;
- // parameter types must be the same up to the duplicated arguments
- if (diffParamTypes(newType, 0, targetType, 0, nptypes, false) != 0)
- return false;
- // duplicated types must be, well, duplicates
- if (diffParamTypes(newType, dupArgPos, targetType, nptypes, dupArgCount, false) != 0)
- return false;
- return true;
- }
-
- /** Factory method: Duplicate the selected argument.
- * Return null if this is not possible.
- */
- static MethodHandle makeDupArguments(MethodType newType, MethodHandle target,
- int dupArgPos, int dupArgCount) {
- if (!canDupArguments(newType, target.type(), dupArgPos, dupArgCount))
- return null;
- if (dupArgCount == 0)
- return target;
- // in arglist: [0: ...keep1 | dpos: dup... | dpos+dcount: keep2... ]
- // out arglist: [0: ...keep1 | dpos: dup... | dpos+dcount: keep2... | dup... ]
- throw new NotYetImplementedError();
- }
-
- /** Can an adapter swap two arguments to convert the target to newType? */
- static boolean canSwapArguments(MethodType newType, MethodType targetType,
- int swapArg1, int swapArg2) {
- if (diffReturnTypes(newType, targetType, false) != 0)
- return false;
- if (swapArg1 >= swapArg2) return false; // caller resp
- int nptypes = newType.parameterCount();
- if (targetType.parameterCount() != nptypes)
- return false;
- if (swapArg1 < 0 || swapArg2 >= nptypes)
- return false;
- if (diffParamTypes(newType, 0, targetType, 0, swapArg1, false) != 0)
- return false;
- if (diffParamTypes(newType, swapArg1, targetType, swapArg2, 1, false) != 0)
- return false;
- if (diffParamTypes(newType, swapArg1+1, targetType, swapArg1+1, swapArg2-swapArg1-1, false) != 0)
- return false;
- if (diffParamTypes(newType, swapArg2, targetType, swapArg1, 1, false) != 0)
- return false;
- if (diffParamTypes(newType, swapArg2+1, targetType, swapArg2+1, nptypes-swapArg2-1, false) != 0)
- return false;
- return true;
- }
-
- /** Factory method: Swap the selected arguments.
- * Return null if this is not possible.
- */
- static MethodHandle makeSwapArguments(MethodType newType, MethodHandle target,
- int swapArg1, int swapArg2) {
- if (swapArg1 == swapArg2)
- return target;
- if (swapArg1 > swapArg2) { int t = swapArg1; swapArg1 = swapArg2; swapArg2 = t; }
- if (!canSwapArguments(newType, target.type(), swapArg1, swapArg2))
- return null;
- // in arglist: [0: ...keep1 | pos1: a1 | pos1+1: keep2... | pos2: a2 | pos2+1: keep3... ]
- // out arglist: [0: ...keep1 | pos1: a2 | pos1+1: keep2... | pos2: a1 | pos2+1: keep3... ]
- throw new NotYetImplementedError();
- }
-
- static int positiveRotation(int argCount, int rotateBy) {
- assert(argCount > 0);
- if (rotateBy >= 0) {
- if (rotateBy < argCount)
- return rotateBy;
- return rotateBy % argCount;
- } else if (rotateBy >= -argCount) {
- return rotateBy + argCount;
- } else {
- return (-1-((-1-rotateBy) % argCount)) + argCount;
- }
- }
-
- final static int MAX_ARG_ROTATION = 1;
-
- /** Can an adapter rotate arguments to convert the target to newType? */
- static boolean canRotateArguments(MethodType newType, MethodType targetType,
- int firstArg, int argCount, int rotateBy) {
- rotateBy = positiveRotation(argCount, rotateBy);
- if (rotateBy == 0) return false; // no rotation
- if (rotateBy > MAX_ARG_ROTATION && rotateBy < argCount - MAX_ARG_ROTATION)
- return false; // too many argument positions
- // Rotate incoming args right N to the out args, N in 1..(argCouunt-1).
- if (diffReturnTypes(newType, targetType, false) != 0)
- return false;
- int nptypes = newType.parameterCount();
- if (targetType.parameterCount() != nptypes)
- return false;
- if (firstArg < 0 || firstArg >= nptypes) return false;
- int argLimit = firstArg + argCount;
- if (argLimit > nptypes) return false;
- if (diffParamTypes(newType, 0, targetType, 0, firstArg, false) != 0)
- return false;
- int newChunk1 = argCount - rotateBy, newChunk2 = rotateBy;
- // swap new chunk1 with target chunk2
- if (diffParamTypes(newType, firstArg, targetType, argLimit-newChunk1, newChunk1, false) != 0)
- return false;
- // swap new chunk2 with target chunk1
- if (diffParamTypes(newType, firstArg+newChunk1, targetType, firstArg, newChunk2, false) != 0)
- return false;
- return true;
- }
-
- /** Factory method: Rotate the selected argument range.
- * Return null if this is not possible.
- */
- static MethodHandle makeRotateArguments(MethodType newType, MethodHandle target,
- int firstArg, int argCount, int rotateBy) {
- rotateBy = positiveRotation(argCount, rotateBy);
- if (!canRotateArguments(newType, target.type(), firstArg, argCount, rotateBy))
- return null;
- throw new NotYetImplementedError();
- }
-
- /** Can an adapter spread an argument to convert the target to newType? */
- static boolean canSpreadArguments(MethodType newType, MethodType targetType,
- Class<?> spreadArgType, int spreadArgPos, int spreadArgCount) {
- if (diffReturnTypes(newType, targetType, false) != 0)
- return false;
- int nptypes = newType.parameterCount();
- // parameter types must be the same up to the spread point
- if (spreadArgPos != 0 && diffParamTypes(newType, 0, targetType, 0, spreadArgPos, false) != 0)
- return false;
- int afterPos = spreadArgPos + spreadArgCount;
- int afterCount = nptypes - (spreadArgPos + 1);
- if (spreadArgPos < 0 || spreadArgPos >= nptypes ||
- spreadArgCount < 0 ||
- targetType.parameterCount() != afterPos + afterCount)
- return false;
- // parameter types after the spread point must also be the same
- if (afterCount != 0 && diffParamTypes(newType, spreadArgPos+1, targetType, afterPos, afterCount, false) != 0)
- return false;
- // match the array element type to the spread arg types
- Class<?> rawSpreadArgType = newType.parameterType(spreadArgPos);
- if (rawSpreadArgType != spreadArgType && !canCheckCast(rawSpreadArgType, spreadArgType))
- return false;
- for (int i = 0; i < spreadArgCount; i++) {
- Class<?> src = VerifyType.spreadArgElementType(spreadArgType, i);
- Class<?> dst = targetType.parameterType(spreadArgPos + i);
- if (src == null || !canConvertArgument(src, dst, 1))
- return false;
- }
- return true;
- }
-
-
- /** Factory method: Spread selected argument. */
- static native MethodHandle makeSpreadArguments(MethodType newType, MethodHandle target, Class<?> spreadArgType, int spreadArgPos, int spreadArgCount);
-
- /** Can an adapter collect a series of arguments, replacing them by zero or one results? */
- static boolean canCollectArguments(MethodType targetType,
- MethodType collectorType, int collectArgPos, boolean retainOriginalArgs) {
- int collectArgCount = collectorType.parameterCount();
- Class<?> rtype = collectorType.returnType();
- assert(rtype == void.class || targetType.parameterType(collectArgPos) == rtype)
- // [(Object)Object[], (Object[])Object[], 0, 1]
- : Arrays.asList(targetType, collectorType, collectArgPos, collectArgCount)
- ;
- return true;
- }
-
- /** Factory method: Collect or filter selected argument(s). */
- static native MethodHandle makeCollectArguments(MethodHandle target, MethodHandle collector, int collectArgPos, boolean retainOriginalArgs);
-}
diff --git a/openjdk/java/lang/invoke/BoundMethodHandle.java b/openjdk/java/lang/invoke/BoundMethodHandle.java
deleted file mode 100644
index 6098ca3f..00000000
--- a/openjdk/java/lang/invoke/BoundMethodHandle.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * Extensively modified for IKVM.NET by Jeroen Frijters
- * Copyright (C) 2011 Jeroen Frijters
- */
-
-package java.lang.invoke;
-
-import sun.invoke.util.VerifyType;
-import sun.invoke.util.Wrapper;
-import static java.lang.invoke.MethodHandleStatics.*;
-
-/**
- * The flavor of method handle which emulates an invoke instruction
- * on a predetermined argument. The JVM dispatches to the correct method
- * when the handle is created, not when it is invoked.
- * @author jrose
- */
-class BoundMethodHandle extends MethodHandle {
- //MethodHandle vmtarget; // next BMH or final DMH or methodOop
- private final Object argument; // argument to insert
- private final int vmargslot; // position at which it is inserted
-
- // Constructors in this class *must* be package scoped or private.
-
- /** Bind a direct MH to its receiver (or first ref. argument).
- * The JVM will pre-dispatch the MH if it is not already static.
- */
- /*non-public*/ BoundMethodHandle(DirectMethodHandle mh, Object argument) {
- super(mh.type().dropParameterTypes(0, 1));
- // check the type now, once for all:
- this.argument = checkReferenceArgument(argument, mh, 0);
- this.vmargslot = this.type().parameterSlotCount();
- initTarget(mh, 0);
- }
-
- /** Insert an argument into an arbitrary method handle.
- * If argnum is zero, inserts the first argument, etc.
- * The argument type must be a reference.
- */
- /*non-public*/ BoundMethodHandle(MethodHandle mh, Object argument, int argnum) {
- this(mh.type().dropParameterTypes(argnum, argnum+1),
- mh, argument, argnum);
- }
-
- /** Insert an argument into an arbitrary method handle.
- * If argnum is zero, inserts the first argument, etc.
- */
- /*non-public*/ BoundMethodHandle(MethodType type, MethodHandle mh, Object argument, int argnum) {
- super(type);
- if (mh.type().parameterType(argnum).isPrimitive())
- this.argument = bindPrimitiveArgument(argument, mh, argnum);
- else {
- this.argument = checkReferenceArgument(argument, mh, argnum);
- }
- this.vmargslot = type.parameterSlotDepth(argnum);
- initTarget(mh, argnum);
- }
-
- private void initTarget(MethodHandle mh, int argnum) {
- vmtarget = createDelegate(type(), mh, argnum, argument);
- }
-
- private static native Object createDelegate(MethodType newType, MethodHandle mh, int argnum, Object argument);
-
- /** For the AdapterMethodHandle subclass.
- */
- /*non-public*/ BoundMethodHandle(MethodType type, Object argument, int vmargslot) {
- super(type);
- this.argument = argument;
- this.vmargslot = vmargslot;
- assert(this instanceof AdapterMethodHandle);
- }
-
- /** Initialize the current object as a self-bound method handle, binding it
- * as the first argument of the method handle {@code entryPoint}.
- * The invocation type of the resulting method handle will be the
- * same as {@code entryPoint}, except that the first argument
- * type will be dropped.
- */
- /*non-public*/ BoundMethodHandle(MethodHandle entryPoint) {
- super(entryPoint.type().dropParameterTypes(0, 1));
- this.argument = this; // kludge; get rid of
- this.vmargslot = this.type().parameterSlotDepth(0);
- initTarget(entryPoint, 0);
- }
-
- /** Make sure the given {@code argument} can be used as {@code argnum}-th
- * parameter of the given method handle {@code mh}, which must be a reference.
- * <p>
- * If this fails, throw a suitable {@code WrongMethodTypeException},
- * which will prevent the creation of an illegally typed bound
- * method handle.
- */
- final static Object checkReferenceArgument(Object argument, MethodHandle mh, int argnum) {
- Class<?> ptype = mh.type().parameterType(argnum);
- if (ptype.isPrimitive()) {
- // fail
- } else if (argument == null) {
- return null;
- } else if (VerifyType.isNullReferenceConversion(argument.getClass(), ptype)) {
- return argument;
- }
- throw badBoundArgumentException(argument, mh, argnum);
- }
-
- /** Make sure the given {@code argument} can be used as {@code argnum}-th
- * parameter of the given method handle {@code mh}, which must be a primitive.
- * <p>
- * If this fails, throw a suitable {@code WrongMethodTypeException},
- * which will prevent the creation of an illegally typed bound
- * method handle.
- */
- final static Object bindPrimitiveArgument(Object argument, MethodHandle mh, int argnum) {
- Class<?> ptype = mh.type().parameterType(argnum);
- Wrapper wrap = Wrapper.forPrimitiveType(ptype);
- Object zero = wrap.zero();
- if (zero == null) {
- // fail
- } else if (argument == null) {
- if (ptype != int.class && wrap.isSubwordOrInt())
- return Integer.valueOf(0);
- else
- return zero;
- } else if (VerifyType.isNullReferenceConversion(argument.getClass(), zero.getClass())) {
- if (ptype != int.class && wrap.isSubwordOrInt())
- return Wrapper.INT.wrap(argument);
- else
- return argument;
- }
- throw badBoundArgumentException(argument, mh, argnum);
- }
-
- final static RuntimeException badBoundArgumentException(Object argument, MethodHandle mh, int argnum) {
- String atype = (argument == null) ? "null" : argument.getClass().toString();
- return new ClassCastException("cannot bind "+atype+" argument to parameter #"+argnum+" of "+mh.type());
- }
-}
diff --git a/openjdk/java/lang/invoke/CallSite.java b/openjdk/java/lang/invoke/CallSite.java
deleted file mode 100644
index 9b07446a..00000000
--- a/openjdk/java/lang/invoke/CallSite.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * Extensively modified for IKVM.NET by Jeroen Frijters
- * Copyright (C) 2011 Jeroen Frijters
- */
-
-package java.lang.invoke;
-
-import sun.invoke.empty.Empty;
-import sun.misc.Unsafe;
-import static java.lang.invoke.MethodHandleStatics.*;
-import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
-
-/**
- * A {@code CallSite} is a holder for a variable {@link MethodHandle},
- * which is called its {@code target}.
- * An {@code invokedynamic} instruction linked to a {@code CallSite} delegates
- * all calls to the site's current target.
- * A {@code CallSite} may be associated with several {@code invokedynamic}
- * instructions, or it may be "free floating", associated with none.
- * In any case, it may be invoked through an associated method handle
- * called its {@linkplain #dynamicInvoker dynamic invoker}.
- * <p>
- * {@code CallSite} is an abstract class which does not allow
- * direct subclassing by users. It has three immediate,
- * concrete subclasses that may be either instantiated or subclassed.
- * <ul>
- * <li>If a mutable target is not required, an {@code invokedynamic} instruction
- * may be permanently bound by means of a {@linkplain ConstantCallSite constant call site}.
- * <li>If a mutable target is required which has volatile variable semantics,
- * because updates to the target must be immediately and reliably witnessed by other threads,
- * a {@linkplain VolatileCallSite volatile call site} may be used.
- * <li>Otherwise, if a mutable target is required,
- * a {@linkplain MutableCallSite mutable call site} may be used.
- * </ul>
- * <p>
- * A non-constant call site may be <em>relinked</em> by changing its target.
- * The new target must have the same {@linkplain MethodHandle#type() type}
- * as the previous target.
- * Thus, though a call site can be relinked to a series of
- * successive targets, it cannot change its type.
- * <p>
- * Here is a sample use of call sites and bootstrap methods which links every
- * dynamic call site to print its arguments:
-<blockquote><pre><!-- see indy-demo/src/PrintArgsDemo.java -->
-static void test() throws Throwable {
- // THE FOLLOWING LINE IS PSEUDOCODE FOR A JVM INSTRUCTION
- InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14);
-}
-private static void printArgs(Object... args) {
- System.out.println(java.util.Arrays.deepToString(args));
-}
-private static final MethodHandle printArgs;
-static {
- MethodHandles.Lookup lookup = MethodHandles.lookup();
- Class thisClass = lookup.lookupClass(); // (who am I?)
- printArgs = lookup.findStatic(thisClass,
- "printArgs", MethodType.methodType(void.class, Object[].class));
-}
-private static CallSite bootstrapDynamic(MethodHandles.Lookup caller, String name, MethodType type) {
- // ignore caller and name, but match the type:
- return new ConstantCallSite(printArgs.asType(type));
-}
-</pre></blockquote>
- * @author John Rose, JSR 292 EG
- */
-abstract
-public class CallSite {
-
- interface IndyCallSite {
- void setTarget(Object target);
- }
-
- // The actual payload of this call site:
- /*package-private*/
- volatile MethodHandle target;
- final IndyCallSite ics;
-
- /**
- * Make a blank call site object with the given method type.
- * An initial target method is supplied which will throw
- * an {@link IllegalStateException} if called.
- * <p>
- * Before this {@code CallSite} object is returned from a bootstrap method,
- * it is usually provided with a more useful target method,
- * via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
- * @throws NullPointerException if the proposed type is null
- */
- /*package-private*/
- CallSite(MethodType type) {
- this(type.invokers().uninitializedCallSite());
- }
-
- /**
- * Make a call site object equipped with an initial target method handle.
- * @param target the method handle which will be the initial target of the call site
- * @throws NullPointerException if the proposed target is null
- */
- /*package-private*/
- CallSite(MethodHandle target) {
- target.getClass(); // null check
- ics = createIndyCallSite(target.vmtarget);
- setTargetNormal(target);
- }
-
- private static native IndyCallSite createIndyCallSite(Object target);
-
- final void setTargetNormal(MethodHandle target) {
- this.target = target;
- ics.setTarget(target.vmtarget);
- }
-
- final void setTargetVolatile(MethodHandle target) {
- synchronized(ics) {
- setTargetNormal(target);
- }
- }
-
- final MethodHandle getTargetVolatile() {
- synchronized(ics) {
- return target;
- }
- }
-
- /**
- * Make a call site object equipped with an initial target method handle.
- * @param targetType the desired type of the call site
- * @param createTargetHook a hook which will bind the call site to the target method handle
- * @throws WrongMethodTypeException if the hook cannot be invoked on the required arguments,
- * or if the target returned by the hook is not of the given {@code targetType}
- * @throws NullPointerException if the hook returns a null value
- * @throws ClassCastException if the hook returns something other than a {@code MethodHandle}
- * @throws Throwable anything else thrown by the the hook function
- */
- /*package-private*/
- CallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable {
- this(targetType);
- ConstantCallSite selfCCS = (ConstantCallSite) this;
- MethodHandle boundTarget = (MethodHandle) createTargetHook.invokeWithArguments(selfCCS);
- checkTargetChange(this.target, boundTarget);
- setTargetNormal(boundTarget);
- }
-
- /**
- * Returns the type of this call site's target.
- * Although targets may change, any call site's type is permanent, and can never change to an unequal type.
- * The {@code setTarget} method enforces this invariant by refusing any new target that does
- * not have the previous target's type.
- * @return the type of the current target, which is also the type of any future target
- */
- public MethodType type() {
- // warning: do not call getTarget here, because CCS.getTarget can throw IllegalStateException
- return target.type();
- }
-
- /**
- * Returns the target method of the call site, according to the
- * behavior defined by this call site's specific class.
- * The immediate subclasses of {@code CallSite} document the
- * class-specific behaviors of this method.
- *
- * @return the current linkage state of the call site, its target method handle
- * @see ConstantCallSite
- * @see VolatileCallSite
- * @see #setTarget
- * @see ConstantCallSite#getTarget
- * @see MutableCallSite#getTarget
- * @see VolatileCallSite#getTarget
- */
- public abstract MethodHandle getTarget();
-
- /**
- * Updates the target method of this call site, according to the
- * behavior defined by this call site's specific class.
- * The immediate subclasses of {@code CallSite} document the
- * class-specific behaviors of this method.
- * <p>
- * The type of the new target must be {@linkplain MethodType#equals equal to}
- * the type of the old target.
- *
- * @param newTarget the new target
- * @throws NullPointerException if the proposed new target is null
- * @throws WrongMethodTypeException if the proposed new target
- * has a method type that differs from the previous target
- * @see CallSite#getTarget
- * @see ConstantCallSite#setTarget
- * @see MutableCallSite#setTarget
- * @see VolatileCallSite#setTarget
- */
- public abstract void setTarget(MethodHandle newTarget);
-
- void checkTargetChange(MethodHandle oldTarget, MethodHandle newTarget) {
- MethodType oldType = oldTarget.type();
- MethodType newType = newTarget.type(); // null check!
- if (!newType.equals(oldType))
- throw wrongTargetType(newTarget, oldType);
- }
-
- private static WrongMethodTypeException wrongTargetType(MethodHandle target, MethodType type) {
- return new WrongMethodTypeException(String.valueOf(target)+" should be of type "+type);
- }
-
- /**
- * Produces a method handle equivalent to an invokedynamic instruction
- * which has been linked to this call site.
- * <p>
- * This method is equivalent to the following code:
- * <blockquote><pre>
- * MethodHandle getTarget, invoker, result;
- * getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
- * invoker = MethodHandles.exactInvoker(this.type());
- * result = MethodHandles.foldArguments(invoker, getTarget)
- * </pre></blockquote>
- *
- * @return a method handle which always invokes this call site's current target
- */
- public abstract MethodHandle dynamicInvoker();
-
- /*non-public*/ MethodHandle makeDynamicInvoker() {
- MethodHandle getTarget = MethodHandleImpl.bindReceiver(GET_TARGET, this);
- MethodHandle invoker = MethodHandles.exactInvoker(this.type());
- return MethodHandles.foldArguments(invoker, getTarget);
- }
-
- private static final MethodHandle GET_TARGET;
- static {
- try {
- GET_TARGET = IMPL_LOOKUP.
- findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
- } catch (ReflectiveOperationException ignore) {
- throw new InternalError();
- }
- }
-
- /** This guy is rolled into the default target if a MethodType is supplied to the constructor. */
- /*package-private*/
- static Empty uninitializedCallSite() {
- throw new IllegalStateException("uninitialized call site");
- }
-}
diff --git a/openjdk/java/lang/invoke/ConstantCallSite.java b/openjdk/java/lang/invoke/ConstantCallSite.java
deleted file mode 100644
index 2d9fedec..00000000
--- a/openjdk/java/lang/invoke/ConstantCallSite.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.invoke;
-
-/**
- * A {@code ConstantCallSite} is a {@link CallSite} whose target is permanent, and can never be changed.
- * An {@code invokedynamic} instruction linked to a {@code ConstantCallSite} is permanently
- * bound to the call site's target.
- * @author John Rose, JSR 292 EG
- */
-public class ConstantCallSite extends CallSite {
- private final boolean isFrozen;
-
- /**
- * Creates a call site with a permanent target.
- * @param target the target to be permanently associated with this call site
- * @throws NullPointerException if the proposed target is null
- */
- public ConstantCallSite(MethodHandle target) {
- super(target);
- isFrozen = true;
- }
-
- /**
- * Creates a call site with a permanent target, possibly bound to the call site itself.
- * <p>
- * During construction of the call site, the {@code createTargetHook} is invoked to
- * produce the actual target, as if by a call of the form
- * {@code (MethodHandle) createTargetHook.invoke(this)}.
- * <p>
- * Note that user code cannot perform such an action directly in a subclass constructor,
- * since the target must be fixed before the {@code ConstantCallSite} constructor returns.
- * <p>
- * The hook is said to bind the call site to a target method handle,
- * and a typical action would be {@code someTarget.bindTo(this)}.
- * However, the hook is free to take any action whatever,
- * including ignoring the call site and returning a constant target.
- * <p>
- * The result returned by the hook must be a method handle of exactly
- * the same type as the call site.
- * <p>
- * While the hook is being called, the new {@code ConstantCallSite}
- * object is in a partially constructed state.
- * In this state,
- * a call to {@code getTarget}, or any other attempt to use the target,
- * will result in an {@code IllegalStateException}.
- * It is legal at all times to obtain the call site's type using the {@code type} method.
- *
- * @param targetType the type of the method handle to be permanently associated with this call site
- * @param createTargetHook a method handle to invoke (on the call site) to produce the call site's target
- * @throws WrongMethodTypeException if the hook cannot be invoked on the required arguments,
- * or if the target returned by the hook is not of the given {@code targetType}
- * @throws NullPointerException if the hook returns a null value
- * @throws ClassCastException if the hook returns something other than a {@code MethodHandle}
- * @throws Throwable anything else thrown by the the hook function
- */
- protected ConstantCallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable {
- super(targetType, createTargetHook);
- isFrozen = true;
- }
-
- /**
- * Returns the target method of the call site, which behaves
- * like a {@code final} field of the {@code ConstantCallSite}.
- * That is, the the target is always the original value passed
- * to the constructor call which created this instance.
- *
- * @return the immutable linkage state of this call site, a constant method handle
- * @throws IllegalStateException if the {@code ConstantCallSite} constructor has not completed
- */
- @Override public final MethodHandle getTarget() {
- if (!isFrozen) throw new IllegalStateException();
- return target;
- }
-
- /**
- * Always throws an {@link UnsupportedOperationException}.
- * This kind of call site cannot change its target.
- * @param ignore a new target proposed for the call site, which is ignored
- * @throws UnsupportedOperationException because this kind of call site cannot change its target
- */
- @Override public final void setTarget(MethodHandle ignore) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Returns this call site's permanent target.
- * Since that target will never change, this is a correct implementation
- * of {@link CallSite#dynamicInvoker CallSite.dynamicInvoker}.
- * @return the immutable linkage state of this call site, a constant method handle
- * @throws IllegalStateException if the {@code ConstantCallSite} constructor has not completed
- */
- @Override
- public final MethodHandle dynamicInvoker() {
- return getTarget();
- }
-}
diff --git a/openjdk/java/lang/invoke/DirectMethodHandle.java b/openjdk/java/lang/invoke/DirectMethodHandle.java
deleted file mode 100644
index 23a55dce..00000000
--- a/openjdk/java/lang/invoke/DirectMethodHandle.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.invoke;
-
-/**
- * The flavor of method handle which emulates invokespecial or invokestatic.
- * @author jrose
- */
-class DirectMethodHandle extends MethodHandle {
- //inherited oop vmtarget; // methodOop or virtual class/interface oop
-
- // Constructors in this class *must* be package scoped or private.
- DirectMethodHandle(MethodType mtype, MemberName m, boolean doDispatch, Class<?> lookupClass) {
- super(mtype);
-
- assert(m.isMethod() || !doDispatch && m.isConstructor());
- if (!m.isResolved())
- throw new InternalError();
-
- vmtarget = createDelegate(mtype, m, doDispatch, lookupClass);
- }
-
- private static native Object createDelegate(MethodType type, MemberName m, boolean doDispatch, Class<?> lookupClass);
-
- boolean isValid() {
- return vmtarget != null;
- }
-}
diff --git a/openjdk/java/lang/invoke/MethodHandleImpl.java b/openjdk/java/lang/invoke/MethodHandleImpl.java
deleted file mode 100644
index 76c41aa0..00000000
--- a/openjdk/java/lang/invoke/MethodHandleImpl.java
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * Extensively modified for IKVM.NET by Jeroen Frijters
- * Copyright (C) 2011 Jeroen Frijters
- */
-
-package java.lang.invoke;
-
-import sun.invoke.util.VerifyType;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import sun.invoke.empty.Empty;
-import sun.invoke.util.ValueConversions;
-import sun.invoke.util.Wrapper;
-import sun.misc.Unsafe;
-import static java.lang.invoke.MethodHandleStatics.*;
-import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
-
-/**
- * Trusted implementation code for MethodHandle.
- * @author jrose
- */
-/*non-public*/ abstract class MethodHandleImpl {
- /// Factory methods to create method handles:
-
- private static final MemberName.Factory LOOKUP = MemberName.Factory.INSTANCE;
-
- static void initStatics() {
- // Trigger preceding sequence.
- }
-
- /** Look up a given method.
- * Callable only from sun.invoke and related packages.
- * <p>
- * The resulting method handle type will be of the given type,
- * with a receiver type {@code rcvc} prepended if the member is not static.
- * <p>
- * Access checks are made as of the given lookup class.
- * In particular, if the method is protected and {@code defc} is in a
- * different package from the lookup class, then {@code rcvc} must be
- * the lookup class or a subclass.
- * @param token Proof that the lookup class has access to this package.
- * @param member Resolved method or constructor to call.
- * @param name Name of the desired method.
- * @param rcvc Receiver type of desired non-static method (else null)
- * @param doDispatch whether the method handle will test the receiver type
- * @param lookupClass access-check relative to this class
- * @return a direct handle to the matching method
- * @throws IllegalAccessException if the given method cannot be accessed by the lookup class
- */
- static
- MethodHandle findMethod(MemberName method,
- boolean doDispatch, Class<?> lookupClass) throws IllegalAccessException {
- MethodType mtype = method.getMethodType();
- if (!method.isStatic()) {
- // adjust the advertised receiver type to be exactly the one requested
- // (in the case of invokespecial, this will be the calling class)
- Class<?> recvType = method.getDeclaringClass();
- mtype = mtype.insertParameterTypes(0, recvType);
- }
- DirectMethodHandle mh = new DirectMethodHandle(mtype, method, doDispatch, lookupClass);
- if (!mh.isValid())
- throw method.makeAccessException("no direct method handle", lookupClass);
- assert(mh.type() == mtype);
- if (!method.isVarargs())
- return mh;
- int argc = mtype.parameterCount();
- if (argc != 0) {
- Class<?> arrayType = mtype.parameterType(argc-1);
- if (arrayType.isArray())
- return AdapterMethodHandle.makeVarargsCollector(mh, arrayType);
- }
- throw method.makeAccessException("cannot make variable arity", null);
- }
-
- static
- MethodHandle makeAllocator(MethodHandle rawConstructor) {
- MethodType rawConType = rawConstructor.type();
- Class<?> allocateClass = rawConType.parameterType(0);
- // Wrap the raw (unsafe) constructor with the allocation of a suitable object.
- // allocator(arg...)
- // [fold]=> cookedConstructor(obj=allocate(C), arg...)
- // [dup,collect]=> identity(obj, void=rawConstructor(obj, arg...))
- MethodHandle returner = MethodHandles.identity(allocateClass);
- MethodType ctype = rawConType.insertParameterTypes(0, allocateClass).changeReturnType(allocateClass);
- MethodHandle cookedConstructor = AdapterMethodHandle.makeCollectArguments(returner, rawConstructor, 1, false);
- assert(cookedConstructor.type().equals(ctype));
- ctype = ctype.dropParameterTypes(0, 1);
- cookedConstructor = AdapterMethodHandle.makeCollectArguments(cookedConstructor, returner, 0, true);
- MethodHandle allocator = new AllocateObject(allocateClass);
- // allocate() => new C(void)
- assert(allocator.type().equals(MethodType.methodType(allocateClass)));
- ctype = ctype.dropParameterTypes(0, 1);
- MethodHandle fold = foldArguments(cookedConstructor, ctype, 0, allocator);
- return fold;
- }
-
- static final class AllocateObject<C> extends BoundMethodHandle {
- private static final Unsafe unsafe = Unsafe.getUnsafe();
-
- private final Class<C> allocateClass;
-
- // for allocation only:
- private AllocateObject(Class<C> allocateClass) {
- super(ALLOCATE.asType(MethodType.methodType(allocateClass, AllocateObject.class)));
- this.allocateClass = allocateClass;
- }
- @SuppressWarnings("unchecked")
- private C allocate() throws InstantiationException {
- return (C) unsafe.allocateInstance(allocateClass);
- }
- static final MethodHandle ALLOCATE;
- static {
- try {
- ALLOCATE = IMPL_LOOKUP.findVirtual(AllocateObject.class, "allocate", MethodType.genericMethodType(0));
- } catch (ReflectiveOperationException ex) {
- throw uncaughtException(ex);
- }
- }
- }
-
- static
- MethodHandle accessField(MemberName member, boolean isSetter,
- Class<?> lookupClass) {
- // Use sun. misc.Unsafe to dig up the dirt on the field.
- MethodHandle mh = new FieldAccessor(member, isSetter);
- return mh;
- }
-
- static
- MethodHandle accessArrayElement(Class<?> arrayClass, boolean isSetter) {
- if (!arrayClass.isArray())
- throw newIllegalArgumentException("not an array: "+arrayClass);
- Class<?> elemClass = arrayClass.getComponentType();
- MethodHandle[] mhs = FieldAccessor.ARRAY_CACHE.get(elemClass);
- if (mhs == null) {
- if (!FieldAccessor.doCache(elemClass))
- return FieldAccessor.ahandle(arrayClass, isSetter);
- mhs = new MethodHandle[] {
- FieldAccessor.ahandle(arrayClass, false),
- FieldAccessor.ahandle(arrayClass, true)
- };
- if (mhs[0].type().parameterType(0) == Class.class) {
- mhs[0] = mhs[0].bindTo(elemClass);
- mhs[1] = mhs[1].bindTo(elemClass);
- }
- synchronized (FieldAccessor.ARRAY_CACHE) {} // memory barrier
- FieldAccessor.ARRAY_CACHE.put(elemClass, mhs);
- }
- return mhs[isSetter ? 1 : 0];
- }
-
- static final class FieldAccessor<C,V> extends BoundMethodHandle {
- private static final Unsafe unsafe = Unsafe.getUnsafe();
- final Object base; // for static refs only
- final long offset;
- final String name;
-
- FieldAccessor(MemberName field, boolean isSetter) {
- super(fhandle(field.getDeclaringClass(), field.getFieldType(), isSetter, field.isStatic()));
- this.offset = fieldOffset(field);
- this.name = field.getName();
- this.base = null;
- }
- @Override
- String debugString() { return addTypeString(name, this); }
-
- int getFieldI(C obj) { return unsafe.getInt(obj, offset); }
- void setFieldI(C obj, int x) { unsafe.putInt(obj, offset, x); }
- long getFieldJ(C obj) { return unsafe.getLong(obj, offset); }
- void setFieldJ(C obj, long x) { unsafe.putLong(obj, offset, x); }
- float getFieldF(C obj) { return unsafe.getFloat(obj, offset); }
- void setFieldF(C obj, float x) { unsafe.putFloat(obj, offset, x); }
- double getFieldD(C obj) { return unsafe.getDouble(obj, offset); }
- void setFieldD(C obj, double x) { unsafe.putDouble(obj, offset, x); }
- boolean getFieldZ(C obj) { return unsafe.getBoolean(obj, offset); }
- void setFieldZ(C obj, boolean x) { unsafe.putBoolean(obj, offset, x); }
- byte getFieldB(C obj) { return unsafe.getByte(obj, offset); }
- void setFieldB(C obj, byte x) { unsafe.putByte(obj, offset, x); }
- short getFieldS(C obj) { return unsafe.getShort(obj, offset); }
- void setFieldS(C obj, short x) { unsafe.putShort(obj, offset, x); }
- char getFieldC(C obj) { return unsafe.getChar(obj, offset); }
- void setFieldC(C obj, char x) { unsafe.putChar(obj, offset, x); }
- @SuppressWarnings("unchecked")
- V getFieldL(C obj) { return (V) unsafe.getObject(obj, offset); }
- @SuppressWarnings("unchecked")
- void setFieldL(C obj, V x) { unsafe.putObject(obj, offset, x); }
- // cast (V) is OK here, since we wrap convertArguments around the MH.
-
- static Integer fieldOffset(final MemberName field) {
- return AccessController.doPrivileged(new PrivilegedAction<Integer>() {
- public Integer run() {
- try {
- Class c = field.getDeclaringClass();
- // FIXME: Should not have to create 'f' to get this value.
- java.lang.reflect.Field f = c.getDeclaredField(field.getName());
- return unsafe.fieldOffset(f);
- } catch (NoSuchFieldException ee) {
- throw uncaughtException(ee);
- }
- }
- });
- }
-
- int getStaticI() { return unsafe.getInt(base, offset); }
- void setStaticI(int x) { unsafe.putInt(base, offset, x); }
- long getStaticJ() { return unsafe.getLong(base, offset); }
- void setStaticJ(long x) { unsafe.putLong(base, offset, x); }
- float getStaticF() { return unsafe.getFloat(base, offset); }
- void setStaticF(float x) { unsafe.putFloat(base, offset, x); }
- double getStaticD() { return unsafe.getDouble(base, offset); }
- void setStaticD(double x) { unsafe.putDouble(base, offset, x); }
- boolean getStaticZ() { return unsafe.getBoolean(base, offset); }
- void setStaticZ(boolean x) { unsafe.putBoolean(base, offset, x); }
- byte getStaticB() { return unsafe.getByte(base, offset); }
- void setStaticB(byte x) { unsafe.putByte(base, offset, x); }
- short getStaticS() { return unsafe.getShort(base, offset); }
- void setStaticS(short x) { unsafe.putShort(base, offset, x); }
- char getStaticC() { return unsafe.getChar(base, offset); }
- void setStaticC(char x) { unsafe.putChar(base, offset, x); }
- V getStaticL() { return (V) unsafe.getObject(base, offset); }
- void setStaticL(V x) { unsafe.putObject(base, offset, x); }
-
- static String fname(Class<?> vclass, boolean isSetter, boolean isStatic) {
- String stem;
- if (!isStatic)
- stem = (!isSetter ? "getField" : "setField");
- else
- stem = (!isSetter ? "getStatic" : "setStatic");
- return stem + Wrapper.basicTypeChar(vclass);
- }
- static MethodType ftype(Class<?> cclass, Class<?> vclass, boolean isSetter, boolean isStatic) {
- MethodType type;
- if (!isStatic) {
- if (!isSetter)
- return MethodType.methodType(vclass, cclass);
- else
- return MethodType.methodType(void.class, cclass, vclass);
- } else {
- if (!isSetter)
- return MethodType.methodType(vclass);
- else
- return MethodType.methodType(void.class, vclass);
- }
- }
- static MethodHandle fhandle(Class<?> cclass, Class<?> vclass, boolean isSetter, boolean isStatic) {
- String name = FieldAccessor.fname(vclass, isSetter, isStatic);
- if (cclass.isPrimitive()) throw newIllegalArgumentException("primitive "+cclass);
- Class<?> ecclass = Object.class; //erase this type
- Class<?> evclass = vclass;
- if (!evclass.isPrimitive()) evclass = Object.class;
- MethodType type = FieldAccessor.ftype(ecclass, evclass, isSetter, isStatic);
- MethodHandle mh;
- try {
- mh = IMPL_LOOKUP.findVirtual(FieldAccessor.class, name, type);
- } catch (ReflectiveOperationException ex) {
- throw uncaughtException(ex);
- }
- if (evclass != vclass || (!isStatic && ecclass != cclass)) {
- MethodType strongType = FieldAccessor.ftype(cclass, vclass, isSetter, isStatic);
- strongType = strongType.insertParameterTypes(0, FieldAccessor.class);
- mh = convertArguments(mh, strongType, 0);
- }
- return mh;
- }
-
- /// Support for array element access
- static final HashMap<Class<?>, MethodHandle[]> ARRAY_CACHE =
- new HashMap<Class<?>, MethodHandle[]>();
- // FIXME: Cache on the classes themselves, not here.
- static boolean doCache(Class<?> elemClass) {
- if (elemClass.isPrimitive()) return true;
- ClassLoader cl = elemClass.getClassLoader();
- return cl == null || cl == ClassLoader.getSystemClassLoader();
- }
- static int getElementI(int[] a, int i) { return a[i]; }
- static void setElementI(int[] a, int i, int x) { a[i] = x; }
- static long getElementJ(long[] a, int i) { return a[i]; }
- static void setElementJ(long[] a, int i, long x) { a[i] = x; }
- static float getElementF(float[] a, int i) { return a[i]; }
- static void setElementF(float[] a, int i, float x) { a[i] = x; }
- static double getElementD(double[] a, int i) { return a[i]; }
- static void setElementD(double[] a, int i, double x) { a[i] = x; }
- static boolean getElementZ(boolean[] a, int i) { return a[i]; }
- static void setElementZ(boolean[] a, int i, boolean x) { a[i] = x; }
- static byte getElementB(byte[] a, int i) { return a[i]; }
- static void setElementB(byte[] a, int i, byte x) { a[i] = x; }
- static short getElementS(short[] a, int i) { return a[i]; }
- static void setElementS(short[] a, int i, short x) { a[i] = x; }
- static char getElementC(char[] a, int i) { return a[i]; }
- static void setElementC(char[] a, int i, char x) { a[i] = x; }
- static Object getElementL(Object[] a, int i) { return a[i]; }
- static void setElementL(Object[] a, int i, Object x) { a[i] = x; }
- static <V> V getElementL(Class<V[]> aclass, V[] a, int i) { return aclass.cast(a)[i]; }
- static <V> void setElementL(Class<V[]> aclass, V[] a, int i, V x) { aclass.cast(a)[i] = x; }
-
- static String aname(Class<?> aclass, boolean isSetter) {
- Class<?> vclass = aclass.getComponentType();
- if (vclass == null) throw new IllegalArgumentException();
- return (!isSetter ? "getElement" : "setElement") + Wrapper.basicTypeChar(vclass);
- }
- static MethodType atype(Class<?> aclass, boolean isSetter) {
- Class<?> vclass = aclass.getComponentType();
- if (!isSetter)
- return MethodType.methodType(vclass, aclass, int.class);
- else
- return MethodType.methodType(void.class, aclass, int.class, vclass);
- }
- static MethodHandle ahandle(Class<?> aclass, boolean isSetter) {
- Class<?> vclass = aclass.getComponentType();
- String name = FieldAccessor.aname(aclass, isSetter);
- Class<?> caclass = null;
- if (!vclass.isPrimitive() && vclass != Object.class) {
- caclass = aclass;
- aclass = Object[].class;
- vclass = Object.class;
- }
- MethodType type = FieldAccessor.atype(aclass, isSetter);
- if (caclass != null)
- type = type.insertParameterTypes(0, Class.class);
- MethodHandle mh;
- try {
- mh = IMPL_LOOKUP.findStatic(FieldAccessor.class, name, type);
- } catch (ReflectiveOperationException ex) {
- throw uncaughtException(ex);
- }
- if (caclass != null) {
- MethodType strongType = FieldAccessor.atype(caclass, isSetter);
- mh = mh.bindTo(caclass);
- mh = convertArguments(mh, strongType, 0);
- }
- return mh;
- }
- }
-
- /** Bind a predetermined first argument to the given direct method handle.
- * Callable only from MethodHandles.
- * @param token Proof that the caller has access to this package.
- * @param target Any direct method handle.
- * @param receiver Receiver (or first static method argument) to pre-bind.
- * @return a BoundMethodHandle for the given DirectMethodHandle, or null if it does not exist
- */
- static
- MethodHandle bindReceiver(MethodHandle target, Object receiver) {
- if (receiver == null) return null;
- return new BoundMethodHandle(target, receiver, 0);
- }
-
- /** Bind a predetermined argument to the given arbitrary method handle.
- * Callable only from MethodHandles.
- * @param token Proof that the caller has access to this package.
- * @param target Any method handle.
- * @param receiver Argument (which can be a boxed primitive) to pre-bind.
- * @return a suitable BoundMethodHandle
- */
- static
- MethodHandle bindArgument(MethodHandle target, int argnum, Object receiver) {
- return new BoundMethodHandle(target, receiver, argnum);
- }
-
- static native MethodHandle permuteArguments(MethodHandle target,
- MethodType newType,
- MethodType oldType,
- int[] permutationOrNull);
-
- /*non-public*/ static
- MethodHandle convertArguments(MethodHandle target, MethodType newType, int level) {
- MethodType oldType = target.type();
- if (oldType.equals(newType))
- return target;
- assert(level > 1 || oldType.isConvertibleTo(newType));
- MethodHandle retFilter = null;
- Class<?> oldRT = oldType.returnType();
- Class<?> newRT = newType.returnType();
- if (!VerifyType.isNullConversion(oldRT, newRT)) {
- if (oldRT == void.class) {
- Wrapper wrap = newRT.isPrimitive() ? Wrapper.forPrimitiveType(newRT) : Wrapper.OBJECT;
- retFilter = ValueConversions.zeroConstantFunction(wrap);
- } else {
- retFilter = MethodHandles.identity(newRT);
- retFilter = convertArguments(retFilter, retFilter.type().changeParameterType(0, oldRT), level);
- }
- newType = newType.changeReturnType(oldRT);
- }
- MethodHandle res = null;
- Exception ex = null;
- try {
- res = convertArguments(target, newType, oldType, level);
- } catch (IllegalArgumentException ex1) {
- ex = ex1;
- }
- if (res == null) {
- WrongMethodTypeException wmt = new WrongMethodTypeException("cannot convert to "+newType+": "+target);
- wmt.initCause(ex);
- throw wmt;
- }
- if (retFilter != null)
- res = MethodHandles.filterReturnValue(res, retFilter);
- return res;
- }
-
- static MethodHandle convertArguments(MethodHandle target,
- MethodType newType,
- MethodType oldType,
- int level) {
- assert(oldType.parameterCount() == target.type().parameterCount());
- if (newType == oldType)
- return target;
- if (oldType.parameterCount() != newType.parameterCount())
- throw newIllegalArgumentException("mismatched parameter count", oldType, newType);
- return AdapterMethodHandle.makePairwiseConvert(newType, target, level);
- }
-
- static MethodHandle spreadArguments(MethodHandle target, Class<?> arrayType, int arrayLength) {
- MethodType oldType = target.type();
- int nargs = oldType.parameterCount();
- int keepPosArgs = nargs - arrayLength;
- MethodType newType = oldType
- .dropParameterTypes(keepPosArgs, nargs)
- .insertParameterTypes(keepPosArgs, arrayType);
- return spreadArguments(target, newType, keepPosArgs, arrayType, arrayLength);
- }
- // called internally only
- static MethodHandle spreadArgumentsFromPos(MethodHandle target, MethodType newType, int spreadArgPos) {
- int arrayLength = target.type().parameterCount() - spreadArgPos;
- return spreadArguments(target, newType, spreadArgPos, Object[].class, arrayLength);
- }
- static MethodHandle spreadArguments(MethodHandle target,
- MethodType newType,
- int spreadArgPos,
- Class<?> arrayType,
- int arrayLength) {
- // TO DO: maybe allow the restarg to be Object and implicitly cast to Object[]
- MethodType oldType = target.type();
- // spread the last argument of newType to oldType
- assert(arrayLength == oldType.parameterCount() - spreadArgPos);
- assert(newType.parameterType(spreadArgPos) == arrayType);
- return AdapterMethodHandle.makeSpreadArguments(newType, target, arrayType, spreadArgPos, arrayLength);
- }
-
- static MethodHandle collectArguments(MethodHandle target,
- int collectArg,
- MethodHandle collector) {
- MethodType type = target.type();
- Class<?> collectType = collector.type().returnType();
- assert(collectType != void.class); // else use foldArguments
- if (collectType != type.parameterType(collectArg))
- target = target.asType(type.changeParameterType(collectArg, collectType));
- MethodType newType = type
- .dropParameterTypes(collectArg, collectArg+1)
- .insertParameterTypes(collectArg, collector.type().parameterArray());
- return collectArguments(target, newType, collectArg, collector);
- }
- static MethodHandle collectArguments(MethodHandle target,
- MethodType newType,
- int collectArg,
- MethodHandle collector) {
- MethodType oldType = target.type(); // (a...,c)=>r
- // newType // (a..., b...)=>r
- MethodType colType = collector.type(); // (b...)=>c
- // oldType // (a..., b...)=>r
- assert(newType.parameterCount() == collectArg + colType.parameterCount());
- assert(oldType.parameterCount() == collectArg + 1);
- return AdapterMethodHandle.makeCollectArguments(target, collector, collectArg, false);
- }
-
- static MethodHandle filterArgument(MethodHandle target,
- int pos,
- MethodHandle filter) {
- MethodType ttype = target.type();
- MethodType ftype = filter.type();
- assert(ftype.parameterCount() == 1);
- return AdapterMethodHandle.makeCollectArguments(target, filter, pos, false);
- }
-
- static MethodHandle foldArguments(MethodHandle target,
- MethodType newType,
- int foldPos,
- MethodHandle combiner) {
- MethodType oldType = target.type();
- MethodType ctype = combiner.type();
- return AdapterMethodHandle.makeCollectArguments(target, combiner, foldPos, true);
- }
-
- static
- MethodHandle dropArguments(MethodHandle target,
- MethodType newType, int argnum) {
- int drops = newType.parameterCount() - target.type().parameterCount();
- return AdapterMethodHandle.makeDropArguments(newType, target, argnum, drops);
- }
-
- static
- MethodHandle selectAlternative(boolean testResult, MethodHandle target, MethodHandle fallback) {
- return testResult ? target : fallback;
- }
-
- static MethodHandle SELECT_ALTERNATIVE;
- static MethodHandle selectAlternative() {
- if (SELECT_ALTERNATIVE != null) return SELECT_ALTERNATIVE;
- try {
- SELECT_ALTERNATIVE
- = IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "selectAlternative",
- MethodType.methodType(MethodHandle.class, boolean.class, MethodHandle.class, MethodHandle.class));
- } catch (ReflectiveOperationException ex) {
- throw new RuntimeException(ex);
- }
- return SELECT_ALTERNATIVE;
- }
-
- static
- MethodHandle makeGuardWithTest(MethodHandle test,
- MethodHandle target,
- MethodHandle fallback) {
- // gwt(arg...)
- // [fold]=> continueAfterTest(z=test(arg...), arg...)
- // [filter]=> (tf=select(z))(arg...)
- // where select(z) = select(z, t, f).bindTo(t, f) => z ? t f
- // [tailcall]=> tf(arg...)
- assert(test.type().returnType() == boolean.class);
- MethodType targetType = target.type();
- MethodType foldTargetType = targetType.insertParameterTypes(0, boolean.class);
- // working backwards, as usual:
- assert(target.type().equals(fallback.type()));
- MethodHandle tailcall = MethodHandles.exactInvoker(target.type());
- MethodHandle select = selectAlternative();
- select = bindArgument(select, 2, fallback);
- select = bindArgument(select, 1, target);
- // select(z: boolean) => (z ? target : fallback)
- MethodHandle filter = filterArgument(tailcall, 0, select);
- assert(filter.type().parameterType(0) == boolean.class);
- MethodHandle fold = foldArguments(filter, filter.type().dropParameterTypes(0, 1), 0, test);
- return fold;
- }
-
- private static class GuardWithCatch extends BoundMethodHandle {
- private final MethodHandle target;
- private final Class<? extends Throwable> exType;
- private final MethodHandle catcher;
- GuardWithCatch(MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) {
- this(INVOKES[target.type().parameterCount()], target, exType, catcher);
- }
- // FIXME: Build the control flow out of foldArguments.
- GuardWithCatch(MethodHandle invoker,
- MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) {
- super(invoker);
- this.target = target;
- this.exType = exType;
- this.catcher = catcher;
- }
- @Override
- String debugString() {
- return addTypeString(target, this);
- }
- private Object invoke_V(Object... av) throws Throwable {
- try {
- return target.invokeExact(av);
- } catch (Throwable t) {
- if (!exType.isInstance(t)) throw t;
- return catcher.invokeExact(t, av);
- }
- }
- private Object invoke_L0() throws Throwable {
- try {
- return target.invokeExact();
- } catch (Throwable t) {
- if (!exType.isInstance(t)) throw t;
- return catcher.invokeExact(t);
- }
- }
- private Object invoke_L1(Object a0) throws Throwable {
- try {
- return target.invokeExact(a0);
- } catch (Throwable t) {
- if (!exType.isInstance(t)) throw t;
- return catcher.invokeExact(t, a0);
- }
- }
- private Object invoke_L2(Object a0, Object a1) throws Throwable {
- try {
- return target.invokeExact(a0, a1);
- } catch (Throwable t) {
- if (!exType.isInstance(t)) throw t;
- return catcher.invokeExact(t, a0, a1);
- }
- }
- private Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable {
- try {
- return target.invokeExact(a0, a1, a2);
- } catch (Throwable t) {
- if (!exType.isInstance(t)) throw t;
- return catcher.invokeExact(t, a0, a1, a2);
- }
- }
- private Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- try {
- return target.invokeExact(a0, a1, a2, a3);
- } catch (Throwable t) {
- if (!exType.isInstance(t)) throw t;
- return catcher.invokeExact(t, a0, a1, a2, a3);
- }
- }
- private Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable {
- try {
- return target.invokeExact(a0, a1, a2, a3, a4);
- } catch (Throwable t) {
- if (!exType.isInstance(t)) throw t;
- return catcher.invokeExact(t, a0, a1, a2, a3, a4);
- }
- }
- private Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable {
- try {
- return target.invokeExact(a0, a1, a2, a3, a4, a5);
- } catch (Throwable t) {
- if (!exType.isInstance(t)) throw t;
- return catcher.invokeExact(t, a0, a1, a2, a3, a4, a5);
- }
- }
- private Object invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable {
- try {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6);
- } catch (Throwable t) {
- if (!exType.isInstance(t)) throw t;
- return catcher.invokeExact(t, a0, a1, a2, a3, a4, a5, a6);
- }
- }
- private Object invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable {
- try {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7);
- } catch (Throwable t) {
- if (!exType.isInstance(t)) throw t;
- return catcher.invokeExact(t, a0, a1, a2, a3, a4, a5, a6, a7);
- }
- }
- static MethodHandle[] makeInvokes() {
- ArrayList<MethodHandle> invokes = new ArrayList<MethodHandle>();
- MethodHandles.Lookup lookup = IMPL_LOOKUP;
- for (;;) {
- int nargs = invokes.size();
- String name = "invoke_L"+nargs;
- MethodHandle invoke = null;
- try {
- invoke = lookup.findVirtual(GuardWithCatch.class, name, MethodType.genericMethodType(nargs));
- } catch (ReflectiveOperationException ex) {
- }
- if (invoke == null) break;
- invokes.add(invoke);
- }
- assert(invokes.size() == 9); // current number of methods
- return invokes.toArray(new MethodHandle[0]);
- };
- static final MethodHandle[] INVOKES = makeInvokes();
- // For testing use this:
- //static final MethodHandle[] INVOKES = Arrays.copyOf(makeInvokes(), 2);
- static final MethodHandle VARARGS_INVOKE;
- static {
- try {
- VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(GuardWithCatch.class, "invoke_V", MethodType.genericMethodType(0, true));
- } catch (ReflectiveOperationException ex) {
- throw uncaughtException(ex);
- }
- }
- }
-
-
- static
- MethodHandle makeGuardWithCatch(MethodHandle target,
- Class<? extends Throwable> exType,
- MethodHandle catcher) {
- MethodType type = target.type();
- MethodType ctype = catcher.type();
- int nargs = type.parameterCount();
- if (nargs < GuardWithCatch.INVOKES.length) {
- MethodType gtype = type.generic();
- MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class);
- // Note: convertArguments(...2) avoids interface casts present in convertArguments(...0)
- MethodHandle gtarget = convertArguments(target, gtype, type, 2);
- MethodHandle gcatcher = convertArguments(catcher, gcatchType, ctype, 2);
- MethodHandle gguard = new GuardWithCatch(gtarget, exType, gcatcher);
- if (gtarget == null || gcatcher == null || gguard == null) return null;
- return convertArguments(gguard, type, gtype, 2);
- } else {
- MethodType gtype = MethodType.genericMethodType(0, true);
- MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class);
- MethodHandle gtarget = spreadArgumentsFromPos(target, gtype, 0);
- catcher = catcher.asType(ctype.changeParameterType(0, Throwable.class));
- MethodHandle gcatcher = spreadArgumentsFromPos(catcher, gcatchType, 1);
- MethodHandle gguard = new GuardWithCatch(GuardWithCatch.VARARGS_INVOKE, gtarget, exType, gcatcher);
- if (gtarget == null || gcatcher == null || gguard == null) return null;
- return collectArguments(gguard, type, 0, ValueConversions.varargsArray(nargs)).asType(type);
- }
- }
-
- static
- MethodHandle throwException(MethodType type) {
- return AdapterMethodHandle.makeRetypeRaw(type, throwException());
- }
-
- static MethodHandle THROW_EXCEPTION;
- static MethodHandle throwException() {
- if (THROW_EXCEPTION != null) return THROW_EXCEPTION;
- try {
- THROW_EXCEPTION
- = IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "throwException",
- MethodType.methodType(Empty.class, Throwable.class));
- } catch (ReflectiveOperationException ex) {
- throw new RuntimeException(ex);
- }
- return THROW_EXCEPTION;
- }
- static <T extends Throwable> Empty throwException(T t) throws T { throw t; }
-}
diff --git a/openjdk/java/lang/invoke/MethodHandleNatives.java b/openjdk/java/lang/invoke/MethodHandleNatives.java
deleted file mode 100644
index 4f7da894..00000000
--- a/openjdk/java/lang/invoke/MethodHandleNatives.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * Extensively modified for IKVM.NET by Jeroen Frijters
- * Copyright (C) 2011 Jeroen Frijters
- */
-
-package java.lang.invoke;
-
-import java.lang.invoke.MethodHandles.Lookup;
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Field;
-import static java.lang.invoke.MethodHandleNatives.Constants.*;
-import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
-
-/**
- * The JVM interface for the method handles package is all here.
- * This is an interface internal and private to an implemetantion of JSR 292.
- * <em>This class is not part of the JSR 292 standard.</em>
- * @author jrose
- */
-class MethodHandleNatives {
-
- private MethodHandleNatives() { } // static only
-
- /// MethodName support
-
- static native void init(MemberName self, Object ref);
- static native void expand(MemberName self);
- static native void resolve(MemberName self, Class<?> caller);
- static native int getMembers(Class<?> defc, String matchName, String matchSig,
- int matchFlags, Class<?> caller, int skip, MemberName[] results);
-
- /** Initialize a method type, once per form. */
- static void init(MethodType self) { }
-
- /** Fetch the name of the handled method, if available.
- * This routine is for debugging and reflection.
- */
- static MemberName getMethodName(MethodHandle self) {
- throw new ikvm.internal.NotYetImplementedError();
- }
-
- static Object[] makeTarget(Class<?> defc, String name, String sig, int mods, Class<?> refc) {
- return new Object[] { defc, name, sig, mods, refc };
- }
-
- /** Java copy of MethodHandlePushLimit in range 2..255. */
- static final int JVM_PUSH_LIMIT;
- /** JVM stack motion (in words) after one slot is pushed, usually -1.
- */
- static final int JVM_STACK_MOVE_UNIT;
-
- /** Which conv-ops are implemented by the JVM? */
- static final int CONV_OP_IMPLEMENTED_MASK;
- /** Derived mode flag. Only false on some old JVM implementations. */
- static final boolean HAVE_RICOCHET_FRAMES;
-
- static final int OP_ROT_ARGS_DOWN_LIMIT_BIAS;
-
- static {
- int k;
- JVM_PUSH_LIMIT = 3;
- JVM_STACK_MOVE_UNIT = 1;
- k = 0;
- CONV_OP_IMPLEMENTED_MASK = (k != 0) ? k : DEFAULT_CONV_OP_IMPLEMENTED_MASK;
- k = 0;
- OP_ROT_ARGS_DOWN_LIMIT_BIAS = (k != 0) ? (byte)k : -1;
- HAVE_RICOCHET_FRAMES = (CONV_OP_IMPLEMENTED_MASK & (1<<OP_COLLECT_ARGS)) != 0;
- //sun.reflect.Reflection.registerMethodsToFilter(MethodHandleImpl.class, "init");
- }
-
- // All compile-time constants go here.
- // There is an opportunity to check them against the JVM's idea of them.
- static class Constants {
- Constants() { } // static only
- // MethodHandleImpl
- static final int // for getConstant
- GC_JVM_PUSH_LIMIT = 0,
- GC_JVM_STACK_MOVE_UNIT = 1,
- GC_CONV_OP_IMPLEMENTED_MASK = 2,
- GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS = 3;
- static final int
- ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method)
- ETF_DIRECT_HANDLE = 1, // ultimate method handle (will be a DMH, may be self)
- ETF_METHOD_NAME = 2, // ultimate method as MemberName
- ETF_REFLECT_METHOD = 3; // ultimate method as java.lang.reflect object (sans refClass)
-
- // MemberName
- // The JVM uses values of -2 and above for vtable indexes.
- // Field values are simple positive offsets.
- // Ref: src/share/vm/oops/methodOop.hpp
- // This value is negative enough to avoid such numbers,
- // but not too negative.
- static final int
- MN_IS_METHOD = 0x00010000, // method (not constructor)
- MN_IS_CONSTRUCTOR = 0x00020000, // constructor
- MN_IS_FIELD = 0x00040000, // field
- MN_IS_TYPE = 0x00080000, // nested type
- MN_SEARCH_SUPERCLASSES = 0x00100000, // for MHN.getMembers
- MN_SEARCH_INTERFACES = 0x00200000, // for MHN.getMembers
- VM_INDEX_UNINITIALIZED = -99;
-
- // BoundMethodHandle
- /** Constants for decoding the vmargslot field, which contains 2 values. */
- static final int
- ARG_SLOT_PUSH_SHIFT = 16,
- ARG_SLOT_MASK = (1<<ARG_SLOT_PUSH_SHIFT)-1;
-
- // AdapterMethodHandle
- /** Conversions recognized by the JVM.
- * They must align with the constants in java.lang.invoke.AdapterMethodHandle,
- * in the JVM file hotspot/src/share/vm/classfile/javaClasses.hpp.
- */
- static final int
- OP_RETYPE_ONLY = 0x0, // no argument changes; straight retype
- OP_RETYPE_RAW = 0x1, // straight retype, trusted (void->int, Object->T)
- OP_CHECK_CAST = 0x2, // ref-to-ref conversion; requires a Class argument
- OP_PRIM_TO_PRIM = 0x3, // converts from one primitive to another
- OP_REF_TO_PRIM = 0x4, // unboxes a wrapper to produce a primitive
- OP_PRIM_TO_REF = 0x5, // boxes a primitive into a wrapper
- OP_SWAP_ARGS = 0x6, // swap arguments (vminfo is 2nd arg)
- OP_ROT_ARGS = 0x7, // rotate arguments (vminfo is displaced arg)
- OP_DUP_ARGS = 0x8, // duplicates one or more arguments (at TOS)
- OP_DROP_ARGS = 0x9, // remove one or more argument slots
- OP_COLLECT_ARGS = 0xA, // combine arguments using an auxiliary function
- OP_SPREAD_ARGS = 0xB, // expand in place a varargs array (of known size)
- OP_FOLD_ARGS = 0xC, // combine but do not remove arguments; prepend result
- //OP_UNUSED_13 = 0xD, // unused code, perhaps for reified argument lists
- CONV_OP_LIMIT = 0xE; // limit of CONV_OP enumeration
- /** Shift and mask values for decoding the AMH.conversion field.
- * These numbers are shared with the JVM for creating AMHs.
- */
- static final int
- CONV_OP_MASK = 0xF00, // this nybble contains the conversion op field
- CONV_TYPE_MASK = 0x0F, // fits T_ADDRESS and below
- CONV_VMINFO_MASK = 0x0FF, // LSB is reserved for JVM use
- CONV_VMINFO_SHIFT = 0, // position of bits in CONV_VMINFO_MASK
- CONV_OP_SHIFT = 8, // position of bits in CONV_OP_MASK
- CONV_DEST_TYPE_SHIFT = 12, // byte 2 has the adapter BasicType (if needed)
- CONV_SRC_TYPE_SHIFT = 16, // byte 2 has the source BasicType (if needed)
- CONV_STACK_MOVE_SHIFT = 20, // high 12 bits give signed SP change
- CONV_STACK_MOVE_MASK = (1 << (32 - CONV_STACK_MOVE_SHIFT)) - 1;
-
- /** Which conv-ops are implemented by the JVM? */
- static final int DEFAULT_CONV_OP_IMPLEMENTED_MASK =
- // Value to use if the corresponding JVM query fails.
- ((1<<OP_RETYPE_ONLY)
- |(1<<OP_RETYPE_RAW)
- |(1<<OP_CHECK_CAST)
- |(1<<OP_PRIM_TO_PRIM)
- |(1<<OP_REF_TO_PRIM)
- |(1<<OP_SWAP_ARGS)
- |(1<<OP_ROT_ARGS)
- |(1<<OP_DUP_ARGS)
- |(1<<OP_DROP_ARGS)
- //|(1<<OP_SPREAD_ARGS)
- );
-
- /**
- * Basic types as encoded in the JVM. These code values are not
- * intended for use outside this class. They are used as part of
- * a private interface between the JVM and this class.
- */
- static final int
- T_BOOLEAN = 4,
- T_CHAR = 5,
- T_FLOAT = 6,
- T_DOUBLE = 7,
- T_BYTE = 8,
- T_SHORT = 9,
- T_INT = 10,
- T_LONG = 11,
- T_OBJECT = 12,
- //T_ARRAY = 13
- T_VOID = 14,
- //T_ADDRESS = 15
- T_ILLEGAL = 99;
-
- /**
- * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
- */
- static final int
- REF_getField = 1,
- REF_getStatic = 2,
- REF_putField = 3,
- REF_putStatic = 4,
- REF_invokeVirtual = 5,
- REF_invokeStatic = 6,
- REF_invokeSpecial = 7,
- REF_newInvokeSpecial = 8,
- REF_invokeInterface = 9;
- }
-
- /**
- * This assertion marks code which was written before ricochet frames were implemented.
- * Such code will go away when the ports catch up.
- */
- static boolean workaroundWithoutRicochetFrames() {
- assert(!HAVE_RICOCHET_FRAMES) : "this code should not be executed if `-XX:+UseRicochetFrames is enabled";
- return true;
- }
-}
diff --git a/openjdk/java/lang/invoke/MethodHandles.java b/openjdk/java/lang/invoke/MethodHandles.java
deleted file mode 100644
index 6f0db408..00000000
--- a/openjdk/java/lang/invoke/MethodHandles.java
+++ /dev/null
@@ -1,2273 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.invoke;
-
-import java.lang.reflect.*;
-import sun.invoke.WrapperInstance;
-import sun.invoke.util.ValueConversions;
-import sun.invoke.util.VerifyAccess;
-import sun.invoke.util.Wrapper;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Arrays;
-import sun.reflect.CallerSensitive;
-import sun.reflect.Reflection;
-import static java.lang.invoke.MethodHandleStatics.*;
-import static java.lang.invoke.MethodHandleNatives.Constants.*;
-
-/**
- * This class consists exclusively of static methods that operate on or return
- * method handles. They fall into several categories:
- * <ul>
- * <li>Lookup methods which help create method handles for methods and fields.
- * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
- * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
- * <li>Wrapper methods which can convert between method handles and interface types.
- * </ul>
- * <p>
- * @author John Rose, JSR 292 EG
- */
-public class MethodHandles {
-
- private MethodHandles() { } // do not instantiate
-
- private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
- static { MethodHandleImpl.initStatics(); }
- // See IMPL_LOOKUP below.
-
- //// Method handle creation from ordinary methods.
-
- /**
- * Returns a {@link Lookup lookup object} on the caller,
- * which has the capability to access any method handle that the caller has access to,
- * including direct method handles to private fields and methods.
- * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
- * Do not store it in place where untrusted code can access it.
- */
- @CallerSensitive
- public static Lookup lookup() {
- return new Lookup(Reflection.getCallerClass());
- }
-
- /**
- * Returns a {@link Lookup lookup object} which is trusted minimally.
- * It can only be used to create method handles to
- * publicly accessible fields and methods.
- * <p>
- * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
- * of this lookup object will be {@link java.lang.Object}.
- * <p>
- * The lookup class can be changed to any other class {@code C} using an expression of the form
- * {@linkplain Lookup#in <code>publicLookup().in(C.class)</code>}.
- * Since all classes have equal access to public names,
- * such a change would confer no new access rights.
- */
- public static Lookup publicLookup() {
- return Lookup.PUBLIC_LOOKUP;
- }
-
- /**
- * A <em>lookup object</em> is a factory for creating method handles,
- * when the creation requires access checking.
- * Method handles do not perform
- * access checks when they are called, but rather when they are created.
- * Therefore, method handle access
- * restrictions must be enforced when a method handle is created.
- * The caller class against which those restrictions are enforced
- * is known as the {@linkplain #lookupClass lookup class}.
- * <p>
- * A lookup class which needs to create method handles will call
- * {@link MethodHandles#lookup MethodHandles.lookup} to create a factory for itself.
- * When the {@code Lookup} factory object is created, the identity of the lookup class is
- * determined, and securely stored in the {@code Lookup} object.
- * The lookup class (or its delegates) may then use factory methods
- * on the {@code Lookup} object to create method handles for access-checked members.
- * This includes all methods, constructors, and fields which are allowed to the lookup class,
- * even private ones.
- * <p>
- * The factory methods on a {@code Lookup} object correspond to all major
- * use cases for methods, constructors, and fields.
- * Here is a summary of the correspondence between these factory methods and
- * the behavior the resulting method handles:
- * <code>
- * <table border=1 cellpadding=5 summary="lookup method behaviors">
- * <tr><th>lookup expression</th><th>member</th><th>behavior</th></tr>
- * <tr>
- * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
- * <td>FT f;</td><td>(T) this.f;</td>
- * </tr>
- * <tr>
- * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td>
- * <td>static<br>FT f;</td><td>(T) C.f;</td>
- * </tr>
- * <tr>
- * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td>
- * <td>FT f;</td><td>this.f = x;</td>
- * </tr>
- * <tr>
- * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td>
- * <td>static<br>FT f;</td><td>C.f = arg;</td>
- * </tr>
- * <tr>
- * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}</td>
- * <td>T m(A*);</td><td>(T) this.m(arg*);</td>
- * </tr>
- * <tr>
- * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}</td>
- * <td>static<br>T m(A*);</td><td>(T) C.m(arg*);</td>
- * </tr>
- * <tr>
- * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}</td>
- * <td>T m(A*);</td><td>(T) super.m(arg*);</td>
- * </tr>
- * <tr>
- * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}</td>
- * <td>C(A*);</td><td>(T) new C(arg*);</td>
- * </tr>
- * <tr>
- * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td>
- * <td>(static)?<br>FT f;</td><td>(FT) aField.get(thisOrNull);</td>
- * </tr>
- * <tr>
- * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td>
- * <td>(static)?<br>FT f;</td><td>aField.set(thisOrNull, arg);</td>
- * </tr>
- * <tr>
- * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
- * <td>(static)?<br>T m(A*);</td><td>(T) aMethod.invoke(thisOrNull, arg*);</td>
- * </tr>
- * <tr>
- * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td>
- * <td>C(A*);</td><td>(C) aConstructor.newInstance(arg*);</td>
- * </tr>
- * <tr>
- * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
- * <td>(static)?<br>T m(A*);</td><td>(T) aMethod.invoke(thisOrNull, arg*);</td>
- * </tr>
- * </table>
- * </code>
- * Here, the type {@code C} is the class or interface being searched for a member,
- * documented as a parameter named {@code refc} in the lookup methods.
- * The method or constructor type {@code MT} is composed from the return type {@code T}
- * and the sequence of argument types {@code A*}.
- * Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}.
- * The formal parameter {@code this} stands for the self-reference of type {@code C};
- * if it is present, it is always the leading argument to the method handle invocation.
- * The name {@code arg} stands for all the other method handle arguments.
- * In the code examples for the Core Reflection API, the name {@code thisOrNull}
- * stands for a null reference if the accessed method or field is static,
- * and {@code this} otherwise.
- * The names {@code aMethod}, {@code aField}, and {@code aConstructor} stand
- * for reflective objects corresponding to the given members.
- * <p>
- * In cases where the given member is of variable arity (i.e., a method or constructor)
- * the returned method handle will also be of {@linkplain MethodHandle#asVarargsCollector variable arity}.
- * In all other cases, the returned method handle will be of fixed arity.
- * <p>
- * The equivalence between looked-up method handles and underlying
- * class members can break down in a few ways:
- * <ul>
- * <li>If {@code C} is not symbolically accessible from the lookup class's loader,
- * the lookup can still succeed, even when there is no equivalent
- * Java expression or bytecoded constant.
- * <li>Likewise, if {@code T} or {@code MT}
- * is not symbolically accessible from the lookup class's loader,
- * the lookup can still succeed.
- * For example, lookups for {@code MethodHandle.invokeExact} and
- * {@code MethodHandle.invoke} will always succeed, regardless of requested type.
- * <li>If there is a security manager installed, it can forbid the lookup
- * on various grounds (<a href="#secmgr">see below</a>).
- * By contrast, the {@code ldc} instruction is not subject to
- * security manager checks.
- * </ul>
- *
- * <h3><a name="access"></a>Access checking</h3>
- * Access checks are applied in the factory methods of {@code Lookup},
- * when a method handle is created.
- * This is a key difference from the Core Reflection API, since
- * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
- * performs access checking against every caller, on every call.
- * <p>
- * All access checks start from a {@code Lookup} object, which
- * compares its recorded lookup class against all requests to
- * create method handles.
- * A single {@code Lookup} object can be used to create any number
- * of access-checked method handles, all checked against a single
- * lookup class.
- * <p>
- * A {@code Lookup} object can be shared with other trusted code,
- * such as a metaobject protocol.
- * A shared {@code Lookup} object delegates the capability
- * to create method handles on private members of the lookup class.
- * Even if privileged code uses the {@code Lookup} object,
- * the access checking is confined to the privileges of the
- * original lookup class.
- * <p>
- * A lookup can fail, because
- * the containing class is not accessible to the lookup class, or
- * because the desired class member is missing, or because the
- * desired class member is not accessible to the lookup class.
- * In any of these cases, a {@code ReflectiveOperationException} will be
- * thrown from the attempted lookup. The exact class will be one of
- * the following:
- * <ul>
- * <li>NoSuchMethodException &mdash; if a method is requested but does not exist
- * <li>NoSuchFieldException &mdash; if a field is requested but does not exist
- * <li>IllegalAccessException &mdash; if the member exists but an access check fails
- * </ul>
- * <p>
- * In general, the conditions under which a method handle may be
- * looked up for a method {@code M} are exactly equivalent to the conditions
- * under which the lookup class could have compiled and resolved a call to {@code M}.
- * And the effect of invoking the method handle resulting from the lookup
- * is exactly equivalent to executing the compiled and resolved call to {@code M}.
- * The same point is true of fields and constructors.
- * <p>
- * In some cases, access between nested classes is obtained by the Java compiler by creating
- * an wrapper method to access a private method of another class
- * in the same top-level declaration.
- * For example, a nested class {@code C.D}
- * can access private members within other related classes such as
- * {@code C}, {@code C.D.E}, or {@code C.B},
- * but the Java compiler may need to generate wrapper methods in
- * those related classes. In such cases, a {@code Lookup} object on
- * {@code C.E} would be unable to those private members.
- * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
- * which can transform a lookup on {@code C.E} into one on any of those other
- * classes, without special elevation of privilege.
- * <p>
- * Although bytecode instructions can only refer to classes in
- * a related class loader, this API can search for methods in any
- * class, as long as a reference to its {@code Class} object is
- * available. Such cross-loader references are also possible with the
- * Core Reflection API, and are impossible to bytecode instructions
- * such as {@code invokestatic} or {@code getfield}.
- * There is a {@linkplain java.lang.SecurityManager security manager API}
- * to allow applications to check such cross-loader references.
- * These checks apply to both the {@code MethodHandles.Lookup} API
- * and the Core Reflection API
- * (as found on {@link java.lang.Class Class}).
- * <p>
- * Access checks only apply to named and reflected methods,
- * constructors, and fields.
- * Other method handle creation methods, such as
- * {@link MethodHandle#asType MethodHandle.asType},
- * do not require any access checks, and are done
- * with static methods of {@link MethodHandles},
- * independently of any {@code Lookup} object.
- *
- * <h3>Security manager interactions</h3>
- * <a name="secmgr"></a>
- * If a security manager is present, member lookups are subject to
- * additional checks.
- * From one to four calls are made to the security manager.
- * Any of these calls can refuse access by throwing a
- * {@link java.lang.SecurityException SecurityException}.
- * Define {@code smgr} as the security manager,
- * {@code refc} as the containing class in which the member
- * is being sought, and {@code defc} as the class in which the
- * member is actually defined.
- * The calls are made according to the following rules:
- * <ul>
- * <li>In all cases, {@link SecurityManager#checkMemberAccess
- * smgr.checkMemberAccess(refc, Member.PUBLIC)} is called.
- * <li>If the class loader of the lookup class is not
- * the same as or an ancestor of the class loader of {@code refc},
- * then {@link SecurityManager#checkPackageAccess
- * smgr.checkPackageAccess(refcPkg)} is called,
- * where {@code refcPkg} is the package of {@code refc}.
- * <li>If the retrieved member is not public,
- * {@link SecurityManager#checkMemberAccess
- * smgr.checkMemberAccess(defc, Member.DECLARED)} is called.
- * (Note that {@code defc} might be the same as {@code refc}.)
- * The default implementation of this security manager method
- * inspects the stack to determine the original caller of
- * the reflective request (such as {@code findStatic}),
- * and performs additional permission checks if the
- * class loader of {@code defc} differs from the class
- * loader of the class from which the reflective request came.
- * <li>If the retrieved member is not public,
- * and if {@code defc} and {@code refc} are in different class loaders,
- * and if the class loader of the lookup class is not
- * the same as or an ancestor of the class loader of {@code defc},
- * then {@link SecurityManager#checkPackageAccess
- * smgr.checkPackageAccess(defcPkg)} is called,
- * where {@code defcPkg} is the package of {@code defc}.
- * </ul>
- */
- public static final
- class Lookup {
- /** The class on behalf of whom the lookup is being performed. */
- private final Class<?> lookupClass;
-
- /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
- private final int allowedModes;
-
- // [IKVM] when dynamically linking method handle constants, we don't want a security manager check
- private final boolean noSecurityCheck;
-
- /** A single-bit mask representing {@code public} access,
- * which may contribute to the result of {@link #lookupModes lookupModes}.
- * The value, {@code 0x01}, happens to be the same as the value of the
- * {@code public} {@linkplain java.lang.reflect.Modifier#PUBLIC modifier bit}.
- */
- public static final int PUBLIC = Modifier.PUBLIC;
-
- /** A single-bit mask representing {@code private} access,
- * which may contribute to the result of {@link #lookupModes lookupModes}.
- * The value, {@code 0x02}, happens to be the same as the value of the
- * {@code private} {@linkplain java.lang.reflect.Modifier#PRIVATE modifier bit}.
- */
- public static final int PRIVATE = Modifier.PRIVATE;
-
- /** A single-bit mask representing {@code protected} access,
- * which may contribute to the result of {@link #lookupModes lookupModes}.
- * The value, {@code 0x04}, happens to be the same as the value of the
- * {@code protected} {@linkplain java.lang.reflect.Modifier#PROTECTED modifier bit}.
- */
- public static final int PROTECTED = Modifier.PROTECTED;
-
- /** A single-bit mask representing {@code package} access (default access),
- * which may contribute to the result of {@link #lookupModes lookupModes}.
- * The value is {@code 0x08}, which does not correspond meaningfully to
- * any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
- */
- public static final int PACKAGE = Modifier.STATIC;
-
- private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE);
- private static final int TRUSTED = -1;
-
- private static int fixmods(int mods) {
- mods &= (ALL_MODES - PACKAGE);
- return (mods != 0) ? mods : PACKAGE;
- }
-
- /** Tells which class is performing the lookup. It is this class against
- * which checks are performed for visibility and access permissions.
- * <p>
- * The class implies a maximum level of access permission,
- * but the permissions may be additionally limited by the bitmask
- * {@link #lookupModes lookupModes}, which controls whether non-public members
- * can be accessed.
- */
- public Class<?> lookupClass() {
- return lookupClass;
- }
-
- // This is just for calling out to MethodHandleImpl.
- private Class<?> lookupClassOrNull() {
- return (allowedModes == TRUSTED) ? null : lookupClass;
- }
-
- /** Tells which access-protection classes of members this lookup object can produce.
- * The result is a bit-mask of the bits
- * {@linkplain #PUBLIC PUBLIC (0x01)},
- * {@linkplain #PRIVATE PRIVATE (0x02)},
- * {@linkplain #PROTECTED PROTECTED (0x04)},
- * and {@linkplain #PACKAGE PACKAGE (0x08)}.
- * <p>
- * A freshly-created lookup object
- * on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class}
- * has all possible bits set, since the caller class can access all its own members.
- * A lookup object on a new lookup class
- * {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
- * may have some mode bits set to zero.
- * The purpose of this is to restrict access via the new lookup object,
- * so that it can access only names which can be reached by the original
- * lookup object, and also by the new lookup class.
- */
- public int lookupModes() {
- return allowedModes & ALL_MODES;
- }
-
- /** Embody the current class (the lookupClass) as a lookup class
- * for method handle creation.
- * Must be called by from a method in this package,
- * which in turn is called by a method not in this package.
- * <p>
- * Also, don't make it private, lest javac interpose
- * an access$N method.
- */
- Lookup(Class<?> lookupClass) {
- this(lookupClass, ALL_MODES);
- checkUnprivilegedlookupClass(lookupClass);
- }
-
- private Lookup(Class<?> lookupClass, int allowedModes) {
- this(lookupClass, allowedModes, false);
- }
-
- Lookup(Class<?> lookupClass, int allowedModes, boolean noSecurityCheck) {
- this.lookupClass = lookupClass;
- this.allowedModes = allowedModes;
- this.noSecurityCheck = noSecurityCheck;
- }
-
- /**
- * Creates a lookup on the specified new lookup class.
- * The resulting object will report the specified
- * class as its own {@link #lookupClass lookupClass}.
- * <p>
- * However, the resulting {@code Lookup} object is guaranteed
- * to have no more access capabilities than the original.
- * In particular, access capabilities can be lost as follows:<ul>
- * <li>If the new lookup class differs from the old one,
- * protected members will not be accessible by virtue of inheritance.
- * (Protected members may continue to be accessible because of package sharing.)
- * <li>If the new lookup class is in a different package
- * than the old one, protected and default (package) members will not be accessible.
- * <li>If the new lookup class is not within the same package member
- * as the old one, private members will not be accessible.
- * <li>If the new lookup class is not accessible to the old lookup class,
- * then no members, not even public members, will be accessible.
- * (In all other cases, public members will continue to be accessible.)
- * </ul>
- *
- * @param requestedLookupClass the desired lookup class for the new lookup object
- * @return a lookup object which reports the desired lookup class
- * @throws NullPointerException if the argument is null
- */
- public Lookup in(Class<?> requestedLookupClass) {
- requestedLookupClass.getClass(); // null check
- if (allowedModes == TRUSTED) // IMPL_LOOKUP can make any lookup at all
- return new Lookup(requestedLookupClass, ALL_MODES);
- if (requestedLookupClass == this.lookupClass)
- return this; // keep same capabilities
- int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
- if ((newModes & PACKAGE) != 0
- && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
- newModes &= ~(PACKAGE|PRIVATE);
- }
- // Allow nestmate lookups to be created without special privilege:
- if ((newModes & PRIVATE) != 0
- && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
- newModes &= ~PRIVATE;
- }
- if ((newModes & PUBLIC) != 0
- && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass, allowedModes)) {
- // The requested class it not accessible from the lookup class.
- // No permissions.
- newModes = 0;
- }
- checkUnprivilegedlookupClass(requestedLookupClass);
- return new Lookup(requestedLookupClass, newModes);
- }
-
- // Make sure outer class is initialized first.
- static { IMPL_NAMES.getClass(); }
-
- /** Version of lookup which is trusted minimally.
- * It can only be used to create method handles to
- * publicly accessible members.
- */
- static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, PUBLIC);
-
- /** Package-private version of lookup which is trusted. */
- static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
-
- private static void checkUnprivilegedlookupClass(Class<?> lookupClass) {
- String name = lookupClass.getName();
- if (name.startsWith("java.lang.invoke."))
- throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
- }
-
- /**
- * Displays the name of the class from which lookups are to be made.
- * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
- * If there are restrictions on the access permitted to this lookup,
- * this is indicated by adding a suffix to the class name, consisting
- * of a slash and a keyword. The keyword represents the strongest
- * allowed access, and is chosen as follows:
- * <ul>
- * <li>If no access is allowed, the suffix is "/noaccess".
- * <li>If only public access is allowed, the suffix is "/public".
- * <li>If only public and package access are allowed, the suffix is "/package".
- * <li>If only public, package, and private access are allowed, the suffix is "/private".
- * </ul>
- * If none of the above cases apply, it is the case that full
- * access (public, package, private, and protected) is allowed.
- * In this case, no suffix is added.
- * This is true only of an object obtained originally from
- * {@link java.lang.invoke.MethodHandles#lookup MethodHandles.lookup}.
- * Objects created by {@link java.lang.invoke.MethodHandles.Lookup#in Lookup.in}
- * always have restricted access, and will display a suffix.
- * <p>
- * (It may seem strange that protected access should be
- * stronger than private access. Viewed independently from
- * package access, protected access is the first to be lost,
- * because it requires a direct subclass relationship between
- * caller and callee.)
- * @see #in
- */
- @Override
- public String toString() {
- String cname = lookupClass.getName();
- switch (allowedModes) {
- case 0: // no privileges
- return cname + "/noaccess";
- case PUBLIC:
- return cname + "/public";
- case PUBLIC|PACKAGE:
- return cname + "/package";
- case ALL_MODES & ~PROTECTED:
- return cname + "/private";
- case ALL_MODES:
- return cname;
- case TRUSTED:
- return "/trusted"; // internal only; not exported
- default: // Should not happen, but it's a bitfield...
- cname = cname + "/" + Integer.toHexString(allowedModes);
- assert(false) : cname;
- return cname;
- }
- }
-
- /* Obtain the external caller class, when called from Lookup.<init> or a first-level subroutine. */
- private static Class<?> getCallerClassAtEntryPoint(boolean inSubroutine) {
- final int CALLER_DEPTH = 4;
- // Stack for the constructor entry point (inSubroutine=false):
- // 0: Reflection.getCC, 1: getCallerClassAtEntryPoint,
- // 2: Lookup.<init>, 3: MethodHandles.*, 4: caller
- // The stack is slightly different for a subroutine of a Lookup.find* method:
- // 2: Lookup.*, 3: Lookup.find*.*, 4: caller
- // Note: This should be the only use of getCallerClass in this file.
- assert(Reflection.getCallerClass(CALLER_DEPTH-2) == Lookup.class);
- assert(Reflection.getCallerClass(CALLER_DEPTH-1) == (inSubroutine ? Lookup.class : MethodHandles.class));
- return Reflection.getCallerClass(CALLER_DEPTH);
- }
-
- /**
- * Produces a method handle for a static method.
- * The type of the method handle will be that of the method.
- * (Since static methods do not take receivers, there is no
- * additional receiver argument inserted into the method handle type,
- * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.)
- * The method and all its argument types must be accessible to the lookup class.
- * If the method's class has not yet been initialized, that is done
- * immediately, before the method handle is returned.
- * <p>
- * The returned method handle will have
- * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
- * the method's variable arity modifier bit ({@code 0x0080}) is set.
- * @param refc the class from which the method is accessed
- * @param name the name of the method
- * @param type the type of the method
- * @return the desired method handle
- * @throws NoSuchMethodException if the method does not exist
- * @throws IllegalAccessException if access checking fails,
- * or if the method is not {@code static},
- * or if the method's variable arity modifier bit
- * is set and {@code asVarargsCollector} fails
- * @exception SecurityException if a security manager is present and it
- * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
- * @throws NullPointerException if any argument is null
- */
- public
- MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
- MemberName method = resolveOrFail(refc, name, type, true);
- checkSecurityManager(refc, method); // stack walk magic: do not refactor
- return accessStatic(refc, method);
- }
- private
- MethodHandle accessStatic(Class<?> refc, MemberName method) throws IllegalAccessException {
- checkMethod(refc, method, true);
- return MethodHandleImpl.findMethod(method, false, lookupClassOrNull());
- }
- private
- MethodHandle resolveStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
- MemberName method = resolveOrFail(refc, name, type, true);
- return accessStatic(refc, method);
- }
-
- /**
- * Produces a method handle for a virtual method.
- * The type of the method handle will be that of the method,
- * with the receiver type (usually {@code refc}) prepended.
- * The method and all its argument types must be accessible to the lookup class.
- * <p>
- * When called, the handle will treat the first argument as a receiver
- * and dispatch on the receiver's type to determine which method
- * implementation to enter.
- * (The dispatching action is identical with that performed by an
- * {@code invokevirtual} or {@code invokeinterface} instruction.)
- * <p>
- * The returned method handle will have
- * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
- * the method's variable arity modifier bit ({@code 0x0080}) is set.
- * <p>
- * Because of the general equivalence between {@code invokevirtual}
- * instructions and method handles produced by {@code findVirtual},
- * if the class is {@code MethodHandle} and the name string is
- * {@code invokeExact} or {@code invoke}, the resulting
- * method handle is equivalent to one produced by
- * {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
- * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}
- * with the same {@code type} argument.
- *
- * @param refc the class or interface from which the method is accessed
- * @param name the name of the method
- * @param type the type of the method, with the receiver argument omitted
- * @return the desired method handle
- * @throws NoSuchMethodException if the method does not exist
- * @throws IllegalAccessException if access checking fails,
- * or if the method is {@code static}
- * or if the method's variable arity modifier bit
- * is set and {@code asVarargsCollector} fails
- * @exception SecurityException if a security manager is present and it
- * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
- MemberName method = resolveOrFail(refc, name, type, false);
- checkSecurityManager(refc, method); // stack walk magic: do not refactor
- return accessVirtual(refc, method);
- }
- private MethodHandle resolveVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
- MemberName method = resolveOrFail(refc, name, type, false);
- return accessVirtual(refc, method);
- }
- private MethodHandle accessVirtual(Class<?> refc, MemberName method) throws IllegalAccessException {
- checkMethod(refc, method, false);
- MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
- return restrictProtectedReceiver(method, mh);
- }
-
- /**
- * Produces a method handle which creates an object and initializes it, using
- * the constructor of the specified type.
- * The parameter types of the method handle will be those of the constructor,
- * while the return type will be a reference to the constructor's class.
- * The constructor and all its argument types must be accessible to the lookup class.
- * If the constructor's class has not yet been initialized, that is done
- * immediately, before the method handle is returned.
- * <p>
- * Note: The requested type must have a return type of {@code void}.
- * This is consistent with the JVM's treatment of constructor type descriptors.
- * <p>
- * The returned method handle will have
- * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
- * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
- * @param refc the class or interface from which the method is accessed
- * @param type the type of the method, with the receiver argument omitted, and a void return type
- * @return the desired method handle
- * @throws NoSuchMethodException if the constructor does not exist
- * @throws IllegalAccessException if access checking fails
- * or if the method's variable arity modifier bit
- * is set and {@code asVarargsCollector} fails
- * @exception SecurityException if a security manager is present and it
- * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
- String name = "<init>";
- MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
- checkSecurityManager(refc, ctor); // stack walk magic: do not refactor
- return accessConstructor(refc, ctor);
- }
- private MethodHandle accessConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
- assert(ctor.isConstructor());
- checkAccess(refc, ctor);
- MethodHandle rawMH = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
- MethodHandle allocMH = MethodHandleImpl.makeAllocator(rawMH);
- return fixVarargs(allocMH, rawMH);
- }
- private MethodHandle resolveConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
- String name = "<init>";
- MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
- return accessConstructor(refc, ctor);
- }
-
- /** Return a version of MH which matches matchMH w.r.t. isVarargsCollector. */
- private static MethodHandle fixVarargs(MethodHandle mh, MethodHandle matchMH) {
- boolean va1 = mh.isVarargsCollector();
- boolean va2 = matchMH.isVarargsCollector();
- if (va1 == va2) {
- return mh;
- } else if (va2) {
- MethodType type = mh.type();
- int arity = type.parameterCount();
- return mh.asVarargsCollector(type.parameterType(arity-1));
- } else {
- return mh.asFixedArity();
- }
- }
-
- /**
- * Produces an early-bound method handle for a virtual method,
- * as if called from an {@code invokespecial}
- * instruction from {@code caller}.
- * The type of the method handle will be that of the method,
- * with a suitably restricted receiver type (such as {@code caller}) prepended.
- * The method and all its argument types must be accessible
- * to the caller.
- * <p>
- * When called, the handle will treat the first argument as a receiver,
- * but will not dispatch on the receiver's type.
- * (This direct invocation action is identical with that performed by an
- * {@code invokespecial} instruction.)
- * <p>
- * If the explicitly specified caller class is not identical with the
- * lookup class, or if this lookup object does not have private access
- * privileges, the access fails.
- * <p>
- * The returned method handle will have
- * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
- * the method's variable arity modifier bit ({@code 0x0080}) is set.
- * @param refc the class or interface from which the method is accessed
- * @param name the name of the method (which must not be "&lt;init&gt;")
- * @param type the type of the method, with the receiver argument omitted
- * @param specialCaller the proposed calling class to perform the {@code invokespecial}
- * @return the desired method handle
- * @throws NoSuchMethodException if the method does not exist
- * @throws IllegalAccessException if access checking fails
- * or if the method's variable arity modifier bit
- * is set and {@code asVarargsCollector} fails
- * @exception SecurityException if a security manager is present and it
- * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
- Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
- checkSpecialCaller(specialCaller);
- MemberName method = resolveOrFail(refc, name, type, false, false, specialCaller);
- checkSecurityManager(refc, method); // stack walk magic: do not refactor
- return accessSpecial(refc, method, specialCaller);
- }
- private MethodHandle accessSpecial(Class<?> refc, MemberName method,
- Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
- checkMethod(refc, method, false);
- MethodHandle mh = MethodHandleImpl.findMethod(method, false, specialCaller);
- return restrictReceiver(method, mh, specialCaller);
- }
- private MethodHandle resolveSpecial(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
- Class<?> specialCaller = lookupClass();
- checkSpecialCaller(specialCaller);
- MemberName method = resolveOrFail(refc, name, type, false, false, specialCaller);
- return accessSpecial(refc, method, specialCaller);
- }
-
- /**
- * Produces a method handle giving read access to a non-static field.
- * The type of the method handle will have a return type of the field's
- * value type.
- * The method handle's single argument will be the instance containing
- * the field.
- * Access checking is performed immediately on behalf of the lookup class.
- * @param refc the class or interface from which the method is accessed
- * @param name the field's name
- * @param type the field's type
- * @return a method handle which can load values from the field
- * @throws NoSuchFieldException if the field does not exist
- * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
- * @exception SecurityException if a security manager is present and it
- * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
- MemberName field = resolveOrFail(refc, name, type, false);
- checkSecurityManager(refc, field); // stack walk magic: do not refactor
- return makeAccessor(refc, field, false, false, 0);
- }
- private MethodHandle resolveGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
- MemberName field = resolveOrFail(refc, name, type, false);
- return makeAccessor(refc, field, false, false, 0);
- }
-
- /**
- * Produces a method handle giving write access to a non-static field.
- * The type of the method handle will have a void return type.
- * The method handle will take two arguments, the instance containing
- * the field, and the value to be stored.
- * The second argument will be of the field's value type.
- * Access checking is performed immediately on behalf of the lookup class.
- * @param refc the class or interface from which the method is accessed
- * @param name the field's name
- * @param type the field's type
- * @return a method handle which can store values into the field
- * @throws NoSuchFieldException if the field does not exist
- * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
- * @exception SecurityException if a security manager is present and it
- * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
- MemberName field = resolveOrFail(refc, name, type, false);
- checkSecurityManager(refc, field); // stack walk magic: do not refactor
- return makeAccessor(refc, field, false, true, 0);
- }
- private MethodHandle resolveSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
- MemberName field = resolveOrFail(refc, name, type, false);
- return makeAccessor(refc, field, false, true, 0);
- }
-
- /**
- * Produces a method handle giving read access to a static field.
- * The type of the method handle will have a return type of the field's
- * value type.
- * The method handle will take no arguments.
- * Access checking is performed immediately on behalf of the lookup class.
- * @param refc the class or interface from which the method is accessed
- * @param name the field's name
- * @param type the field's type
- * @return a method handle which can load values from the field
- * @throws NoSuchFieldException if the field does not exist
- * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
- * @exception SecurityException if a security manager is present and it
- * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
- MemberName field = resolveOrFail(refc, name, type, true);
- checkSecurityManager(refc, field); // stack walk magic: do not refactor
- return makeAccessor(refc, field, false, false, 1);
- }
- private MethodHandle resolveStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
- MemberName field = resolveOrFail(refc, name, type, true);
- return makeAccessor(refc, field, false, false, 1);
- }
-
- /**
- * Produces a method handle giving write access to a static field.
- * The type of the method handle will have a void return type.
- * The method handle will take a single
- * argument, of the field's value type, the value to be stored.
- * Access checking is performed immediately on behalf of the lookup class.
- * @param refc the class or interface from which the method is accessed
- * @param name the field's name
- * @param type the field's type
- * @return a method handle which can store values into the field
- * @throws NoSuchFieldException if the field does not exist
- * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
- * @exception SecurityException if a security manager is present and it
- * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
- MemberName field = resolveOrFail(refc, name, type, true);
- checkSecurityManager(refc, field); // stack walk magic: do not refactor
- return makeAccessor(refc, field, false, true, 1);
- }
- private MethodHandle resolveStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
- MemberName field = resolveOrFail(refc, name, type, true);
- return makeAccessor(refc, field, false, true, 1);
- }
-
- /**
- * Produces an early-bound method handle for a non-static method.
- * The receiver must have a supertype {@code defc} in which a method
- * of the given name and type is accessible to the lookup class.
- * The method and all its argument types must be accessible to the lookup class.
- * The type of the method handle will be that of the method,
- * without any insertion of an additional receiver parameter.
- * The given receiver will be bound into the method handle,
- * so that every call to the method handle will invoke the
- * requested method on the given receiver.
- * <p>
- * The returned method handle will have
- * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
- * the method's variable arity modifier bit ({@code 0x0080}) is set
- * <em>and</em> the trailing array argument is not the only argument.
- * (If the trailing array argument is the only argument,
- * the given receiver value will be bound to it.)
- * <p>
- * This is equivalent to the following code:
- * <blockquote><pre>
-import static java.lang.invoke.MethodHandles.*;
-import static java.lang.invoke.MethodType.*;
-...
-MethodHandle mh0 = lookup().{@link #findVirtual findVirtual}(defc, name, type);
-MethodHandle mh1 = mh0.{@link MethodHandle#bindTo bindTo}(receiver);
-MethodType mt1 = mh1.type();
-if (mh0.isVarargsCollector())
- mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1));
-return mh1;
- * </pre></blockquote>
- * where {@code defc} is either {@code receiver.getClass()} or a super
- * type of that class, in which the requested method is accessible
- * to the lookup class.
- * (Note that {@code bindTo} does not preserve variable arity.)
- * @param receiver the object from which the method is accessed
- * @param name the name of the method
- * @param type the type of the method, with the receiver argument omitted
- * @return the desired method handle
- * @throws NoSuchMethodException if the method does not exist
- * @throws IllegalAccessException if access checking fails
- * or if the method's variable arity modifier bit
- * is set and {@code asVarargsCollector} fails
- * @exception SecurityException if a security manager is present and it
- * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
- Class<? extends Object> refc = receiver.getClass(); // may get NPE
- MemberName method = resolveOrFail(refc, name, type, false);
- checkSecurityManager(refc, method); // stack walk magic: do not refactor
- checkMethod(refc, method, false);
- MethodHandle dmh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
- MethodHandle bmh = MethodHandleImpl.bindReceiver(dmh, receiver);
- if (bmh == null)
- throw method.makeAccessException("no access", this);
- return fixVarargs(bmh, dmh);
- }
-
- /**
- * Makes a direct method handle to <i>m</i>, if the lookup class has permission.
- * If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
- * If <i>m</i> is virtual, overriding is respected on every call.
- * Unlike the Core Reflection API, exceptions are <em>not</em> wrapped.
- * The type of the method handle will be that of the method,
- * with the receiver type prepended (but only if it is non-static).
- * If the method's {@code accessible} flag is not set,
- * access checking is performed immediately on behalf of the lookup class.
- * If <i>m</i> is not public, do not share the resulting handle with untrusted parties.
- * <p>
- * The returned method handle will have
- * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
- * the method's variable arity modifier bit ({@code 0x0080}) is set.
- * @param m the reflected method
- * @return a method handle which can invoke the reflected method
- * @throws IllegalAccessException if access checking fails
- * or if the method's variable arity modifier bit
- * is set and {@code asVarargsCollector} fails
- * @throws NullPointerException if the argument is null
- */
- public MethodHandle unreflect(Method m) throws IllegalAccessException {
- MemberName method = new MemberName(m);
- assert(method.isMethod());
- if (m.isAccessible())
- return MethodHandleImpl.findMethod(method, true, /*no lookupClass*/ null);
- checkMethod(method.getDeclaringClass(), method, method.isStatic());
- MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
- return restrictProtectedReceiver(method, mh);
- }
-
- /**
- * Produces a method handle for a reflected method.
- * It will bypass checks for overriding methods on the receiver,
- * as if by a {@code invokespecial} instruction from within the {@code specialCaller}.
- * The type of the method handle will be that of the method,
- * with the special caller type prepended (and <em>not</em> the receiver of the method).
- * If the method's {@code accessible} flag is not set,
- * access checking is performed immediately on behalf of the lookup class,
- * as if {@code invokespecial} instruction were being linked.
- * <p>
- * The returned method handle will have
- * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
- * the method's variable arity modifier bit ({@code 0x0080}) is set.
- * @param m the reflected method
- * @param specialCaller the class nominally calling the method
- * @return a method handle which can invoke the reflected method
- * @throws IllegalAccessException if access checking fails
- * or if the method's variable arity modifier bit
- * is set and {@code asVarargsCollector} fails
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
- checkSpecialCaller(specialCaller);
- MemberName method = new MemberName(m);
- assert(method.isMethod());
- // ignore m.isAccessible: this is a new kind of access
- checkMethod(m.getDeclaringClass(), method, false);
- MethodHandle mh = MethodHandleImpl.findMethod(method, false, lookupClassOrNull());
- return restrictReceiver(method, mh, specialCaller);
- }
-
- /**
- * Produces a method handle for a reflected constructor.
- * The type of the method handle will be that of the constructor,
- * with the return type changed to the declaring class.
- * The method handle will perform a {@code newInstance} operation,
- * creating a new instance of the constructor's class on the
- * arguments passed to the method handle.
- * <p>
- * If the constructor's {@code accessible} flag is not set,
- * access checking is performed immediately on behalf of the lookup class.
- * <p>
- * The returned method handle will have
- * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
- * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
- * @param c the reflected constructor
- * @return a method handle which can invoke the reflected constructor
- * @throws IllegalAccessException if access checking fails
- * or if the method's variable arity modifier bit
- * is set and {@code asVarargsCollector} fails
- * @throws NullPointerException if the argument is null
- */
- public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException {
- MemberName ctor = new MemberName(c);
- assert(ctor.isConstructor());
- MethodHandle rawCtor;
- if (c.isAccessible()) {
- rawCtor = MethodHandleImpl.findMethod(ctor, false, /*no lookupClass*/ null);
- } else {
- checkAccess(c.getDeclaringClass(), ctor);
- rawCtor = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
- }
- MethodHandle allocator = MethodHandleImpl.makeAllocator(rawCtor);
- return fixVarargs(allocator, rawCtor);
- }
-
- /**
- * Produces a method handle giving read access to a reflected field.
- * The type of the method handle will have a return type of the field's
- * value type.
- * If the field is static, the method handle will take no arguments.
- * Otherwise, its single argument will be the instance containing
- * the field.
- * If the field's {@code accessible} flag is not set,
- * access checking is performed immediately on behalf of the lookup class.
- * @param f the reflected field
- * @return a method handle which can load values from the reflected field
- * @throws IllegalAccessException if access checking fails
- * @throws NullPointerException if the argument is null
- */
- public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
- return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), false, -1);
- }
-
- /**
- * Produces a method handle giving write access to a reflected field.
- * The type of the method handle will have a void return type.
- * If the field is static, the method handle will take a single
- * argument, of the field's value type, the value to be stored.
- * Otherwise, the two arguments will be the instance containing
- * the field, and the value to be stored.
- * If the field's {@code accessible} flag is not set,
- * access checking is performed immediately on behalf of the lookup class.
- * @param f the reflected field
- * @return a method handle which can store values into the reflected field
- * @throws IllegalAccessException if access checking fails
- * @throws NullPointerException if the argument is null
- */
- public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
- return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), true, -1);
- }
-
- /// Helper methods, all package-private.
-
- MemberName resolveOrFail(Class<?> refc, String name, Class<?> type, boolean isStatic) throws NoSuchFieldException, IllegalAccessException {
- checkSymbolicClass(refc); // do this before attempting to resolve
- name.getClass(); type.getClass(); // NPE
- int mods = (isStatic ? Modifier.STATIC : 0);
- return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull(),
- NoSuchFieldException.class);
- }
-
- MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic) throws NoSuchMethodException, IllegalAccessException {
- checkSymbolicClass(refc); // do this before attempting to resolve
- name.getClass(); type.getClass(); // NPE
- int mods = (isStatic ? Modifier.STATIC : 0);
- return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull(),
- NoSuchMethodException.class);
- }
-
- MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic,
- boolean searchSupers, Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
- checkSymbolicClass(refc); // do this before attempting to resolve
- name.getClass(); type.getClass(); // NPE
- int mods = (isStatic ? Modifier.STATIC : 0);
- return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), searchSupers, specialCaller,
- NoSuchMethodException.class);
- }
-
- void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
- Class<?> caller = lookupClassOrNull();
- if (caller != null && !VerifyAccess.isClassAccessible(refc, caller, allowedModes))
- throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this);
- }
-
- /**
- * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
- * This function performs stack walk magic: do not refactor it.
- */
- void checkSecurityManager(Class<?> refc, MemberName m) {
- if (noSecurityCheck) return;
- SecurityManager smgr = System.getSecurityManager();
- if (smgr == null) return;
- if (allowedModes == TRUSTED) return;
- // Step 1:
- smgr.checkMemberAccess(refc, Member.PUBLIC);
- // Step 2:
- Class<?> callerClass = ((allowedModes & PRIVATE) != 0
- ? lookupClass // for strong access modes, no extra check
- // next line does stack walk magic; do not refactor:
- : getCallerClassAtEntryPoint(true));
- if (!VerifyAccess.classLoaderIsAncestor(lookupClass, refc) ||
- (callerClass != lookupClass &&
- !VerifyAccess.classLoaderIsAncestor(callerClass, refc)))
- smgr.checkPackageAccess(VerifyAccess.getPackageName(refc));
- // Step 3:
- if (m.isPublic()) return;
- Class<?> defc = m.getDeclaringClass();
- smgr.checkMemberAccess(defc, Member.DECLARED); // STACK WALK HERE
- // Step 4:
- if (defc != refc)
- smgr.checkPackageAccess(VerifyAccess.getPackageName(defc));
-
- // Comment from SM.checkMemberAccess, where which=DECLARED:
- /*
- * stack depth of 4 should be the caller of one of the
- * methods in java.lang.Class that invoke checkMember
- * access. The stack should look like:
- *
- * someCaller [3]
- * java.lang.Class.someReflectionAPI [2]
- * java.lang.Class.checkMemberAccess [1]
- * SecurityManager.checkMemberAccess [0]
- *
- */
- // For us it is this stack:
- // someCaller [3]
- // Lookup.findSomeMember [2]
- // Lookup.checkSecurityManager [1]
- // SecurityManager.checkMemberAccess [0]
- }
-
- void checkMethod(Class<?> refc, MemberName m, boolean wantStatic) throws IllegalAccessException {
- String message;
- if (m.isConstructor())
- message = "expected a method, not a constructor";
- else if (!m.isMethod())
- message = "expected a method";
- else if (wantStatic != m.isStatic())
- message = wantStatic ? "expected a static method" : "expected a non-static method";
- else
- { checkAccess(refc, m); return; }
- throw m.makeAccessException(message, this);
- }
-
- void checkAccess(Class<?> refc, MemberName m) throws IllegalAccessException {
- int allowedModes = this.allowedModes;
- if (allowedModes == TRUSTED) return;
- int mods = m.getModifiers();
- if (Modifier.isPublic(mods) && Modifier.isPublic(refc.getModifiers()) && allowedModes != 0)
- return; // common case
- int requestedModes = fixmods(mods); // adjust 0 => PACKAGE
- if ((requestedModes & allowedModes) != 0
- && VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
- mods, lookupClass(), allowedModes))
- return;
- if (((requestedModes & ~allowedModes) & PROTECTED) != 0
- && (allowedModes & PACKAGE) != 0
- && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
- // Protected members can also be checked as if they were package-private.
- return;
- throw m.makeAccessException(accessFailedMessage(refc, m), this);
- }
-
- String accessFailedMessage(Class<?> refc, MemberName m) {
- Class<?> defc = m.getDeclaringClass();
- int mods = m.getModifiers();
- // check the class first:
- boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
- (defc == refc ||
- Modifier.isPublic(refc.getModifiers())));
- if (!classOK && (allowedModes & PACKAGE) != 0) {
- classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), ALL_MODES) &&
- (defc == refc ||
- VerifyAccess.isClassAccessible(refc, lookupClass(), ALL_MODES)));
- }
- if (!classOK)
- return "class is not public";
- if (Modifier.isPublic(mods))
- return "access to public member failed"; // (how?)
- if (Modifier.isPrivate(mods))
- return "member is private";
- if (Modifier.isProtected(mods))
- return "member is protected";
- return "member is private to package";
- }
-
- private static final boolean ALLOW_NESTMATE_ACCESS = false;
-
- void checkSpecialCaller(Class<?> specialCaller) throws IllegalAccessException {
- if (allowedModes == TRUSTED) return;
- if ((allowedModes & PRIVATE) == 0
- || (specialCaller != lookupClass()
- && !(ALLOW_NESTMATE_ACCESS &&
- VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
- throw new MemberName(specialCaller).
- makeAccessException("no private access for invokespecial", this);
- }
-
- MethodHandle restrictProtectedReceiver(MemberName method, MethodHandle mh) throws IllegalAccessException {
- // The accessing class only has the right to use a protected member
- // on itself or a subclass. Enforce that restriction, from JVMS 5.4.4, etc.
- if (!method.isProtected() || method.isStatic()
- || allowedModes == TRUSTED
- || method.getDeclaringClass() == lookupClass()
- || VerifyAccess.isSamePackage(method.getDeclaringClass(), lookupClass())
- || (ALLOW_NESTMATE_ACCESS &&
- VerifyAccess.isSamePackageMember(method.getDeclaringClass(), lookupClass())))
- return mh;
- else
- return restrictReceiver(method, mh, lookupClass());
- }
- MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class<?> caller) throws IllegalAccessException {
- assert(!method.isStatic());
- Class<?> defc = method.getDeclaringClass(); // receiver type of mh is too wide
- if (defc.isInterface() || !defc.isAssignableFrom(caller)) {
- throw method.makeAccessException("caller class must be a subclass below the method", caller);
- }
- MethodType rawType = mh.type();
- if (rawType.parameterType(0) == caller) return mh;
- MethodType narrowType = rawType.changeParameterType(0, caller);
- MethodHandle narrowMH = MethodHandleImpl.convertArguments(mh, narrowType, rawType, 0);
- return fixVarargs(narrowMH, mh);
- }
-
- MethodHandle makeAccessor(Class<?> refc, MemberName field,
- boolean trusted, boolean isSetter,
- int checkStatic) throws IllegalAccessException {
- assert(field.isField());
- if (checkStatic >= 0 && (checkStatic != 0) != field.isStatic())
- throw field.makeAccessException((checkStatic != 0)
- ? "expected a static field"
- : "expected a non-static field", this);
- if (trusted)
- return MethodHandleImpl.accessField(field, isSetter, /*no lookupClass*/ null);
- checkAccess(refc, field);
- MethodHandle mh = MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
- return restrictProtectedReceiver(field, mh);
- }
-
- /** Hook called from the JVM (via MethodHandleNatives) to link MH constants:
- */
- /*non-public*/
- MethodHandle linkMethodHandleConstant(int refKind, Class<?> defc, String name, Object type) throws ReflectiveOperationException {
- switch (refKind) {
- case REF_getField: return resolveGetter( defc, name, (Class<?>) type );
- case REF_getStatic: return resolveStaticGetter( defc, name, (Class<?>) type );
- case REF_putField: return resolveSetter( defc, name, (Class<?>) type );
- case REF_putStatic: return resolveStaticSetter( defc, name, (Class<?>) type );
- case REF_invokeVirtual: return resolveVirtual( defc, name, (MethodType) type );
- case REF_invokeStatic: return resolveStatic( defc, name, (MethodType) type );
- case REF_invokeSpecial: return resolveSpecial( defc, name, (MethodType) type );
- case REF_newInvokeSpecial: return resolveConstructor( defc, (MethodType) type );
- case REF_invokeInterface: return resolveVirtual( defc, name, (MethodType) type );
- }
- // oops
- throw new ReflectiveOperationException("bad MethodHandle constant #"+refKind+" "+name+" : "+type);
- }
- }
-
- /**
- * Produces a method handle giving read access to elements of an array.
- * The type of the method handle will have a return type of the array's
- * element type. Its first argument will be the array type,
- * and the second will be {@code int}.
- * @param arrayClass an array type
- * @return a method handle which can load values from the given array type
- * @throws NullPointerException if the argument is null
- * @throws IllegalArgumentException if arrayClass is not an array type
- */
- public static
- MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException {
- return MethodHandleImpl.accessArrayElement(arrayClass, false);
- }
-
- /**
- * Produces a method handle giving write access to elements of an array.
- * The type of the method handle will have a void return type.
- * Its last argument will be the array's element type.
- * The first and second arguments will be the array type and int.
- * @return a method handle which can store values into the array type
- * @throws NullPointerException if the argument is null
- * @throws IllegalArgumentException if arrayClass is not an array type
- */
- public static
- MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException {
- return MethodHandleImpl.accessArrayElement(arrayClass, true);
- }
-
- /// method handle invocation (reflective style)
-
- /**
- * Produces a method handle which will invoke any method handle of the
- * given {@code type}, with a given number of trailing arguments replaced by
- * a single trailing {@code Object[]} array.
- * The resulting invoker will be a method handle with the following
- * arguments:
- * <ul>
- * <li>a single {@code MethodHandle} target
- * <li>zero or more leading values (counted by {@code leadingArgCount})
- * <li>an {@code Object[]} array containing trailing arguments
- * </ul>
- * <p>
- * The invoker will invoke its target like a call to {@link MethodHandle#invoke invoke} with
- * the indicated {@code type}.
- * That is, if the target is exactly of the given {@code type}, it will behave
- * like {@code invokeExact}; otherwise it behave as if {@link MethodHandle#asType asType}
- * is used to convert the target to the required {@code type}.
- * <p>
- * The type of the returned invoker will not be the given {@code type}, but rather
- * will have all parameters except the first {@code leadingArgCount}
- * replaced by a single array of type {@code Object[]}, which will be
- * the final parameter.
- * <p>
- * Before invoking its target, the invoker will spread the final array, apply
- * reference casts as necessary, and unbox and widen primitive arguments.
- * <p>
- * This method is equivalent to the following code (though it may be more efficient):
- * <p><blockquote><pre>
-MethodHandle invoker = MethodHandles.invoker(type);
-int spreadArgCount = type.parameterCount() - leadingArgCount;
-invoker = invoker.asSpreader(Object[].class, spreadArgCount);
-return invoker;
- * </pre></blockquote>
- * <p>
- * This method throws no reflective or security exceptions.
- * @param type the desired target type
- * @param leadingArgCount number of fixed arguments, to be passed unchanged to the target
- * @return a method handle suitable for invoking any method handle of the given type
- * @throws NullPointerException if {@code type} is null
- * @throws IllegalArgumentException if {@code leadingArgCount} is not in
- * the range from 0 to {@code type.parameterCount()} inclusive
- */
- static public
- MethodHandle spreadInvoker(MethodType type, int leadingArgCount) {
- if (leadingArgCount < 0 || leadingArgCount > type.parameterCount())
- throw new IllegalArgumentException("bad argument count "+leadingArgCount);
- return type.invokers().spreadInvoker(leadingArgCount);
- }
-
- /**
- * Produces a special <em>invoker method handle</em> which can be used to
- * invoke any method handle of the given type, as if by {@link MethodHandle#invokeExact invokeExact}.
- * The resulting invoker will have a type which is
- * exactly equal to the desired type, except that it will accept
- * an additional leading argument of type {@code MethodHandle}.
- * <p>
- * This method is equivalent to the following code (though it may be more efficient):
- * <p><blockquote><pre>
-publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
- * </pre></blockquote>
- *
- * <p style="font-size:smaller;">
- * <em>Discussion:</em>
- * Invoker method handles can be useful when working with variable method handles
- * of unknown types.
- * For example, to emulate an {@code invokeExact} call to a variable method
- * handle {@code M}, extract its type {@code T},
- * look up the invoker method {@code X} for {@code T},
- * and call the invoker method, as {@code X.invoke(T, A...)}.
- * (It would not work to call {@code X.invokeExact}, since the type {@code T}
- * is unknown.)
- * If spreading, collecting, or other argument transformations are required,
- * they can be applied once to the invoker {@code X} and reused on many {@code M}
- * method handle values, as long as they are compatible with the type of {@code X}.
- * <p>
- * <em>(Note: The invoker method is not available via the Core Reflection API.
- * An attempt to call {@linkplain java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
- * on the declared {@code invokeExact} or {@code invoke} method will raise an
- * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)</em>
- * <p>
- * This method throws no reflective or security exceptions.
- * @param type the desired target type
- * @return a method handle suitable for invoking any method handle of the given type
- */
- static public
- MethodHandle exactInvoker(MethodType type) {
- return type.invokers().exactInvoker();
- }
-
- /**
- * Produces a special <em>invoker method handle</em> which can be used to
- * invoke any method handle compatible with the given type, as if by {@link MethodHandle#invoke invoke}.
- * The resulting invoker will have a type which is
- * exactly equal to the desired type, except that it will accept
- * an additional leading argument of type {@code MethodHandle}.
- * <p>
- * Before invoking its target, if the target differs from the expected type,
- * the invoker will apply reference casts as
- * necessary and box, unbox, or widen primitive values, as if by {@link MethodHandle#asType asType}.
- * Similarly, the return value will be converted as necessary.
- * If the target is a {@linkplain MethodHandle#asVarargsCollector variable arity method handle},
- * the required arity conversion will be made, again as if by {@link MethodHandle#asType asType}.
- * <p>
- * A {@linkplain MethodType#genericMethodType general method type},
- * mentions only {@code Object} arguments and return values.
- * An invoker for such a type is capable of calling any method handle
- * of the same arity as the general type.
- * <p>
- * This method is equivalent to the following code (though it may be more efficient):
- * <p><blockquote><pre>
-publicLookup().findVirtual(MethodHandle.class, "invoke", type)
- * </pre></blockquote>
- * <p>
- * This method throws no reflective or security exceptions.
- * @param type the desired target type
- * @return a method handle suitable for invoking any method handle convertible to the given type
- */
- static public
- MethodHandle invoker(MethodType type) {
- return type.invokers().generalInvoker();
- }
-
- /**
- * Perform value checking, exactly as if for an adapted method handle.
- * It is assumed that the given value is either null, of type T0,
- * or (if T0 is primitive) of the wrapper class corresponding to T0.
- * The following checks and conversions are made:
- * <ul>
- * <li>If T0 and T1 are references, then a cast to T1 is applied.
- * (The types do not need to be related in any particular way.)
- * <li>If T0 and T1 are primitives, then a widening or narrowing
- * conversion is applied, if one exists.
- * <li>If T0 is a primitive and T1 a reference, and
- * T0 has a wrapper class TW, a boxing conversion to TW is applied,
- * possibly followed by a reference conversion.
- * T1 must be TW or a supertype.
- * <li>If T0 is a reference and T1 a primitive, and
- * T1 has a wrapper class TW, an unboxing conversion is applied,
- * possibly preceded by a reference conversion.
- * T0 must be TW or a supertype.
- * <li>If T1 is void, the return value is discarded
- * <li>If T0 is void and T1 a reference, a null value is introduced.
- * <li>If T0 is void and T1 a primitive, a zero value is introduced.
- * </ul>
- * If the value is discarded, null will be returned.
- * @param valueType
- * @param value
- * @return the value, converted if necessary
- * @throws java.lang.ClassCastException if a cast fails
- */
- // FIXME: This is used in just one place. Refactor away.
- static
- <T0, T1> T1 checkValue(Class<T0> t0, Class<T1> t1, Object value)
- throws ClassCastException
- {
- if (t0 == t1) {
- // no conversion needed; just reassert the same type
- if (t0.isPrimitive())
- return Wrapper.asPrimitiveType(t1).cast(value);
- else
- return Wrapper.OBJECT.convert(value, t1);
- }
- boolean prim0 = t0.isPrimitive(), prim1 = t1.isPrimitive();
- if (!prim0) {
- // check contract with caller
- Wrapper.OBJECT.convert(value, t0);
- if (!prim1) {
- return Wrapper.OBJECT.convert(value, t1);
- }
- // convert reference to primitive by unboxing
- Wrapper w1 = Wrapper.forPrimitiveType(t1);
- return w1.convert(value, t1);
- }
- // check contract with caller:
- Wrapper.asWrapperType(t0).cast(value);
- Wrapper w1 = Wrapper.forPrimitiveType(t1);
- return w1.convert(value, t1);
- }
-
- // FIXME: Delete this. It is used only for insertArguments & bindTo.
- // Replace by a more standard check.
- static
- Object checkValue(Class<?> T1, Object value)
- throws ClassCastException
- {
- Class<?> T0;
- if (value == null)
- T0 = Object.class;
- else
- T0 = value.getClass();
- return checkValue(T0, T1, value);
- }
-
- /// method handle modification (creation from other method handles)
-
- /**
- * Produces a method handle which adapts the type of the
- * given method handle to a new type by pairwise argument and return type conversion.
- * The original type and new type must have the same number of arguments.
- * The resulting method handle is guaranteed to report a type
- * which is equal to the desired new type.
- * <p>
- * If the original type and new type are equal, returns target.
- * <p>
- * The same conversions are allowed as for {@link MethodHandle#asType MethodHandle.asType},
- * and some additional conversions are also applied if those conversions fail.
- * Given types <em>T0</em>, <em>T1</em>, one of the following conversions is applied
- * if possible, before or instead of any conversions done by {@code asType}:
- * <ul>
- * <li>If <em>T0</em> and <em>T1</em> are references, and <em>T1</em> is an interface type,
- * then the value of type <em>T0</em> is passed as a <em>T1</em> without a cast.
- * (This treatment of interfaces follows the usage of the bytecode verifier.)
- * <li>If <em>T0</em> is boolean and <em>T1</em> is another primitive,
- * the boolean is converted to a byte value, 1 for true, 0 for false.
- * (This treatment follows the usage of the bytecode verifier.)
- * <li>If <em>T1</em> is boolean and <em>T0</em> is another primitive,
- * <em>T0</em> is converted to byte via Java casting conversion (JLS 5.5),
- * and the low order bit of the result is tested, as if by {@code (x & 1) != 0}.
- * <li>If <em>T0</em> and <em>T1</em> are primitives other than boolean,
- * then a Java casting conversion (JLS 5.5) is applied.
- * (Specifically, <em>T0</em> will convert to <em>T1</em> by
- * widening and/or narrowing.)
- * <li>If <em>T0</em> is a reference and <em>T1</em> a primitive, an unboxing
- * conversion will be applied at runtime, possibly followed
- * by a Java casting conversion (JLS 5.5) on the primitive value,
- * possibly followed by a conversion from byte to boolean by testing
- * the low-order bit.
- * <li>If <em>T0</em> is a reference and <em>T1</em> a primitive,
- * and if the reference is null at runtime, a zero value is introduced.
- * </ul>
- * @param target the method handle to invoke after arguments are retyped
- * @param newType the expected type of the new method handle
- * @return a method handle which delegates to the target after performing
- * any necessary argument conversions, and arranges for any
- * necessary return value conversions
- * @throws NullPointerException if either argument is null
- * @throws WrongMethodTypeException if the conversion cannot be made
- * @see MethodHandle#asType
- */
- public static
- MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) {
- return MethodHandleImpl.convertArguments(target, newType, 2);
- }
-
- /**
- * Produces a method handle which adapts the calling sequence of the
- * given method handle to a new type, by reordering the arguments.
- * The resulting method handle is guaranteed to report a type
- * which is equal to the desired new type.
- * <p>
- * The given array controls the reordering.
- * Call {@code #I} the number of incoming parameters (the value
- * {@code newType.parameterCount()}, and call {@code #O} the number
- * of outgoing parameters (the value {@code target.type().parameterCount()}).
- * Then the length of the reordering array must be {@code #O},
- * and each element must be a non-negative number less than {@code #I}.
- * For every {@code N} less than {@code #O}, the {@code N}-th
- * outgoing argument will be taken from the {@code I}-th incoming
- * argument, where {@code I} is {@code reorder[N]}.
- * <p>
- * No argument or return value conversions are applied.
- * The type of each incoming argument, as determined by {@code newType},
- * must be identical to the type of the corresponding outgoing parameter
- * or parameters in the target method handle.
- * The return type of {@code newType} must be identical to the return
- * type of the original target.
- * <p>
- * The reordering array need not specify an actual permutation.
- * An incoming argument will be duplicated if its index appears
- * more than once in the array, and an incoming argument will be dropped
- * if its index does not appear in the array.
- * As in the case of {@link #dropArguments(MethodHandle,int,List) dropArguments},
- * incoming arguments which are not mentioned in the reordering array
- * are may be any type, as determined only by {@code newType}.
- * <blockquote><pre>
-import static java.lang.invoke.MethodHandles.*;
-import static java.lang.invoke.MethodType.*;
-...
-MethodType intfn1 = methodType(int.class, int.class);
-MethodType intfn2 = methodType(int.class, int.class, int.class);
-MethodHandle sub = ... {int x, int y => x-y} ...;
-assert(sub.type().equals(intfn2));
-MethodHandle sub1 = permuteArguments(sub, intfn2, 0, 1);
-MethodHandle rsub = permuteArguments(sub, intfn2, 1, 0);
-assert((int)rsub.invokeExact(1, 100) == 99);
-MethodHandle add = ... {int x, int y => x+y} ...;
-assert(add.type().equals(intfn2));
-MethodHandle twice = permuteArguments(add, intfn1, 0, 0);
-assert(twice.type().equals(intfn1));
-assert((int)twice.invokeExact(21) == 42);
- * </pre></blockquote>
- * @param target the method handle to invoke after arguments are reordered
- * @param newType the expected type of the new method handle
- * @param reorder an index array which controls the reordering
- * @return a method handle which delegates to the target after it
- * drops unused arguments and moves and/or duplicates the other arguments
- * @throws NullPointerException if any argument is null
- * @throws IllegalArgumentException if the index array length is not equal to
- * the arity of the target, or if any index array element
- * not a valid index for a parameter of {@code newType},
- * or if two corresponding parameter types in
- * {@code target.type()} and {@code newType} are not identical,
- */
- public static
- MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
- MethodType oldType = target.type();
- checkReorder(reorder, newType, oldType);
- return MethodHandleImpl.permuteArguments(target,
- newType, oldType,
- reorder);
- }
-
- private static void checkReorder(int[] reorder, MethodType newType, MethodType oldType) {
- if (newType.returnType() != oldType.returnType())
- throw newIllegalArgumentException("return types do not match",
- oldType, newType);
- if (reorder.length == oldType.parameterCount()) {
- int limit = newType.parameterCount();
- boolean bad = false;
- for (int j = 0; j < reorder.length; j++) {
- int i = reorder[j];
- if (i < 0 || i >= limit) {
- bad = true; break;
- }
- Class<?> src = newType.parameterType(i);
- Class<?> dst = oldType.parameterType(j);
- if (src != dst)
- throw newIllegalArgumentException("parameter types do not match after reorder",
- oldType, newType);
- }
- if (!bad) return;
- }
- throw newIllegalArgumentException("bad reorder array: "+Arrays.toString(reorder));
- }
-
- /**
- * Produces a method handle of the requested return type which returns the given
- * constant value every time it is invoked.
- * <p>
- * Before the method handle is returned, the passed-in value is converted to the requested type.
- * If the requested type is primitive, widening primitive conversions are attempted,
- * else reference conversions are attempted.
- * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)}.
- * @param type the return type of the desired method handle
- * @param value the value to return
- * @return a method handle of the given return type and no arguments, which always returns the given value
- * @throws NullPointerException if the {@code type} argument is null
- * @throws ClassCastException if the value cannot be converted to the required return type
- * @throws IllegalArgumentException if the given type is {@code void.class}
- */
- public static
- MethodHandle constant(Class<?> type, Object value) {
- if (type.isPrimitive()) {
- if (type == void.class)
- throw newIllegalArgumentException("void type");
- Wrapper w = Wrapper.forPrimitiveType(type);
- return insertArguments(identity(type), 0, w.convert(value, type));
- } else {
- return identity(type).bindTo(type.cast(value));
- }
- }
-
- /**
- * Produces a method handle which returns its sole argument when invoked.
- * @param type the type of the sole parameter and return value of the desired method handle
- * @return a unary method handle which accepts and returns the given type
- * @throws NullPointerException if the argument is null
- * @throws IllegalArgumentException if the given type is {@code void.class}
- */
- public static
- MethodHandle identity(Class<?> type) {
- if (type == void.class)
- throw newIllegalArgumentException("void type");
- else if (type == Object.class)
- return ValueConversions.identity();
- else if (type.isPrimitive())
- return ValueConversions.identity(Wrapper.forPrimitiveType(type));
- else
- return AdapterMethodHandle.makeRetypeRaw(
- MethodType.methodType(type, type), ValueConversions.identity());
- }
-
- /**
- * Provides a target method handle with one or more <em>bound arguments</em>
- * in advance of the method handle's invocation.
- * The formal parameters to the target corresponding to the bound
- * arguments are called <em>bound parameters</em>.
- * Returns a new method handle which saves away the bound arguments.
- * When it is invoked, it receives arguments for any non-bound parameters,
- * binds the saved arguments to their corresponding parameters,
- * and calls the original target.
- * <p>
- * The type of the new method handle will drop the types for the bound
- * parameters from the original target type, since the new method handle
- * will no longer require those arguments to be supplied by its callers.
- * <p>
- * Each given argument object must match the corresponding bound parameter type.
- * If a bound parameter type is a primitive, the argument object
- * must be a wrapper, and will be unboxed to produce the primitive value.
- * <p>
- * The {@code pos} argument selects which parameters are to be bound.
- * It may range between zero and <i>N-L</i> (inclusively),
- * where <i>N</i> is the arity of the target method handle
- * and <i>L</i> is the length of the values array.
- * @param target the method handle to invoke after the argument is inserted
- * @param pos where to insert the argument (zero for the first)
- * @param values the series of arguments to insert
- * @return a method handle which inserts an additional argument,
- * before calling the original method handle
- * @throws NullPointerException if the target or the {@code values} array is null
- * @see MethodHandle#bindTo
- */
- public static
- MethodHandle insertArguments(MethodHandle target, int pos, Object... values) {
- int insCount = values.length;
- MethodType oldType = target.type();
- int outargs = oldType.parameterCount();
- int inargs = outargs - insCount;
- if (inargs < 0)
- throw newIllegalArgumentException("too many values to insert");
- if (pos < 0 || pos > inargs)
- throw newIllegalArgumentException("no argument type to append");
- MethodHandle result = target;
- for (int i = 0; i < insCount; i++) {
- Object value = values[i];
- Class<?> valueType = oldType.parameterType(pos+i);
- value = checkValue(valueType, value);
- if (pos == 0 && !valueType.isPrimitive()) {
- // At least for now, make bound method handles a special case.
- MethodHandle bmh = MethodHandleImpl.bindReceiver(result, value);
- if (bmh != null) {
- result = bmh;
- continue;
- }
- // else fall through to general adapter machinery
- }
- result = MethodHandleImpl.bindArgument(result, pos, value);
- }
- return result;
- }
-
- /**
- * Produces a method handle which will discard some dummy arguments
- * before calling some other specified <i>target</i> method handle.
- * The type of the new method handle will be the same as the target's type,
- * except it will also include the dummy argument types,
- * at some given position.
- * <p>
- * The {@code pos} argument may range between zero and <i>N</i>,
- * where <i>N</i> is the arity of the target.
- * If {@code pos} is zero, the dummy arguments will precede
- * the target's real arguments; if {@code pos} is <i>N</i>
- * they will come after.
- * <p>
- * <b>Example:</b>
- * <p><blockquote><pre>
-import static java.lang.invoke.MethodHandles.*;
-import static java.lang.invoke.MethodType.*;
-...
-MethodHandle cat = lookup().findVirtual(String.class,
- "concat", methodType(String.class, String.class));
-assertEquals("xy", (String) cat.invokeExact("x", "y"));
-MethodType bigType = cat.type().insertParameterTypes(0, int.class, String.class);
-MethodHandle d0 = dropArguments(cat, 0, bigType.parameterList().subList(0,2));
-assertEquals(bigType, d0.type());
-assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
- * </pre></blockquote>
- * <p>
- * This method is also equivalent to the following code:
- * <p><blockquote><pre>
- * {@link #dropArguments(MethodHandle,int,Class...) dropArguments}(target, pos, valueTypes.toArray(new Class[0]))
- * </pre></blockquote>
- * @param target the method handle to invoke after the arguments are dropped
- * @param valueTypes the type(s) of the argument(s) to drop
- * @param pos position of first argument to drop (zero for the leftmost)
- * @return a method handle which drops arguments of the given types,
- * before calling the original method handle
- * @throws NullPointerException if the target is null,
- * or if the {@code valueTypes} list or any of its elements is null
- * @throws IllegalArgumentException if any element of {@code valueTypes} is {@code void.class},
- * or if {@code pos} is negative or greater than the arity of the target,
- * or if the new method handle's type would have too many parameters
- */
- public static
- MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
- MethodType oldType = target.type(); // get NPE
- if (valueTypes.size() == 0) return target;
- int outargs = oldType.parameterCount();
- int inargs = outargs + valueTypes.size();
- if (pos < 0 || pos >= inargs)
- throw newIllegalArgumentException("no argument type to remove");
- ArrayList<Class<?>> ptypes =
- new ArrayList<Class<?>>(oldType.parameterList());
- ptypes.addAll(pos, valueTypes);
- MethodType newType = MethodType.methodType(oldType.returnType(), ptypes);
- return MethodHandleImpl.dropArguments(target, newType, pos);
- }
-
- /**
- * Produces a method handle which will discard some dummy arguments
- * before calling some other specified <i>target</i> method handle.
- * The type of the new method handle will be the same as the target's type,
- * except it will also include the dummy argument types,
- * at some given position.
- * <p>
- * The {@code pos} argument may range between zero and <i>N</i>,
- * where <i>N</i> is the arity of the target.
- * If {@code pos} is zero, the dummy arguments will precede
- * the target's real arguments; if {@code pos} is <i>N</i>
- * they will come after.
- * <p>
- * <b>Example:</b>
- * <p><blockquote><pre>
-import static java.lang.invoke.MethodHandles.*;
-import static java.lang.invoke.MethodType.*;
-...
-MethodHandle cat = lookup().findVirtual(String.class,
- "concat", methodType(String.class, String.class));
-assertEquals("xy", (String) cat.invokeExact("x", "y"));
-MethodHandle d0 = dropArguments(cat, 0, String.class);
-assertEquals("yz", (String) d0.invokeExact("x", "y", "z"));
-MethodHandle d1 = dropArguments(cat, 1, String.class);
-assertEquals("xz", (String) d1.invokeExact("x", "y", "z"));
-MethodHandle d2 = dropArguments(cat, 2, String.class);
-assertEquals("xy", (String) d2.invokeExact("x", "y", "z"));
-MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
-assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
- * </pre></blockquote>
- * <p>
- * This method is also equivalent to the following code:
- * <p><blockquote><pre>
- * {@link #dropArguments(MethodHandle,int,List) dropArguments}(target, pos, Arrays.asList(valueTypes))
- * </pre></blockquote>
- * @param target the method handle to invoke after the arguments are dropped
- * @param valueTypes the type(s) of the argument(s) to drop
- * @param pos position of first argument to drop (zero for the leftmost)
- * @return a method handle which drops arguments of the given types,
- * before calling the original method handle
- * @throws NullPointerException if the target is null,
- * or if the {@code valueTypes} array or any of its elements is null
- * @throws IllegalArgumentException if any element of {@code valueTypes} is {@code void.class},
- * or if {@code pos} is negative or greater than the arity of the target,
- * or if the new method handle's type would have too many parameters
- */
- public static
- MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
- return dropArguments(target, pos, Arrays.asList(valueTypes));
- }
-
- /**
- * Adapts a target method handle by pre-processing
- * one or more of its arguments, each with its own unary filter function,
- * and then calling the target with each pre-processed argument
- * replaced by the result of its corresponding filter function.
- * <p>
- * The pre-processing is performed by one or more method handles,
- * specified in the elements of the {@code filters} array.
- * The first element of the filter array corresponds to the {@code pos}
- * argument of the target, and so on in sequence.
- * <p>
- * Null arguments in the array are treated as identity functions,
- * and the corresponding arguments left unchanged.
- * (If there are no non-null elements in the array, the original target is returned.)
- * Each filter is applied to the corresponding argument of the adapter.
- * <p>
- * If a filter {@code F} applies to the {@code N}th argument of
- * the target, then {@code F} must be a method handle which
- * takes exactly one argument. The type of {@code F}'s sole argument
- * replaces the corresponding argument type of the target
- * in the resulting adapted method handle.
- * The return type of {@code F} must be identical to the corresponding
- * parameter type of the target.
- * <p>
- * It is an error if there are elements of {@code filters}
- * (null or not)
- * which do not correspond to argument positions in the target.
- * <b>Example:</b>
- * <p><blockquote><pre>
-import static java.lang.invoke.MethodHandles.*;
-import static java.lang.invoke.MethodType.*;
-...
-MethodHandle cat = lookup().findVirtual(String.class,
- "concat", methodType(String.class, String.class));
-MethodHandle upcase = lookup().findVirtual(String.class,
- "toUpperCase", methodType(String.class));
-assertEquals("xy", (String) cat.invokeExact("x", "y"));
-MethodHandle f0 = filterArguments(cat, 0, upcase);
-assertEquals("Xy", (String) f0.invokeExact("x", "y")); // Xy
-MethodHandle f1 = filterArguments(cat, 1, upcase);
-assertEquals("xY", (String) f1.invokeExact("x", "y")); // xY
-MethodHandle f2 = filterArguments(cat, 0, upcase, upcase);
-assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
- * </pre></blockquote>
- * <p> Here is pseudocode for the resulting adapter:
- * <blockquote><pre>
- * V target(P... p, A[i]... a[i], B... b);
- * A[i] filter[i](V[i]);
- * T adapter(P... p, V[i]... v[i], B... b) {
- * return target(p..., f[i](v[i])..., b...);
- * }
- * </pre></blockquote>
- *
- * @param target the method handle to invoke after arguments are filtered
- * @param pos the position of the first argument to filter
- * @param filters method handles to call initially on filtered arguments
- * @return method handle which incorporates the specified argument filtering logic
- * @throws NullPointerException if the target is null
- * or if the {@code filters} array is null
- * @throws IllegalArgumentException if a non-null element of {@code filters}
- * does not match a corresponding argument type of target as described above,
- * or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()}
- */
- public static
- MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
- MethodType targetType = target.type();
- MethodHandle adapter = target;
- MethodType adapterType = null;
- assert((adapterType = targetType) != null);
- int maxPos = targetType.parameterCount();
- if (pos + filters.length > maxPos)
- throw newIllegalArgumentException("too many filters");
- int curPos = pos-1; // pre-incremented
- for (MethodHandle filter : filters) {
- curPos += 1;
- if (filter == null) continue; // ignore null elements of filters
- adapter = filterArgument(adapter, curPos, filter);
- assert((adapterType = adapterType.changeParameterType(curPos, filter.type().parameterType(0))) != null);
- }
- assert(adapterType.equals(adapter.type()));
- return adapter;
- }
-
- /*non-public*/ static
- MethodHandle filterArgument(MethodHandle target, int pos, MethodHandle filter) {
- MethodType targetType = target.type();
- MethodType filterType = filter.type();
- if (filterType.parameterCount() != 1
- || filterType.returnType() != targetType.parameterType(pos))
- throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
- return MethodHandleImpl.filterArgument(target, pos, filter);
- }
-
- /**
- * Adapts a target method handle by post-processing
- * its return value (if any) with a filter (another method handle).
- * The result of the filter is returned from the adapter.
- * <p>
- * If the target returns a value, the filter must accept that value as
- * its only argument.
- * If the target returns void, the filter must accept no arguments.
- * <p>
- * The return type of the filter
- * replaces the return type of the target
- * in the resulting adapted method handle.
- * The argument type of the filter (if any) must be identical to the
- * return type of the target.
- * <b>Example:</b>
- * <p><blockquote><pre>
-import static java.lang.invoke.MethodHandles.*;
-import static java.lang.invoke.MethodType.*;
-...
-MethodHandle cat = lookup().findVirtual(String.class,
- "concat", methodType(String.class, String.class));
-MethodHandle length = lookup().findVirtual(String.class,
- "length", methodType(int.class));
-System.out.println((String) cat.invokeExact("x", "y")); // xy
-MethodHandle f0 = filterReturnValue(cat, length);
-System.out.println((int) f0.invokeExact("x", "y")); // 2
- * </pre></blockquote>
- * <p> Here is pseudocode for the resulting adapter:
- * <blockquote><pre>
- * V target(A...);
- * T filter(V);
- * T adapter(A... a) {
- * V v = target(a...);
- * return filter(v);
- * }
- * // and if the target has a void return:
- * void target2(A...);
- * T filter2();
- * T adapter2(A... a) {
- * target2(a...);
- * return filter2();
- * }
- * // and if the filter has a void return:
- * V target3(A...);
- * void filter3(V);
- * void adapter3(A... a) {
- * V v = target3(a...);
- * filter3(v);
- * }
- * </pre></blockquote>
- * @param target the method handle to invoke before filtering the return value
- * @param filter method handle to call on the return value
- * @return method handle which incorporates the specified return value filtering logic
- * @throws NullPointerException if either argument is null
- * @throws IllegalArgumentException if the argument list of {@code filter}
- * does not match the return type of target as described above
- */
- public static
- MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter) {
- MethodType targetType = target.type();
- MethodType filterType = filter.type();
- Class<?> rtype = targetType.returnType();
- int filterValues = filterType.parameterCount();
- if (filterValues == 0
- ? (rtype != void.class)
- : (rtype != filterType.parameterType(0)))
- throw newIllegalArgumentException("target and filter types do not match", target, filter);
- // result = fold( lambda(retval, arg...) { filter(retval) },
- // lambda( arg...) { target(arg...) } )
- MethodType newType = targetType.changeReturnType(filterType.returnType());
- MethodHandle result = null;
- if (AdapterMethodHandle.canCollectArguments(filterType, targetType, 0, false)) {
- result = AdapterMethodHandle.makeCollectArguments(filter, target, 0, false);
- if (result != null) return result;
- }
- // FIXME: Too many nodes here.
- assert(MethodHandleNatives.workaroundWithoutRicochetFrames()); // this class is deprecated
- MethodHandle returner = dropArguments(filter, filterValues, targetType.parameterList());
- result = foldArguments(returner, target);
- assert(result.type().equals(newType));
- return result;
- }
-
- /**
- * Adapts a target method handle by pre-processing
- * some of its arguments, and then calling the target with
- * the result of the pre-processing, inserted into the original
- * sequence of arguments.
- * <p>
- * The pre-processing is performed by {@code combiner}, a second method handle.
- * Of the arguments passed to the adapter, the first {@code N} arguments
- * are copied to the combiner, which is then called.
- * (Here, {@code N} is defined as the parameter count of the combiner.)
- * After this, control passes to the target, with any result
- * from the combiner inserted before the original {@code N} incoming
- * arguments.
- * <p>
- * If the combiner returns a value, the first parameter type of the target
- * must be identical with the return type of the combiner, and the next
- * {@code N} parameter types of the target must exactly match the parameters
- * of the combiner.
- * <p>
- * If the combiner has a void return, no result will be inserted,
- * and the first {@code N} parameter types of the target
- * must exactly match the parameters of the combiner.
- * <p>
- * The resulting adapter is the same type as the target, except that the
- * first parameter type is dropped,
- * if it corresponds to the result of the combiner.
- * <p>
- * (Note that {@link #dropArguments(MethodHandle,int,List) dropArguments} can be used to remove any arguments
- * that either the combiner or the target does not wish to receive.
- * If some of the incoming arguments are destined only for the combiner,
- * consider using {@link MethodHandle#asCollector asCollector} instead, since those
- * arguments will not need to be live on the stack on entry to the
- * target.)
- * <b>Example:</b>
- * <p><blockquote><pre>
-import static java.lang.invoke.MethodHandles.*;
-import static java.lang.invoke.MethodType.*;
-...
-MethodHandle trace = publicLookup().findVirtual(java.io.PrintStream.class,
- "println", methodType(void.class, String.class))
- .bindTo(System.out);
-MethodHandle cat = lookup().findVirtual(String.class,
- "concat", methodType(String.class, String.class));
-assertEquals("boojum", (String) cat.invokeExact("boo", "jum"));
-MethodHandle catTrace = foldArguments(cat, trace);
-// also prints "boo":
-assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
- * </pre></blockquote>
- * <p> Here is pseudocode for the resulting adapter:
- * <blockquote><pre>
- * // there are N arguments in A...
- * T target(V, A[N]..., B...);
- * V combiner(A...);
- * T adapter(A... a, B... b) {
- * V v = combiner(a...);
- * return target(v, a..., b...);
- * }
- * // and if the combiner has a void return:
- * T target2(A[N]..., B...);
- * void combiner2(A...);
- * T adapter2(A... a, B... b) {
- * combiner2(a...);
- * return target2(a..., b...);
- * }
- * </pre></blockquote>
- * @param target the method handle to invoke after arguments are combined
- * @param combiner method handle to call initially on the incoming arguments
- * @return method handle which incorporates the specified argument folding logic
- * @throws NullPointerException if either argument is null
- * @throws IllegalArgumentException if {@code combiner}'s return type
- * is non-void and not the same as the first argument type of
- * the target, or if the initial {@code N} argument types
- * of the target
- * (skipping one matching the {@code combiner}'s return type)
- * are not identical with the argument types of {@code combiner}
- */
- public static
- MethodHandle foldArguments(MethodHandle target, MethodHandle combiner) {
- int pos = 0;
- MethodType targetType = target.type();
- MethodType combinerType = combiner.type();
- int foldPos = pos;
- int foldArgs = combinerType.parameterCount();
- int foldVals = combinerType.returnType() == void.class ? 0 : 1;
- int afterInsertPos = foldPos + foldVals;
- boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
- if (ok && !(combinerType.parameterList()
- .equals(targetType.parameterList().subList(afterInsertPos,
- afterInsertPos + foldArgs))))
- ok = false;
- if (ok && foldVals != 0 && !combinerType.returnType().equals(targetType.parameterType(0)))
- ok = false;
- if (!ok)
- throw misMatchedTypes("target and combiner types", targetType, combinerType);
- MethodType newType = targetType.dropParameterTypes(foldPos, afterInsertPos);
- MethodHandle res = MethodHandleImpl.foldArguments(target, newType, foldPos, combiner);
- if (res == null) throw newIllegalArgumentException("cannot fold from "+newType+" to " +targetType);
- return res;
- }
-
- /**
- * Makes a method handle which adapts a target method handle,
- * by guarding it with a test, a boolean-valued method handle.
- * If the guard fails, a fallback handle is called instead.
- * All three method handles must have the same corresponding
- * argument and return types, except that the return type
- * of the test must be boolean, and the test is allowed
- * to have fewer arguments than the other two method handles.
- * <p> Here is pseudocode for the resulting adapter:
- * <blockquote><pre>
- * boolean test(A...);
- * T target(A...,B...);
- * T fallback(A...,B...);
- * T adapter(A... a,B... b) {
- * if (test(a...))
- * return target(a..., b...);
- * else
- * return fallback(a..., b...);
- * }
- * </pre></blockquote>
- * Note that the test arguments ({@code a...} in the pseudocode) cannot
- * be modified by execution of the test, and so are passed unchanged
- * from the caller to the target or fallback as appropriate.
- * @param test method handle used for test, must return boolean
- * @param target method handle to call if test passes
- * @param fallback method handle to call if test fails
- * @return method handle which incorporates the specified if/then/else logic
- * @throws NullPointerException if any argument is null
- * @throws IllegalArgumentException if {@code test} does not return boolean,
- * or if all three method types do not match (with the return
- * type of {@code test} changed to match that of the target).
- */
- public static
- MethodHandle guardWithTest(MethodHandle test,
- MethodHandle target,
- MethodHandle fallback) {
- MethodType gtype = test.type();
- MethodType ttype = target.type();
- MethodType ftype = fallback.type();
- if (!ttype.equals(ftype))
- throw misMatchedTypes("target and fallback types", ttype, ftype);
- if (gtype.returnType() != boolean.class)
- throw newIllegalArgumentException("guard type is not a predicate "+gtype);
- List<Class<?>> targs = ttype.parameterList();
- List<Class<?>> gargs = gtype.parameterList();
- if (!targs.equals(gargs)) {
- int gpc = gargs.size(), tpc = targs.size();
- if (gpc >= tpc || !targs.subList(0, gpc).equals(gargs))
- throw misMatchedTypes("target and test types", ttype, gtype);
- test = dropArguments(test, gpc, targs.subList(gpc, tpc));
- gtype = test.type();
- }
- return MethodHandleImpl.makeGuardWithTest(test, target, fallback);
- }
-
- static RuntimeException misMatchedTypes(String what, MethodType t1, MethodType t2) {
- return newIllegalArgumentException(what + " must match: " + t1 + " != " + t2);
- }
-
- /**
- * Makes a method handle which adapts a target method handle,
- * by running it inside an exception handler.
- * If the target returns normally, the adapter returns that value.
- * If an exception matching the specified type is thrown, the fallback
- * handle is called instead on the exception, plus the original arguments.
- * <p>
- * The target and handler must have the same corresponding
- * argument and return types, except that handler may omit trailing arguments
- * (similarly to the predicate in {@link #guardWithTest guardWithTest}).
- * Also, the handler must have an extra leading parameter of {@code exType} or a supertype.
- * <p> Here is pseudocode for the resulting adapter:
- * <blockquote><pre>
- * T target(A..., B...);
- * T handler(ExType, A...);
- * T adapter(A... a, B... b) {
- * try {
- * return target(a..., b...);
- * } catch (ExType ex) {
- * return handler(ex, a...);
- * }
- * }
- * </pre></blockquote>
- * Note that the saved arguments ({@code a...} in the pseudocode) cannot
- * be modified by execution of the target, and so are passed unchanged
- * from the caller to the handler, if the handler is invoked.
- * <p>
- * The target and handler must return the same type, even if the handler
- * always throws. (This might happen, for instance, because the handler
- * is simulating a {@code finally} clause).
- * To create such a throwing handler, compose the handler creation logic
- * with {@link #throwException throwException},
- * in order to create a method handle of the correct return type.
- * @param target method handle to call
- * @param exType the type of exception which the handler will catch
- * @param handler method handle to call if a matching exception is thrown
- * @return method handle which incorporates the specified try/catch logic
- * @throws NullPointerException if any argument is null
- * @throws IllegalArgumentException if {@code handler} does not accept
- * the given exception type, or if the method handle types do
- * not match in their return types and their
- * corresponding parameters
- */
- public static
- MethodHandle catchException(MethodHandle target,
- Class<? extends Throwable> exType,
- MethodHandle handler) {
- MethodType ttype = target.type();
- MethodType htype = handler.type();
- if (htype.parameterCount() < 1 ||
- !htype.parameterType(0).isAssignableFrom(exType))
- throw newIllegalArgumentException("handler does not accept exception type "+exType);
- if (htype.returnType() != ttype.returnType())
- throw misMatchedTypes("target and handler return types", ttype, htype);
- List<Class<?>> targs = ttype.parameterList();
- List<Class<?>> hargs = htype.parameterList();
- hargs = hargs.subList(1, hargs.size()); // omit leading parameter from handler
- if (!targs.equals(hargs)) {
- int hpc = hargs.size(), tpc = targs.size();
- if (hpc >= tpc || !targs.subList(0, hpc).equals(hargs))
- throw misMatchedTypes("target and handler types", ttype, htype);
- handler = dropArguments(handler, 1+hpc, targs.subList(hpc, tpc));
- htype = handler.type();
- }
- return MethodHandleImpl.makeGuardWithCatch(target, exType, handler);
- }
-
- /**
- * Produces a method handle which will throw exceptions of the given {@code exType}.
- * The method handle will accept a single argument of {@code exType},
- * and immediately throw it as an exception.
- * The method type will nominally specify a return of {@code returnType}.
- * The return type may be anything convenient: It doesn't matter to the
- * method handle's behavior, since it will never return normally.
- * @return method handle which can throw the given exceptions
- * @throws NullPointerException if either argument is null
- */
- public static
- MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
- return MethodHandleImpl.throwException(MethodType.methodType(returnType, exType));
- }
-}
diff --git a/openjdk/java/lang/invoke/MutableCallSite.java b/openjdk/java/lang/invoke/MutableCallSite.java
deleted file mode 100644
index d48f99af..00000000
--- a/openjdk/java/lang/invoke/MutableCallSite.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.invoke;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * A {@code MutableCallSite} is a {@link CallSite} whose target variable
- * behaves like an ordinary field.
- * An {@code invokedynamic} instruction linked to a {@code MutableCallSite} delegates
- * all calls to the site's current target.
- * The {@linkplain CallSite#dynamicInvoker dynamic invoker} of a mutable call site
- * also delegates each call to the site's current target.
- * <p>
- * Here is an example of a mutable call site which introduces a
- * state variable into a method handle chain.
- * <!-- JavaDocExamplesTest.testMutableCallSite -->
- * <blockquote><pre>
-MutableCallSite name = new MutableCallSite(MethodType.methodType(String.class));
-MethodHandle MH_name = name.dynamicInvoker();
-MethodType MT_str1 = MethodType.methodType(String.class);
-MethodHandle MH_upcase = MethodHandles.lookup()
- .findVirtual(String.class, "toUpperCase", MT_str1);
-MethodHandle worker1 = MethodHandles.filterReturnValue(MH_name, MH_upcase);
-name.setTarget(MethodHandles.constant(String.class, "Rocky"));
-assertEquals("ROCKY", (String) worker1.invokeExact());
-name.setTarget(MethodHandles.constant(String.class, "Fred"));
-assertEquals("FRED", (String) worker1.invokeExact());
-// (mutation can be continued indefinitely)
- * </pre></blockquote>
- * <p>
- * The same call site may be used in several places at once.
- * <blockquote><pre>
-MethodType MT_str2 = MethodType.methodType(String.class, String.class);
-MethodHandle MH_cat = lookup().findVirtual(String.class,
- "concat", methodType(String.class, String.class));
-MethodHandle MH_dear = MethodHandles.insertArguments(MH_cat, 1, ", dear?");
-MethodHandle worker2 = MethodHandles.filterReturnValue(MH_name, MH_dear);
-assertEquals("Fred, dear?", (String) worker2.invokeExact());
-name.setTarget(MethodHandles.constant(String.class, "Wilma"));
-assertEquals("WILMA", (String) worker1.invokeExact());
-assertEquals("Wilma, dear?", (String) worker2.invokeExact());
- * </pre></blockquote>
- * <p>
- * <em>Non-synchronization of target values:</em>
- * A write to a mutable call site's target does not force other threads
- * to become aware of the updated value. Threads which do not perform
- * suitable synchronization actions relative to the updated call site
- * may cache the old target value and delay their use of the new target
- * value indefinitely.
- * (This is a normal consequence of the Java Memory Model as applied
- * to object fields.)
- * <p>
- * The {@link #syncAll syncAll} operation provides a way to force threads
- * to accept a new target value, even if there is no other synchronization.
- * <p>
- * For target values which will be frequently updated, consider using
- * a {@linkplain VolatileCallSite volatile call site} instead.
- * @author John Rose, JSR 292 EG
- */
-public class MutableCallSite extends CallSite {
- /**
- * Creates a blank call site object with the given method type.
- * The initial target is set to a method handle of the given type
- * which will throw an {@link IllegalStateException} if called.
- * <p>
- * The type of the call site is permanently set to the given type.
- * <p>
- * Before this {@code CallSite} object is returned from a bootstrap method,
- * or invoked in some other manner,
- * it is usually provided with a more useful target method,
- * via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
- * @param type the method type that this call site will have
- * @throws NullPointerException if the proposed type is null
- */
- public MutableCallSite(MethodType type) {
- super(type);
- }
-
- /**
- * Creates a call site object with an initial target method handle.
- * The type of the call site is permanently set to the initial target's type.
- * @param target the method handle that will be the initial target of the call site
- * @throws NullPointerException if the proposed target is null
- */
- public MutableCallSite(MethodHandle target) {
- super(target);
- }
-
- /**
- * Returns the target method of the call site, which behaves
- * like a normal field of the {@code MutableCallSite}.
- * <p>
- * The interactions of {@code getTarget} with memory are the same
- * as of a read from an ordinary variable, such as an array element or a
- * non-volatile, non-final field.
- * <p>
- * In particular, the current thread may choose to reuse the result
- * of a previous read of the target from memory, and may fail to see
- * a recent update to the target by another thread.
- *
- * @return the linkage state of this call site, a method handle which can change over time
- * @see #setTarget
- */
- @Override public final MethodHandle getTarget() {
- return target;
- }
-
- /**
- * Updates the target method of this call site, as a normal variable.
- * The type of the new target must agree with the type of the old target.
- * <p>
- * The interactions with memory are the same
- * as of a write to an ordinary variable, such as an array element or a
- * non-volatile, non-final field.
- * <p>
- * In particular, unrelated threads may fail to see the updated target
- * until they perform a read from memory.
- * Stronger guarantees can be created by putting appropriate operations
- * into the bootstrap method and/or the target methods used
- * at any given call site.
- *
- * @param newTarget the new target
- * @throws NullPointerException if the proposed new target is null
- * @throws WrongMethodTypeException if the proposed new target
- * has a method type that differs from the previous target
- * @see #getTarget
- */
- @Override public void setTarget(MethodHandle newTarget) {
- checkTargetChange(this.target, newTarget);
- setTargetNormal(newTarget);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public final MethodHandle dynamicInvoker() {
- return makeDynamicInvoker();
- }
-
- /**
- * Performs a synchronization operation on each call site in the given array,
- * forcing all other threads to throw away any cached values previously
- * loaded from the target of any of the call sites.
- * <p>
- * This operation does not reverse any calls that have already started
- * on an old target value.
- * (Java supports {@linkplain java.lang.Object#wait() forward time travel} only.)
- * <p>
- * The overall effect is to force all future readers of each call site's target
- * to accept the most recently stored value.
- * ("Most recently" is reckoned relative to the {@code syncAll} itself.)
- * Conversely, the {@code syncAll} call may block until all readers have
- * (somehow) decached all previous versions of each call site's target.
- * <p>
- * To avoid race conditions, calls to {@code setTarget} and {@code syncAll}
- * should generally be performed under some sort of mutual exclusion.
- * Note that reader threads may observe an updated target as early
- * as the {@code setTarget} call that install the value
- * (and before the {@code syncAll} that confirms the value).
- * On the other hand, reader threads may observe previous versions of
- * the target until the {@code syncAll} call returns
- * (and after the {@code setTarget} that attempts to convey the updated version).
- * <p>
- * This operation is likely to be expensive and should be used sparingly.
- * If possible, it should be buffered for batch processing on sets of call sites.
- * <p>
- * If {@code sites} contains a null element,
- * a {@code NullPointerException} will be raised.
- * In this case, some non-null elements in the array may be
- * processed before the method returns abnormally.
- * Which elements these are (if any) is implementation-dependent.
- *
- * <h3>Java Memory Model details</h3>
- * In terms of the Java Memory Model, this operation performs a synchronization
- * action which is comparable in effect to the writing of a volatile variable
- * by the current thread, and an eventual volatile read by every other thread
- * that may access one of the affected call sites.
- * <p>
- * The following effects are apparent, for each individual call site {@code S}:
- * <ul>
- * <li>A new volatile variable {@code V} is created, and written by the current thread.
- * As defined by the JMM, this write is a global synchronization event.
- * <li>As is normal with thread-local ordering of write events,
- * every action already performed by the current thread is
- * taken to happen before the volatile write to {@code V}.
- * (In some implementations, this means that the current thread
- * performs a global release operation.)
- * <li>Specifically, the write to the current target of {@code S} is
- * taken to happen before the volatile write to {@code V}.
- * <li>The volatile write to {@code V} is placed
- * (in an implementation specific manner)
- * in the global synchronization order.
- * <li>Consider an arbitrary thread {@code T} (other than the current thread).
- * If {@code T} executes a synchronization action {@code A}
- * after the volatile write to {@code V} (in the global synchronization order),
- * it is therefore required to see either the current target
- * of {@code S}, or a later write to that target,
- * if it executes a read on the target of {@code S}.
- * (This constraint is called "synchronization-order consistency".)
- * <li>The JMM specifically allows optimizing compilers to elide
- * reads or writes of variables that are known to be useless.
- * Such elided reads and writes have no effect on the happens-before
- * relation. Regardless of this fact, the volatile {@code V}
- * will not be elided, even though its written value is
- * indeterminate and its read value is not used.
- * </ul>
- * Because of the last point, the implementation behaves as if a
- * volatile read of {@code V} were performed by {@code T}
- * immediately after its action {@code A}. In the local ordering
- * of actions in {@code T}, this read happens before any future
- * read of the target of {@code S}. It is as if the
- * implementation arbitrarily picked a read of {@code S}'s target
- * by {@code T}, and forced a read of {@code V} to precede it,
- * thereby ensuring communication of the new target value.
- * <p>
- * As long as the constraints of the Java Memory Model are obeyed,
- * implementations may delay the completion of a {@code syncAll}
- * operation while other threads ({@code T} above) continue to
- * use previous values of {@code S}'s target.
- * However, implementations are (as always) encouraged to avoid
- * livelock, and to eventually require all threads to take account
- * of the updated target.
- *
- * <p style="font-size:smaller;">
- * <em>Discussion:</em>
- * For performance reasons, {@code syncAll} is not a virtual method
- * on a single call site, but rather applies to a set of call sites.
- * Some implementations may incur a large fixed overhead cost
- * for processing one or more synchronization operations,
- * but a small incremental cost for each additional call site.
- * In any case, this operation is likely to be costly, since
- * other threads may have to be somehow interrupted
- * in order to make them notice the updated target value.
- * However, it may be observed that a single call to synchronize
- * several sites has the same formal effect as many calls,
- * each on just one of the sites.
- *
- * <p style="font-size:smaller;">
- * <em>Implementation Note:</em>
- * Simple implementations of {@code MutableCallSite} may use
- * a volatile variable for the target of a mutable call site.
- * In such an implementation, the {@code syncAll} method can be a no-op,
- * and yet it will conform to the JMM behavior documented above.
- *
- * @param sites an array of call sites to be synchronized
- * @throws NullPointerException if the {@code sites} array reference is null
- * or the array contains a null
- */
- public static void syncAll(MutableCallSite[] sites) {
- if (sites.length == 0) return;
- STORE_BARRIER.lazySet(0);
- for (int i = 0; i < sites.length; i++) {
- sites[i].getClass(); // trigger NPE on first null
- }
- // FIXME: NYI
- }
- private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
-}
diff --git a/openjdk/java/lang/invoke/VolatileCallSite.java b/openjdk/java/lang/invoke/VolatileCallSite.java
deleted file mode 100644
index de88f36b..00000000
--- a/openjdk/java/lang/invoke/VolatileCallSite.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.invoke;
-
-/**
- * A {@code VolatileCallSite} is a {@link CallSite} whose target acts like a volatile variable.
- * An {@code invokedynamic} instruction linked to a {@code VolatileCallSite} sees updates
- * to its call site target immediately, even if the update occurs in another thread.
- * There may be a performance penalty for such tight coupling between threads.
- * <p>
- * Unlike {@code MutableCallSite}, there is no
- * {@linkplain MutableCallSite#syncAll syncAll operation} on volatile
- * call sites, since every write to a volatile variable is implicitly
- * synchronized with reader threads.
- * <p>
- * In other respects, a {@code VolatileCallSite} is interchangeable
- * with {@code MutableCallSite}.
- * @see MutableCallSite
- * @author John Rose, JSR 292 EG
- */
-public class VolatileCallSite extends CallSite {
- /**
- * Creates a call site with a volatile binding to its target.
- * The initial target is set to a method handle
- * of the given type which will throw an {@code IllegalStateException} if called.
- * @param type the method type that this call site will have
- * @throws NullPointerException if the proposed type is null
- */
- public VolatileCallSite(MethodType type) {
- super(type);
- }
-
- /**
- * Creates a call site with a volatile binding to its target.
- * The target is set to the given value.
- * @param target the method handle that will be the initial target of the call site
- * @throws NullPointerException if the proposed target is null
- */
- public VolatileCallSite(MethodHandle target) {
- super(target);
- }
-
- /**
- * Returns the target method of the call site, which behaves
- * like a {@code volatile} field of the {@code VolatileCallSite}.
- * <p>
- * The interactions of {@code getTarget} with memory are the same
- * as of a read from a {@code volatile} field.
- * <p>
- * In particular, the current thread is required to issue a fresh
- * read of the target from memory, and must not fail to see
- * a recent update to the target by another thread.
- *
- * @return the linkage state of this call site, a method handle which can change over time
- * @see #setTarget
- */
- @Override public final MethodHandle getTarget() {
- return getTargetVolatile();
- }
-
- /**
- * Updates the target method of this call site, as a volatile variable.
- * The type of the new target must agree with the type of the old target.
- * <p>
- * The interactions with memory are the same as of a write to a volatile field.
- * In particular, any threads is guaranteed to see the updated target
- * the next time it calls {@code getTarget}.
- * @param newTarget the new target
- * @throws NullPointerException if the proposed new target is null
- * @throws WrongMethodTypeException if the proposed new target
- * has a method type that differs from the previous target
- * @see #getTarget
- */
- @Override public void setTarget(MethodHandle newTarget) {
- checkTargetChange(getTargetVolatile(), newTarget);
- setTargetVolatile(newTarget);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public final MethodHandle dynamicInvoker() {
- return makeDynamicInvoker();
- }
-}
diff --git a/openjdk/java/lang/management/PlatformComponent.java b/openjdk/java/lang/management/PlatformComponent.java
deleted file mode 100644
index 3d29a16b..00000000
--- a/openjdk/java/lang/management/PlatformComponent.java
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.management;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import javax.management.MBeanServerConnection;
-import javax.management.ObjectName;
-
-import sun.management.ManagementFactoryHelper;
-import sun.management.Util;
-
-/**
- * This enum class defines the list of platform components
- * that provides monitoring and management support.
- * Each enum represents one MXBean interface. A MXBean
- * instance could implement one or more MXBean interfaces.
- *
- * For example, com.sun.management.GarbageCollectorMXBean
- * extends java.lang.management.GarbageCollectorMXBean
- * and there is one set of garbage collection MXBean instances,
- * each of which implements both c.s.m. and j.l.m. interfaces.
- * There are two separate enums GARBAGE_COLLECTOR
- * and SUN_GARBAGE_COLLECTOR so that ManagementFactory.getPlatformMXBeans(Class)
- * will return the list of MXBeans of the specified type.
- *
- * To add a new MXBean interface for the Java platform,
- * add a new enum constant and implement the MXBeanFetcher.
- */
-enum PlatformComponent {
-
- /**
- * Class loading system of the Java virtual machine.
- */
- CLASS_LOADING(
- "java.lang.management.ClassLoadingMXBean",
- "java.lang", "ClassLoading", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<ClassLoadingMXBean>() {
- public List<ClassLoadingMXBean> getMXBeans() {
- return Collections.singletonList(ManagementFactoryHelper.getClassLoadingMXBean());
- }
- }),
-
- /**
- * Compilation system of the Java virtual machine.
- */
- COMPILATION(
- "java.lang.management.CompilationMXBean",
- "java.lang", "Compilation", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<CompilationMXBean>() {
- public List<CompilationMXBean> getMXBeans() {
- CompilationMXBean m = ManagementFactoryHelper.getCompilationMXBean();
- if (m == null) {
- return Collections.emptyList();
- } else {
- return Collections.singletonList(m);
- }
- }
- }),
-
- /**
- * Memory system of the Java virtual machine.
- */
- MEMORY(
- "java.lang.management.MemoryMXBean",
- "java.lang", "Memory", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<MemoryMXBean>() {
- public List<MemoryMXBean> getMXBeans() {
- return Collections.singletonList(ManagementFactoryHelper.getMemoryMXBean());
- }
- }),
-
- /**
- * Garbage Collector in the Java virtual machine.
- */
- GARBAGE_COLLECTOR(
- "java.lang.management.GarbageCollectorMXBean",
- "java.lang", "GarbageCollector", keyProperties("name"),
- false, // zero or more instances
- new MXBeanFetcher<GarbageCollectorMXBean>() {
- public List<GarbageCollectorMXBean> getMXBeans() {
- return ManagementFactoryHelper.
- getGarbageCollectorMXBeans();
- }
- }),
-
- /**
- * Memory manager in the Java virtual machine.
- */
- MEMORY_MANAGER(
- "java.lang.management.MemoryManagerMXBean",
- "java.lang", "MemoryManager", keyProperties("name"),
- false, // zero or more instances
- new MXBeanFetcher<MemoryManagerMXBean>() {
- public List<MemoryManagerMXBean> getMXBeans() {
- return ManagementFactoryHelper.getMemoryManagerMXBeans();
- }
- },
- GARBAGE_COLLECTOR),
-
- /**
- * Memory pool in the Java virtual machine.
- */
- MEMORY_POOL(
- "java.lang.management.MemoryPoolMXBean",
- "java.lang", "MemoryPool", keyProperties("name"),
- false, // zero or more instances
- new MXBeanFetcher<MemoryPoolMXBean>() {
- public List<MemoryPoolMXBean> getMXBeans() {
- return ManagementFactoryHelper.getMemoryPoolMXBeans();
- }
- }),
-
- /**
- * Operating system on which the Java virtual machine is running
- */
- OPERATING_SYSTEM(
- "java.lang.management.OperatingSystemMXBean",
- "java.lang", "OperatingSystem", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<OperatingSystemMXBean>() {
- public List<OperatingSystemMXBean> getMXBeans() {
- return Collections.singletonList(ManagementFactoryHelper.getOperatingSystemMXBean());
- }
- }),
-
- /**
- * Runtime system of the Java virtual machine.
- */
- RUNTIME(
- "java.lang.management.RuntimeMXBean",
- "java.lang", "Runtime", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<RuntimeMXBean>() {
- public List<RuntimeMXBean> getMXBeans() {
- return Collections.singletonList(ManagementFactoryHelper.getRuntimeMXBean());
- }
- }),
-
- /**
- * Threading system of the Java virtual machine.
- */
- THREADING(
- "java.lang.management.ThreadMXBean",
- "java.lang", "Threading", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<ThreadMXBean>() {
- public List<ThreadMXBean> getMXBeans() {
- return Collections.singletonList(ManagementFactoryHelper.getThreadMXBean());
- }
- }),
-
-
- /**
- * Logging facility.
- */
- LOGGING(
- "java.lang.management.PlatformLoggingMXBean",
- "java.util.logging", "Logging", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<PlatformLoggingMXBean>() {
- public List<PlatformLoggingMXBean> getMXBeans() {
- PlatformLoggingMXBean m = ManagementFactoryHelper.getPlatformLoggingMXBean();
- if (m == null) {
- return Collections.emptyList();
- } else {
- return Collections.singletonList(m);
- }
- }
- }),
-
- /**
- * Buffer pools.
- */
- BUFFER_POOL(
- "java.lang.management.BufferPoolMXBean",
- "java.nio", "BufferPool", keyProperties("name"),
- false, // zero or more instances
- new MXBeanFetcher<BufferPoolMXBean>() {
- public List<BufferPoolMXBean> getMXBeans() {
- return ManagementFactoryHelper.getBufferPoolMXBeans();
- }
- });
-
- /**
- * A task that returns the MXBeans for a component.
- */
- interface MXBeanFetcher<T extends PlatformManagedObject> {
- public List<T> getMXBeans();
- }
-
- /*
- * Returns a list of the GC MXBeans of the given type.
- */
- private static <T extends GarbageCollectorMXBean>
- List<T> getGcMXBeanList(Class<T> gcMXBeanIntf) {
- List<GarbageCollectorMXBean> list =
- ManagementFactoryHelper.getGarbageCollectorMXBeans();
- List<T> result = new ArrayList<>(list.size());
- for (GarbageCollectorMXBean m : list) {
- if (gcMXBeanIntf.isInstance(m)) {
- result.add(gcMXBeanIntf.cast(m));
- }
- }
- return result;
- }
-
- /*
- * Returns the OS mxbean instance of the given type.
- */
- private static <T extends OperatingSystemMXBean>
- List<T> getOSMXBeanList(Class<T> osMXBeanIntf) {
- OperatingSystemMXBean m =
- ManagementFactoryHelper.getOperatingSystemMXBean();
- if (osMXBeanIntf.isInstance(m)) {
- return Collections.singletonList(osMXBeanIntf.cast(m));
- } else {
- return Collections.emptyList();
- }
- }
-
- private final String mxbeanInterfaceName;
- private final String domain;
- private final String type;
- private final Set<String> keyProperties;
- private final MXBeanFetcher fetcher;
- private final PlatformComponent[] subComponents;
- private final boolean singleton;
-
- private PlatformComponent(String intfName,
- String domain, String type,
- Set<String> keyProperties,
- boolean singleton,
- MXBeanFetcher fetcher,
- PlatformComponent... subComponents) {
- this.mxbeanInterfaceName = intfName;
- this.domain = domain;
- this.type = type;
- this.keyProperties = keyProperties;
- this.singleton = singleton;
- this.fetcher = fetcher;
- this.subComponents = subComponents;
- }
-
- private static Set<String> defaultKeyProps;
- private static Set<String> defaultKeyProperties() {
- if (defaultKeyProps == null) {
- defaultKeyProps = Collections.singleton("type");
- }
- return defaultKeyProps;
- }
-
- private static Set<String> keyProperties(String... keyNames) {
- Set<String> set = new HashSet<>();
- set.add("type");
- for (String s : keyNames) {
- set.add(s);
- }
- return set;
- }
-
- boolean isSingleton() {
- return singleton;
- }
-
- String getMXBeanInterfaceName() {
- return mxbeanInterfaceName;
- }
-
- @SuppressWarnings("unchecked")
- Class<? extends PlatformManagedObject> getMXBeanInterface() {
- try {
- // Lazy loading the MXBean interface only when it is needed
- return (Class<? extends PlatformManagedObject>)
- Class.forName(mxbeanInterfaceName, false, null);
- } catch (ClassNotFoundException x) {
- throw new AssertionError(x);
- }
- }
-
- @SuppressWarnings("unchecked")
- <T extends PlatformManagedObject>
- List<T> getMXBeans(Class<T> mxbeanInterface)
- {
- return fetcher.getMXBeans();
- }
-
- <T extends PlatformManagedObject> T getSingletonMXBean(Class<T> mxbeanInterface)
- {
- if (!singleton)
- throw new IllegalArgumentException(mxbeanInterfaceName +
- " can have zero or more than one instances");
-
- List<T> list = fetcher.getMXBeans();
- assert list.size() == 1;
- return list.isEmpty() ? null : list.get(0);
- }
-
- <T extends PlatformManagedObject>
- T getSingletonMXBean(MBeanServerConnection mbs, Class<T> mxbeanInterface)
- throws java.io.IOException
- {
- if (!singleton)
- throw new IllegalArgumentException(mxbeanInterfaceName +
- " can have zero or more than one instances");
-
- // ObjectName of a singleton MXBean contains only domain and type
- assert keyProperties.size() == 1;
- String on = domain + ":type=" + type;
- return ManagementFactory.newPlatformMXBeanProxy(mbs,
- on,
- mxbeanInterface);
- }
-
- <T extends PlatformManagedObject>
- List<T> getMXBeans(MBeanServerConnection mbs, Class<T> mxbeanInterface)
- throws java.io.IOException
- {
- List<T> result = new ArrayList<>();
- for (ObjectName on : getObjectNames(mbs)) {
- result.add(ManagementFactory.
- newPlatformMXBeanProxy(mbs,
- on.getCanonicalName(),
- mxbeanInterface)
- );
- }
- return result;
- }
-
- private Set<ObjectName> getObjectNames(MBeanServerConnection mbs)
- throws java.io.IOException
- {
- String domainAndType = domain + ":type=" + type;
- if (keyProperties.size() > 1) {
- // if there are more than 1 key properties (i.e. other than "type")
- domainAndType += ",*";
- }
- ObjectName on = Util.newObjectName(domainAndType);
- Set<ObjectName> set = mbs.queryNames(on, null);
- for (PlatformComponent pc : subComponents) {
- set.addAll(pc.getObjectNames(mbs));
- }
- return set;
- }
-
- // a map from MXBean interface name to PlatformComponent
- private static Map<String, PlatformComponent> enumMap;
- private static synchronized void ensureInitialized() {
- if (enumMap == null) {
- enumMap = new HashMap<>();
- for (PlatformComponent pc: PlatformComponent.values()) {
- // Use String as the key rather than Class<?> to avoid
- // causing unnecessary class loading of management interface
- enumMap.put(pc.getMXBeanInterfaceName(), pc);
- }
- }
- }
-
- static boolean isPlatformMXBean(String cn) {
- ensureInitialized();
- return enumMap.containsKey(cn);
- }
-
- static <T extends PlatformManagedObject>
- PlatformComponent getPlatformComponent(Class<T> mxbeanInterface)
- {
- ensureInitialized();
- String cn = mxbeanInterface.getName();
- PlatformComponent pc = enumMap.get(cn);
- if (pc != null && pc.getMXBeanInterface() == mxbeanInterface)
- return pc;
- return null;
- }
-
- private static final long serialVersionUID = 6992337162326171013L;
-}
diff --git a/openjdk/java/lang/ref/Reference.java b/openjdk/java/lang/ref/Reference.java
deleted file mode 100644
index cc2bfa5c..00000000
--- a/openjdk/java/lang/ref/Reference.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- Copyright (C) 2003-2012 Jeroen Frijters
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jeroen Frijters
- jeroen@frijters.net
-
-*/
-package java.lang.ref;
-
-import cli.System.Collections.Hashtable;
-import sun.misc.Cleaner;
-
-public abstract class Reference<T>
-{
- // accessed by inner class
- volatile cli.System.WeakReference weakRef;
- volatile T strongRef;
- volatile ReferenceQueue<? super T> queue;
- volatile Reference next;
-
- private static native boolean noclassgc();
-
- Reference(T referent)
- {
- this(referent, null);
- }
-
- Reference(T referent, ReferenceQueue<? super T> queue)
- {
- this.queue = queue == null ? ReferenceQueue.NULL : queue;
- if (referent != null)
- {
- if (referent instanceof Class && noclassgc())
- {
- // We don't do Class gc, so no point in using a weak reference for classes.
- strongRef = referent;
- }
- else
- {
- weakRef = new cli.System.WeakReference(referent, this instanceof PhantomReference);
- if (queue != null || referent instanceof Cleaner || this instanceof SoftReference)
- {
- new QueueWatcher(this);
- }
- }
- }
- }
-
- private static final boolean debug = false;
-
- private static final class QueueWatcher
- {
- private static final Hashtable keepAlive = Hashtable.Synchronized(new Hashtable());
- private cli.System.WeakReference handle;
-
- QueueWatcher(Reference r)
- {
- handle = new cli.System.WeakReference(r, true);
- // FXBUG when a WeakReference is finalizer reachable, it gets cleared by the GC (even if we call GC.SuppressFinalize),
- // so we have to maintain a strong reference to it to prevent it from being cleared.
- keepAlive.Add(handle, null);
- }
-
- boolean check(Reference r)
- {
- r.strongRef = null;
- boolean alive = false;
- try
- {
- if (false) throw new cli.System.InvalidOperationException();
- cli.System.WeakReference referent = r.weakRef;
- if (referent == null)
- {
- // ref was explicitly cleared, so we don't enqueue
- return false;
- }
- alive = referent.get_IsAlive();
- }
- catch (cli.System.InvalidOperationException x)
- {
- // this happens if the reference is already finalized (if we were
- // the only one still hanging on to it)
- }
- if (alive)
- {
- // we don't want to keep creating finalizable objects during shutdown
- if (!cli.System.Environment.get_HasShutdownStarted())
- {
- return true;
- }
- }
- else
- {
- if (r instanceof Cleaner)
- {
- ((Cleaner)r).clean();
- }
- else if (r.queue != null)
- {
- r.queue.enqueue(r);
- }
- }
- return false;
- }
-
- protected void finalize()
- {
- Reference r = (Reference)handle.get_Target();
- if (debug)
- cli.System.Console.WriteLine("~QueueWatcher: " + hashCode() + " on " + r);
- if (r != null && r.next == null && check(r))
- {
- cli.System.GC.ReRegisterForFinalize(QueueWatcher.this);
- }
- else
- {
- handle.set_Target(null);
- keepAlive.Remove(handle);
- }
- }
- }
-
- public T get()
- {
- try
- {
- if (false) throw new cli.System.InvalidOperationException();
- cli.System.WeakReference referent = this.weakRef;
- if (referent == null)
- {
- return strongRef;
- }
- T value = (T)referent.get_Target();
- if (value == null)
- {
- queue.enqueue(this);
- }
- return value;
- }
- catch (cli.System.InvalidOperationException x)
- {
- // we were already finalized, so we just return null.
- return null;
- }
- }
-
- public void clear()
- {
- weakRef = null;
- strongRef = null;
- }
-
- public synchronized boolean isEnqueued()
- {
- return queue != ReferenceQueue.NULL && next != null;
- }
-
- public boolean enqueue()
- {
- return queue.enqueue(this);
- }
-}
diff --git a/openjdk/java/lang/ref/SoftReference.java b/openjdk/java/lang/ref/SoftReference.java
deleted file mode 100644
index 04d24933..00000000
--- a/openjdk/java/lang/ref/SoftReference.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.ref;
-
-
-/**
- * Soft reference objects, which are cleared at the discretion of the garbage
- * collector in response to memory demand. Soft references are most often used
- * to implement memory-sensitive caches.
- *
- * <p> Suppose that the garbage collector determines at a certain point in time
- * that an object is <a href="package-summary.html#reachability">softly
- * reachable</a>. At that time it may choose to clear atomically all soft
- * references to that object and all soft references to any other
- * softly-reachable objects from which that object is reachable through a chain
- * of strong references. At the same time or at some later time it will
- * enqueue those newly-cleared soft references that are registered with
- * reference queues.
- *
- * <p> All soft references to softly-reachable objects are guaranteed to have
- * been cleared before the virtual machine throws an
- * <code>OutOfMemoryError</code>. Otherwise no constraints are placed upon the
- * time at which a soft reference will be cleared or the order in which a set
- * of such references to different objects will be cleared. Virtual machine
- * implementations are, however, encouraged to bias against clearing
- * recently-created or recently-used soft references.
- *
- * <p> Direct instances of this class may be used to implement simple caches;
- * this class or derived subclasses may also be used in larger data structures
- * to implement more sophisticated caches. As long as the referent of a soft
- * reference is strongly reachable, that is, is actually in use, the soft
- * reference will not be cleared. Thus a sophisticated cache can, for example,
- * prevent its most recently used entries from being discarded by keeping
- * strong referents to those entries, leaving the remaining entries to be
- * discarded at the discretion of the garbage collector.
- *
- * @author Mark Reinhold
- * @since 1.2
- */
-
-public class SoftReference<T> extends Reference<T> {
-
- /**
- * Timestamp clock, updated by the garbage collector
- */
- static private long clock;
-
- /**
- * Timestamp updated by each invocation of the get method. The VM may use
- * this field when selecting soft references to be cleared, but it is not
- * required to do so.
- */
- private long timestamp;
-
- /**
- * Creates a new soft reference that refers to the given object. The new
- * reference is not registered with any queue.
- *
- * @param referent object the new soft reference will refer to
- */
- public SoftReference(T referent) {
- super(referent);
- strongRef = referent;
- }
-
- /**
- * Creates a new soft reference that refers to the given object and is
- * registered with the given queue.
- *
- * @param referent object the new soft reference will refer to
- * @param q the queue with which the reference is to be registered,
- * or <tt>null</tt> if registration is not required
- *
- */
- public SoftReference(T referent, ReferenceQueue<? super T> q) {
- super(referent, q);
- strongRef = referent;
- }
-
- /**
- * Returns this reference object's referent. If this reference object has
- * been cleared, either by the program or by the garbage collector, then
- * this method returns <code>null</code>.
- *
- * @return The object to which this reference refers, or
- * <code>null</code> if this reference object has been cleared
- */
- public T get() {
- T o = super.get();
- strongRef = o;
- return o;
- }
-
-}
diff --git a/openjdk/java/lang/reflect/Constructor.java b/openjdk/java/lang/reflect/Constructor.java
deleted file mode 100644
index b13d30a5..00000000
--- a/openjdk/java/lang/reflect/Constructor.java
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.reflect;
-
-import sun.reflect.CallerSensitive;
-import sun.reflect.ConstructorAccessor;
-import sun.reflect.Reflection;
-import sun.reflect.generics.repository.ConstructorRepository;
-import sun.reflect.generics.factory.CoreReflectionFactory;
-import sun.reflect.generics.factory.GenericsFactory;
-import sun.reflect.generics.scope.ConstructorScope;
-import java.lang.annotation.Annotation;
-import java.util.Map;
-import sun.reflect.annotation.AnnotationParser;
-import java.lang.annotation.AnnotationFormatError;
-import java.lang.reflect.Modifier;
-
-/**
- * {@code Constructor} provides information about, and access to, a single
- * constructor for a class.
- *
- * <p>{@code Constructor} permits widening conversions to occur when matching the
- * actual parameters to newInstance() with the underlying
- * constructor's formal parameters, but throws an
- * {@code IllegalArgumentException} if a narrowing conversion would occur.
- *
- * @param <T> the class in which the constructor is declared
- *
- * @see Member
- * @see java.lang.Class
- * @see java.lang.Class#getConstructors()
- * @see java.lang.Class#getConstructor(Class[])
- * @see java.lang.Class#getDeclaredConstructors()
- *
- * @author Kenneth Russell
- * @author Nakul Saraiya
- */
-public final
- class Constructor<T> extends AccessibleObject implements
- GenericDeclaration,
- Member {
-
- private Class<T> clazz;
- private int slot;
- private Class<?>[] parameterTypes;
- private Class<?>[] exceptionTypes;
- private int modifiers;
- // Generics and annotations support
- private transient String signature;
- // generic info repository; lazily initialized
- private transient ConstructorRepository genericInfo;
-
- // Generics infrastructure
- // Accessor for factory
- private GenericsFactory getFactory() {
- // create scope and factory
- return CoreReflectionFactory.make(this, ConstructorScope.make(this));
- }
-
- // Accessor for generic info repository
- private ConstructorRepository getGenericInfo() {
- // lazily initialize repository if necessary
- if (genericInfo == null) {
- // create and cache generic info repository
- genericInfo =
- ConstructorRepository.make(getSignature(),
- getFactory());
- }
- return genericInfo; //return cached repository
- }
-
- private volatile ConstructorAccessor constructorAccessor;
- // For sharing of ConstructorAccessors. This branching structure
- // is currently only two levels deep (i.e., one root Constructor
- // and potentially many Constructor objects pointing to it.)
- private Constructor<T> root;
-
- /**
- * Package-private constructor used by ReflectAccess to enable
- * instantiation of these objects in Java code from the java.lang
- * package via sun.reflect.LangReflectAccess.
- */
- Constructor(Class<T> declaringClass,
- Class<?>[] parameterTypes,
- Class<?>[] checkedExceptions,
- int modifiers,
- int slot,
- String signature,
- byte[] unused1,
- byte[] unused2)
- {
- this.clazz = declaringClass;
- this.parameterTypes = parameterTypes;
- this.exceptionTypes = checkedExceptions;
- this.modifiers = modifiers;
- this.slot = slot;
- this.signature = signature;
- }
-
- /**
- * Package-private routine (exposed to java.lang.Class via
- * ReflectAccess) which returns a copy of this Constructor. The copy's
- * "root" field points to this Constructor.
- */
- Constructor<T> copy() {
- // This routine enables sharing of ConstructorAccessor objects
- // among Constructor objects which refer to the same underlying
- // method in the VM. (All of this contortion is only necessary
- // because of the "accessibility" bit in AccessibleObject,
- // which implicitly requires that new java.lang.reflect
- // objects be fabricated for each reflective call on Class
- // objects.)
- Constructor<T> res = new Constructor<>(clazz,
- parameterTypes,
- exceptionTypes, modifiers, slot,
- signature,
- null,
- null);
- res.root = this;
- // Might as well eagerly propagate this if already present
- res.constructorAccessor = constructorAccessor;
- return res;
- }
-
- /**
- * Returns the {@code Class} object representing the class that declares
- * the constructor represented by this {@code Constructor} object.
- */
- public Class<T> getDeclaringClass() {
- return clazz;
- }
-
- /**
- * Returns the name of this constructor, as a string. This is
- * the binary name of the constructor's declaring class.
- */
- public String getName() {
- return getDeclaringClass().getName();
- }
-
- /**
- * Returns the Java language modifiers for the constructor
- * represented by this {@code Constructor} object, as an integer. The
- * {@code Modifier} class should be used to decode the modifiers.
- *
- * @see Modifier
- */
- public int getModifiers() {
- return modifiers;
- }
-
- /**
- * Returns an array of {@code TypeVariable} objects that represent the
- * type variables declared by the generic declaration represented by this
- * {@code GenericDeclaration} object, in declaration order. Returns an
- * array of length 0 if the underlying generic declaration declares no type
- * variables.
- *
- * @return an array of {@code TypeVariable} objects that represent
- * the type variables declared by this generic declaration
- * @throws GenericSignatureFormatError if the generic
- * signature of this generic declaration does not conform to
- * the format specified in
- * <cite>The Java&trade; Virtual Machine Specification</cite>
- * @since 1.5
- */
- public TypeVariable<Constructor<T>>[] getTypeParameters() {
- if (getSignature() != null) {
- return (TypeVariable<Constructor<T>>[])getGenericInfo().getTypeParameters();
- } else
- return (TypeVariable<Constructor<T>>[])new TypeVariable[0];
- }
-
-
- /**
- * Returns an array of {@code Class} objects that represent the formal
- * parameter types, in declaration order, of the constructor
- * represented by this {@code Constructor} object. Returns an array of
- * length 0 if the underlying constructor takes no parameters.
- *
- * @return the parameter types for the constructor this object
- * represents
- */
- public Class<?>[] getParameterTypes() {
- return (Class<?>[]) parameterTypes.clone();
- }
-
-
- /**
- * Returns an array of {@code Type} objects that represent the formal
- * parameter types, in declaration order, of the method represented by
- * this {@code Constructor} object. Returns an array of length 0 if the
- * underlying method takes no parameters.
- *
- * <p>If a formal parameter type is a parameterized type,
- * the {@code Type} object returned for it must accurately reflect
- * the actual type parameters used in the source code.
- *
- * <p>If a formal parameter type is a type variable or a parameterized
- * type, it is created. Otherwise, it is resolved.
- *
- * @return an array of {@code Type}s that represent the formal
- * parameter types of the underlying method, in declaration order
- * @throws GenericSignatureFormatError
- * if the generic method signature does not conform to the format
- * specified in
- * <cite>The Java&trade; Virtual Machine Specification</cite>
- * @throws TypeNotPresentException if any of the parameter
- * types of the underlying method refers to a non-existent type
- * declaration
- * @throws MalformedParameterizedTypeException if any of
- * the underlying method's parameter types refer to a parameterized
- * type that cannot be instantiated for any reason
- * @since 1.5
- */
- public Type[] getGenericParameterTypes() {
- if (getSignature() != null)
- return getGenericInfo().getParameterTypes();
- else
- return getParameterTypes();
- }
-
-
- /**
- * Returns an array of {@code Class} objects that represent the types
- * of exceptions declared to be thrown by the underlying constructor
- * represented by this {@code Constructor} object. Returns an array of
- * length 0 if the constructor declares no exceptions in its {@code throws} clause.
- *
- * @return the exception types declared as being thrown by the
- * constructor this object represents
- */
- public Class<?>[] getExceptionTypes() {
- return (Class<?>[])exceptionTypes.clone();
- }
-
-
- /**
- * Returns an array of {@code Type} objects that represent the
- * exceptions declared to be thrown by this {@code Constructor} object.
- * Returns an array of length 0 if the underlying method declares
- * no exceptions in its {@code throws} clause.
- *
- * <p>If an exception type is a type variable or a parameterized
- * type, it is created. Otherwise, it is resolved.
- *
- * @return an array of Types that represent the exception types
- * thrown by the underlying method
- * @throws GenericSignatureFormatError
- * if the generic method signature does not conform to the format
- * specified in
- * <cite>The Java&trade; Virtual Machine Specification</cite>
- * @throws TypeNotPresentException if the underlying method's
- * {@code throws} clause refers to a non-existent type declaration
- * @throws MalformedParameterizedTypeException if
- * the underlying method's {@code throws} clause refers to a
- * parameterized type that cannot be instantiated for any reason
- * @since 1.5
- */
- public Type[] getGenericExceptionTypes() {
- Type[] result;
- if (getSignature() != null &&
- ( (result = getGenericInfo().getExceptionTypes()).length > 0 ))
- return result;
- else
- return getExceptionTypes();
- }
-
- /**
- * Compares this {@code Constructor} against the specified object.
- * Returns true if the objects are the same. Two {@code Constructor} objects are
- * the same if they were declared by the same class and have the
- * same formal parameter types.
- */
- public boolean equals(Object obj) {
- if (obj != null && obj instanceof Constructor) {
- Constructor<?> other = (Constructor<?>)obj;
- if (getDeclaringClass() == other.getDeclaringClass()) {
- /* Avoid unnecessary cloning */
- Class<?>[] params1 = parameterTypes;
- Class<?>[] params2 = other.parameterTypes;
- if (params1.length == params2.length) {
- for (int i = 0; i < params1.length; i++) {
- if (params1[i] != params2[i])
- return false;
- }
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Returns a hashcode for this {@code Constructor}. The hashcode is
- * the same as the hashcode for the underlying constructor's
- * declaring class name.
- */
- public int hashCode() {
- return getDeclaringClass().getName().hashCode();
- }
-
- /**
- * Returns a string describing this {@code Constructor}. The string is
- * formatted as the constructor access modifiers, if any,
- * followed by the fully-qualified name of the declaring class,
- * followed by a parenthesized, comma-separated list of the
- * constructor's formal parameter types. For example:
- * <pre>
- * public java.util.Hashtable(int,float)
- * </pre>
- *
- * <p>The only possible modifiers for constructors are the access
- * modifiers {@code public}, {@code protected} or
- * {@code private}. Only one of these may appear, or none if the
- * constructor has default (package) access.
- */
- public String toString() {
- try {
- StringBuffer sb = new StringBuffer();
- int mod = getModifiers() & Modifier.constructorModifiers();
- if (mod != 0) {
- sb.append(Modifier.toString(mod) + " ");
- }
- sb.append(Field.getTypeName(getDeclaringClass()));
- sb.append("(");
- Class<?>[] params = parameterTypes; // avoid clone
- for (int j = 0; j < params.length; j++) {
- sb.append(Field.getTypeName(params[j]));
- if (j < (params.length - 1))
- sb.append(",");
- }
- sb.append(")");
- Class<?>[] exceptions = exceptionTypes; // avoid clone
- if (exceptions.length > 0) {
- sb.append(" throws ");
- for (int k = 0; k < exceptions.length; k++) {
- sb.append(exceptions[k].getName());
- if (k < (exceptions.length - 1))
- sb.append(",");
- }
- }
- return sb.toString();
- } catch (Exception e) {
- return "<" + e + ">";
- }
- }
-
- /**
- * Returns a string describing this {@code Constructor},
- * including type parameters. The string is formatted as the
- * constructor access modifiers, if any, followed by an
- * angle-bracketed comma separated list of the constructor's type
- * parameters, if any, followed by the fully-qualified name of the
- * declaring class, followed by a parenthesized, comma-separated
- * list of the constructor's generic formal parameter types.
- *
- * If this constructor was declared to take a variable number of
- * arguments, instead of denoting the last parameter as
- * "<tt><i>Type</i>[]</tt>", it is denoted as
- * "<tt><i>Type</i>...</tt>".
- *
- * A space is used to separate access modifiers from one another
- * and from the type parameters or return type. If there are no
- * type parameters, the type parameter list is elided; if the type
- * parameter list is present, a space separates the list from the
- * class name. If the constructor is declared to throw
- * exceptions, the parameter list is followed by a space, followed
- * by the word "{@code throws}" followed by a
- * comma-separated list of the thrown exception types.
- *
- * <p>The only possible modifiers for constructors are the access
- * modifiers {@code public}, {@code protected} or
- * {@code private}. Only one of these may appear, or none if the
- * constructor has default (package) access.
- *
- * @return a string describing this {@code Constructor},
- * include type parameters
- *
- * @since 1.5
- */
- public String toGenericString() {
- try {
- StringBuilder sb = new StringBuilder();
- int mod = getModifiers() & Modifier.constructorModifiers();
- if (mod != 0) {
- sb.append(Modifier.toString(mod) + " ");
- }
- TypeVariable<?>[] typeparms = getTypeParameters();
- if (typeparms.length > 0) {
- boolean first = true;
- sb.append("<");
- for(TypeVariable<?> typeparm: typeparms) {
- if (!first)
- sb.append(",");
- // Class objects can't occur here; no need to test
- // and call Class.getName().
- sb.append(typeparm.toString());
- first = false;
- }
- sb.append("> ");
- }
- sb.append(Field.getTypeName(getDeclaringClass()));
- sb.append("(");
- Type[] params = getGenericParameterTypes();
- for (int j = 0; j < params.length; j++) {
- String param = (params[j] instanceof Class<?>)?
- Field.getTypeName((Class<?>)params[j]):
- (params[j].toString());
- if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
- param = param.replaceFirst("\\[\\]$", "...");
- sb.append(param);
- if (j < (params.length - 1))
- sb.append(",");
- }
- sb.append(")");
- Type[] exceptions = getGenericExceptionTypes();
- if (exceptions.length > 0) {
- sb.append(" throws ");
- for (int k = 0; k < exceptions.length; k++) {
- sb.append((exceptions[k] instanceof Class)?
- ((Class<?>)exceptions[k]).getName():
- exceptions[k].toString());
- if (k < (exceptions.length - 1))
- sb.append(",");
- }
- }
- return sb.toString();
- } catch (Exception e) {
- return "<" + e + ">";
- }
- }
-
- /**
- * Uses the constructor represented by this {@code Constructor} object to
- * create and initialize a new instance of the constructor's
- * declaring class, with the specified initialization parameters.
- * Individual parameters are automatically unwrapped to match
- * primitive formal parameters, and both primitive and reference
- * parameters are subject to method invocation conversions as necessary.
- *
- * <p>If the number of formal parameters required by the underlying constructor
- * is 0, the supplied {@code initargs} array may be of length 0 or null.
- *
- * <p>If the constructor's declaring class is an inner class in a
- * non-static context, the first argument to the constructor needs
- * to be the enclosing instance; see section 15.9.3 of
- * <cite>The Java&trade; Language Specification</cite>.
- *
- * <p>If the required access and argument checks succeed and the
- * instantiation will proceed, the constructor's declaring class
- * is initialized if it has not already been initialized.
- *
- * <p>If the constructor completes normally, returns the newly
- * created and initialized instance.
- *
- * @param initargs array of objects to be passed as arguments to
- * the constructor call; values of primitive types are wrapped in
- * a wrapper object of the appropriate type (e.g. a {@code float}
- * in a {@link java.lang.Float Float})
- *
- * @return a new object created by calling the constructor
- * this object represents
- *
- * @exception IllegalAccessException if this {@code Constructor} object
- * is enforcing Java language access control and the underlying
- * constructor is inaccessible.
- * @exception IllegalArgumentException if the number of actual
- * and formal parameters differ; if an unwrapping
- * conversion for primitive arguments fails; or if,
- * after possible unwrapping, a parameter value
- * cannot be converted to the corresponding formal
- * parameter type by a method invocation conversion; if
- * this constructor pertains to an enum type.
- * @exception InstantiationException if the class that declares the
- * underlying constructor represents an abstract class.
- * @exception InvocationTargetException if the underlying constructor
- * throws an exception.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- */
- @CallerSensitive
- public T newInstance(Object ... initargs)
- throws InstantiationException, IllegalAccessException,
- IllegalArgumentException, InvocationTargetException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, null, modifiers);
- }
- }
- if ((clazz.getModifiers() & Modifier.ENUM) != 0)
- throw new IllegalArgumentException("Cannot reflectively create enum objects");
- ConstructorAccessor ca = constructorAccessor; // read volatile
- if (ca == null) {
- ca = acquireConstructorAccessor();
- }
- return (T) ca.newInstance(initargs);
- }
-
- /**
- * Returns {@code true} if this constructor was declared to take
- * a variable number of arguments; returns {@code false}
- * otherwise.
- *
- * @return {@code true} if an only if this constructor was declared to
- * take a variable number of arguments.
- * @since 1.5
- */
- public boolean isVarArgs() {
- return (getModifiers() & Modifier.VARARGS) != 0;
- }
-
- /**
- * Returns {@code true} if this constructor is a synthetic
- * constructor; returns {@code false} otherwise.
- *
- * @return true if and only if this constructor is a synthetic
- * constructor as defined by
- * <cite>The Java&trade; Language Specification</cite>.
- * @since 1.5
- */
- public boolean isSynthetic() {
- return Modifier.isSynthetic(getModifiers());
- }
-
- // NOTE that there is no synchronization used here. It is correct
- // (though not efficient) to generate more than one
- // ConstructorAccessor for a given Constructor. However, avoiding
- // synchronization will probably make the implementation more
- // scalable.
- private ConstructorAccessor acquireConstructorAccessor() {
- // First check to see if one has been created yet, and take it
- // if so.
- ConstructorAccessor tmp = null;
- if (root != null) tmp = root.getConstructorAccessor();
- if (tmp != null) {
- constructorAccessor = tmp;
- } else {
- // Otherwise fabricate one and propagate it up to the root
- tmp = reflectionFactory.newConstructorAccessor(this);
- setConstructorAccessor(tmp);
- }
-
- return tmp;
- }
-
- // Returns ConstructorAccessor for this Constructor object, not
- // looking up the chain to the root
- ConstructorAccessor getConstructorAccessor() {
- return constructorAccessor;
- }
-
- // Sets the ConstructorAccessor for this Constructor object and
- // (recursively) its root
- void setConstructorAccessor(ConstructorAccessor accessor) {
- constructorAccessor = accessor;
- // Propagate up
- if (root != null) {
- root.setConstructorAccessor(accessor);
- }
- }
-
- int getSlot() {
- return slot;
- }
-
- String getSignature() {
- return signature;
- }
-
- byte[] getRawAnnotations() {
- return null;
- }
-
- byte[] getRawParameterAnnotations() {
- return null;
- }
-
- /**
- * @throws NullPointerException {@inheritDoc}
- * @since 1.5
- */
- public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
- if (annotationClass == null)
- throw new NullPointerException();
-
- return (T) declaredAnnotations().get(annotationClass);
- }
-
- private static final Annotation[] EMPTY_ANNOTATION_ARRAY=new Annotation[0];
-
- /**
- * @since 1.5
- */
- public Annotation[] getDeclaredAnnotations() {
- return declaredAnnotations().values().toArray(EMPTY_ANNOTATION_ARRAY);
- }
-
- private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
-
- private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
- if (declaredAnnotations == null) {
- declaredAnnotations = Method.getDeclaredAnnotationsImpl(this);
- }
- return declaredAnnotations;
- }
-
- /**
- * Returns an array of arrays that represent the annotations on the formal
- * parameters, in declaration order, of the method represented by
- * this {@code Constructor} object. (Returns an array of length zero if the
- * underlying method is parameterless. If the method has one or more
- * parameters, a nested array of length zero is returned for each parameter
- * with no annotations.) The annotation objects contained in the returned
- * arrays are serializable. The caller of this method is free to modify
- * the returned arrays; it will have no effect on the arrays returned to
- * other callers.
- *
- * @return an array of arrays that represent the annotations on the formal
- * parameters, in declaration order, of the method represented by this
- * Constructor object
- * @since 1.5
- */
- public Annotation[][] getParameterAnnotations() {
- int numParameters = parameterTypes.length;
- Annotation[][] result = Method.getParameterAnnotationsImpl(this);
- if (result == null)
- return new Annotation[numParameters][0];
- if (result.length != numParameters) {
- Class<?> declaringClass = getDeclaringClass();
- if (declaringClass.isEnum() ||
- declaringClass.isAnonymousClass() ||
- declaringClass.isLocalClass() )
- ; // Can't do reliable parameter counting
- else {
- if (!declaringClass.isMemberClass() || // top-level
- // Check for the enclosing instance parameter for
- // non-static member classes
- (declaringClass.isMemberClass() &&
- ((declaringClass.getModifiers() & Modifier.STATIC) == 0) &&
- result.length + 1 != numParameters) ) {
- throw new AnnotationFormatError(
- "Parameter annotations don't match number of parameters");
- }
- }
- }
- return result;
- }
-}
diff --git a/openjdk/java/lang/reflect/Field.java b/openjdk/java/lang/reflect/Field.java
deleted file mode 100644
index b2cb46b3..00000000
--- a/openjdk/java/lang/reflect/Field.java
+++ /dev/null
@@ -1,1134 +0,0 @@
-/*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.reflect;
-
-import sun.reflect.CallerSensitive;
-import sun.reflect.FieldAccessor;
-import sun.reflect.Reflection;
-import sun.reflect.generics.repository.FieldRepository;
-import sun.reflect.generics.factory.CoreReflectionFactory;
-import sun.reflect.generics.factory.GenericsFactory;
-import sun.reflect.generics.scope.ClassScope;
-import java.lang.annotation.Annotation;
-import java.util.Map;
-import sun.reflect.annotation.AnnotationParser;
-
-
-/**
- * A {@code Field} provides information about, and dynamic access to, a
- * single field of a class or an interface. The reflected field may
- * be a class (static) field or an instance field.
- *
- * <p>A {@code Field} permits widening conversions to occur during a get or
- * set access operation, but throws an {@code IllegalArgumentException} if a
- * narrowing conversion would occur.
- *
- * @see Member
- * @see java.lang.Class
- * @see java.lang.Class#getFields()
- * @see java.lang.Class#getField(String)
- * @see java.lang.Class#getDeclaredFields()
- * @see java.lang.Class#getDeclaredField(String)
- *
- * @author Kenneth Russell
- * @author Nakul Saraiya
- */
-public final
-class Field extends AccessibleObject implements Member {
-
- private Class<?> clazz;
- private int slot;
- // This is guaranteed to be interned by the VM in the 1.4
- // reflection implementation
- private String name;
- private Class<?> type;
- private int modifiers;
- // Generics and annotations support
- private transient String signature;
- // generic info repository; lazily initialized
- private transient FieldRepository genericInfo;
- // Cached field accessor created without override
- private FieldAccessor fieldAccessor;
- // Cached field accessor created with override
- private FieldAccessor overrideFieldAccessor;
- // For sharing of FieldAccessors. This branching structure is
- // currently only two levels deep (i.e., one root Field and
- // potentially many Field objects pointing to it.)
- private Field root;
-
- // Generics infrastructure
-
- private String getGenericSignature() {return signature;}
-
- // Accessor for factory
- private GenericsFactory getFactory() {
- Class<?> c = getDeclaringClass();
- // create scope and factory
- return CoreReflectionFactory.make(c, ClassScope.make(c));
- }
-
- // Accessor for generic info repository
- private FieldRepository getGenericInfo() {
- // lazily initialize repository if necessary
- if (genericInfo == null) {
- // create and cache generic info repository
- genericInfo = FieldRepository.make(getGenericSignature(),
- getFactory());
- }
- return genericInfo; //return cached repository
- }
-
-
- /**
- * Package-private constructor used by ReflectAccess to enable
- * instantiation of these objects in Java code from the java.lang
- * package via sun.reflect.LangReflectAccess.
- */
- Field(Class<?> declaringClass,
- String name,
- Class<?> type,
- int modifiers,
- int slot,
- String signature,
- byte[] unused)
- {
- this.clazz = declaringClass;
- this.name = name;
- this.type = type;
- this.modifiers = modifiers;
- this.slot = slot;
- this.signature = signature;
- }
-
- /**
- * Package-private routine (exposed to java.lang.Class via
- * ReflectAccess) which returns a copy of this Field. The copy's
- * "root" field points to this Field.
- */
- Field copy() {
- // This routine enables sharing of FieldAccessor objects
- // among Field objects which refer to the same underlying
- // method in the VM. (All of this contortion is only necessary
- // because of the "accessibility" bit in AccessibleObject,
- // which implicitly requires that new java.lang.reflect
- // objects be fabricated for each reflective call on Class
- // objects.)
- Field res = new Field(clazz, name, type, modifiers, slot, signature, null);
- res.root = this;
- // Might as well eagerly propagate this if already present
- res.fieldAccessor = fieldAccessor;
- res.overrideFieldAccessor = overrideFieldAccessor;
- return res;
- }
-
- /**
- * Returns the {@code Class} object representing the class or interface
- * that declares the field represented by this {@code Field} object.
- */
- public Class<?> getDeclaringClass() {
- return clazz;
- }
-
- /**
- * Returns the name of the field represented by this {@code Field} object.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns the Java language modifiers for the field represented
- * by this {@code Field} object, as an integer. The {@code Modifier} class should
- * be used to decode the modifiers.
- *
- * @see Modifier
- */
- public int getModifiers() {
- return modifiers;
- }
-
- /**
- * Returns {@code true} if this field represents an element of
- * an enumerated type; returns {@code false} otherwise.
- *
- * @return {@code true} if and only if this field represents an element of
- * an enumerated type.
- * @since 1.5
- */
- public boolean isEnumConstant() {
- return (getModifiers() & Modifier.ENUM) != 0;
- }
-
- /**
- * Returns {@code true} if this field is a synthetic
- * field; returns {@code false} otherwise.
- *
- * @return true if and only if this field is a synthetic
- * field as defined by the Java Language Specification.
- * @since 1.5
- */
- public boolean isSynthetic() {
- return Modifier.isSynthetic(getModifiers());
- }
-
- /**
- * Returns a {@code Class} object that identifies the
- * declared type for the field represented by this
- * {@code Field} object.
- *
- * @return a {@code Class} object identifying the declared
- * type of the field represented by this object
- */
- public Class<?> getType() {
- return type;
- }
-
- /**
- * Returns a {@code Type} object that represents the declared type for
- * the field represented by this {@code Field} object.
- *
- * <p>If the {@code Type} is a parameterized type, the
- * {@code Type} object returned must accurately reflect the
- * actual type parameters used in the source code.
- *
- * <p>If the type of the underlying field is a type variable or a
- * parameterized type, it is created. Otherwise, it is resolved.
- *
- * @return a {@code Type} object that represents the declared type for
- * the field represented by this {@code Field} object
- * @throws GenericSignatureFormatError if the generic field
- * signature does not conform to the format specified in
- * <cite>The Java&trade; Virtual Machine Specification</cite>
- * @throws TypeNotPresentException if the generic type
- * signature of the underlying field refers to a non-existent
- * type declaration
- * @throws MalformedParameterizedTypeException if the generic
- * signature of the underlying field refers to a parameterized type
- * that cannot be instantiated for any reason
- * @since 1.5
- */
- public Type getGenericType() {
- if (getGenericSignature() != null)
- return getGenericInfo().getGenericType();
- else
- return getType();
- }
-
-
- /**
- * Compares this {@code Field} against the specified object. Returns
- * true if the objects are the same. Two {@code Field} objects are the same if
- * they were declared by the same class and have the same name
- * and type.
- */
- public boolean equals(Object obj) {
- if (obj != null && obj instanceof Field) {
- Field other = (Field)obj;
- return (getDeclaringClass() == other.getDeclaringClass())
- && (getName() == other.getName())
- && (getType() == other.getType());
- }
- return false;
- }
-
- /**
- * Returns a hashcode for this {@code Field}. This is computed as the
- * exclusive-or of the hashcodes for the underlying field's
- * declaring class name and its name.
- */
- public int hashCode() {
- return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
- }
-
- /**
- * Returns a string describing this {@code Field}. The format is
- * the access modifiers for the field, if any, followed
- * by the field type, followed by a space, followed by
- * the fully-qualified name of the class declaring the field,
- * followed by a period, followed by the name of the field.
- * For example:
- * <pre>
- * public static final int java.lang.Thread.MIN_PRIORITY
- * private int java.io.FileDescriptor.fd
- * </pre>
- *
- * <p>The modifiers are placed in canonical order as specified by
- * "The Java Language Specification". This is {@code public},
- * {@code protected} or {@code private} first, and then other
- * modifiers in the following order: {@code static}, {@code final},
- * {@code transient}, {@code volatile}.
- */
- public String toString() {
- int mod = getModifiers();
- return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
- + getTypeName(getType()) + " "
- + getTypeName(getDeclaringClass()) + "."
- + getName());
- }
-
- /**
- * Returns a string describing this {@code Field}, including
- * its generic type. The format is the access modifiers for the
- * field, if any, followed by the generic field type, followed by
- * a space, followed by the fully-qualified name of the class
- * declaring the field, followed by a period, followed by the name
- * of the field.
- *
- * <p>The modifiers are placed in canonical order as specified by
- * "The Java Language Specification". This is {@code public},
- * {@code protected} or {@code private} first, and then other
- * modifiers in the following order: {@code static}, {@code final},
- * {@code transient}, {@code volatile}.
- *
- * @return a string describing this {@code Field}, including
- * its generic type
- *
- * @since 1.5
- */
- public String toGenericString() {
- int mod = getModifiers();
- Type fieldType = getGenericType();
- return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
- + ((fieldType instanceof Class) ?
- getTypeName((Class)fieldType): fieldType.toString())+ " "
- + getTypeName(getDeclaringClass()) + "."
- + getName());
- }
-
- /**
- * Returns the value of the field represented by this {@code Field}, on
- * the specified object. The value is automatically wrapped in an
- * object if it has a primitive type.
- *
- * <p>The underlying field's value is obtained as follows:
- *
- * <p>If the underlying field is a static field, the {@code obj} argument
- * is ignored; it may be null.
- *
- * <p>Otherwise, the underlying field is an instance field. If the
- * specified {@code obj} argument is null, the method throws a
- * {@code NullPointerException}. If the specified object is not an
- * instance of the class or interface declaring the underlying
- * field, the method throws an {@code IllegalArgumentException}.
- *
- * <p>If this {@code Field} object is enforcing Java language access control, and
- * the underlying field is inaccessible, the method throws an
- * {@code IllegalAccessException}.
- * If the underlying field is static, the class that declared the
- * field is initialized if it has not already been initialized.
- *
- * <p>Otherwise, the value is retrieved from the underlying instance
- * or static field. If the field has a primitive type, the value
- * is wrapped in an object before being returned, otherwise it is
- * returned as is.
- *
- * <p>If the field is hidden in the type of {@code obj},
- * the field's value is obtained according to the preceding rules.
- *
- * @param obj object from which the represented field's value is
- * to be extracted
- * @return the value of the represented field in object
- * {@code obj}; primitive values are wrapped in an appropriate
- * object before being returned
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is inaccessible.
- * @exception IllegalArgumentException if the specified object is not an
- * instance of the class or interface declaring the underlying
- * field (or a subclass or implementor thereof).
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- */
- @CallerSensitive
- public Object get(Object obj)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- return getFieldAccessor(obj).get(obj);
- }
-
- /**
- * Gets the value of a static or instance {@code boolean} field.
- *
- * @param obj the object to extract the {@code boolean} value
- * from
- * @return the value of the {@code boolean} field
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is inaccessible.
- * @exception IllegalArgumentException if the specified object is not
- * an instance of the class or interface declaring the
- * underlying field (or a subclass or implementor
- * thereof), or if the field value cannot be
- * converted to the type {@code boolean} by a
- * widening conversion.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- * @see Field#get
- */
- @CallerSensitive
- public boolean getBoolean(Object obj)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- return getFieldAccessor(obj).getBoolean(obj);
- }
-
- /**
- * Gets the value of a static or instance {@code byte} field.
- *
- * @param obj the object to extract the {@code byte} value
- * from
- * @return the value of the {@code byte} field
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is inaccessible.
- * @exception IllegalArgumentException if the specified object is not
- * an instance of the class or interface declaring the
- * underlying field (or a subclass or implementor
- * thereof), or if the field value cannot be
- * converted to the type {@code byte} by a
- * widening conversion.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- * @see Field#get
- */
- @CallerSensitive
- public byte getByte(Object obj)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- return getFieldAccessor(obj).getByte(obj);
- }
-
- /**
- * Gets the value of a static or instance field of type
- * {@code char} or of another primitive type convertible to
- * type {@code char} via a widening conversion.
- *
- * @param obj the object to extract the {@code char} value
- * from
- * @return the value of the field converted to type {@code char}
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is inaccessible.
- * @exception IllegalArgumentException if the specified object is not
- * an instance of the class or interface declaring the
- * underlying field (or a subclass or implementor
- * thereof), or if the field value cannot be
- * converted to the type {@code char} by a
- * widening conversion.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- * @see Field#get
- */
- @CallerSensitive
- public char getChar(Object obj)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- return getFieldAccessor(obj).getChar(obj);
- }
-
- /**
- * Gets the value of a static or instance field of type
- * {@code short} or of another primitive type convertible to
- * type {@code short} via a widening conversion.
- *
- * @param obj the object to extract the {@code short} value
- * from
- * @return the value of the field converted to type {@code short}
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is inaccessible.
- * @exception IllegalArgumentException if the specified object is not
- * an instance of the class or interface declaring the
- * underlying field (or a subclass or implementor
- * thereof), or if the field value cannot be
- * converted to the type {@code short} by a
- * widening conversion.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- * @see Field#get
- */
- @CallerSensitive
- public short getShort(Object obj)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- return getFieldAccessor(obj).getShort(obj);
- }
-
- /**
- * Gets the value of a static or instance field of type
- * {@code int} or of another primitive type convertible to
- * type {@code int} via a widening conversion.
- *
- * @param obj the object to extract the {@code int} value
- * from
- * @return the value of the field converted to type {@code int}
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is inaccessible.
- * @exception IllegalArgumentException if the specified object is not
- * an instance of the class or interface declaring the
- * underlying field (or a subclass or implementor
- * thereof), or if the field value cannot be
- * converted to the type {@code int} by a
- * widening conversion.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- * @see Field#get
- */
- @CallerSensitive
- public int getInt(Object obj)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- return getFieldAccessor(obj).getInt(obj);
- }
-
- /**
- * Gets the value of a static or instance field of type
- * {@code long} or of another primitive type convertible to
- * type {@code long} via a widening conversion.
- *
- * @param obj the object to extract the {@code long} value
- * from
- * @return the value of the field converted to type {@code long}
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is inaccessible.
- * @exception IllegalArgumentException if the specified object is not
- * an instance of the class or interface declaring the
- * underlying field (or a subclass or implementor
- * thereof), or if the field value cannot be
- * converted to the type {@code long} by a
- * widening conversion.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- * @see Field#get
- */
- @CallerSensitive
- public long getLong(Object obj)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- return getFieldAccessor(obj).getLong(obj);
- }
-
- /**
- * Gets the value of a static or instance field of type
- * {@code float} or of another primitive type convertible to
- * type {@code float} via a widening conversion.
- *
- * @param obj the object to extract the {@code float} value
- * from
- * @return the value of the field converted to type {@code float}
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is inaccessible.
- * @exception IllegalArgumentException if the specified object is not
- * an instance of the class or interface declaring the
- * underlying field (or a subclass or implementor
- * thereof), or if the field value cannot be
- * converted to the type {@code float} by a
- * widening conversion.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- * @see Field#get
- */
- @CallerSensitive
- public float getFloat(Object obj)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- return getFieldAccessor(obj).getFloat(obj);
- }
-
- /**
- * Gets the value of a static or instance field of type
- * {@code double} or of another primitive type convertible to
- * type {@code double} via a widening conversion.
- *
- * @param obj the object to extract the {@code double} value
- * from
- * @return the value of the field converted to type {@code double}
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is inaccessible.
- * @exception IllegalArgumentException if the specified object is not
- * an instance of the class or interface declaring the
- * underlying field (or a subclass or implementor
- * thereof), or if the field value cannot be
- * converted to the type {@code double} by a
- * widening conversion.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- * @see Field#get
- */
- @CallerSensitive
- public double getDouble(Object obj)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- return getFieldAccessor(obj).getDouble(obj);
- }
-
- /**
- * Sets the field represented by this {@code Field} object on the
- * specified object argument to the specified new value. The new
- * value is automatically unwrapped if the underlying field has a
- * primitive type.
- *
- * <p>The operation proceeds as follows:
- *
- * <p>If the underlying field is static, the {@code obj} argument is
- * ignored; it may be null.
- *
- * <p>Otherwise the underlying field is an instance field. If the
- * specified object argument is null, the method throws a
- * {@code NullPointerException}. If the specified object argument is not
- * an instance of the class or interface declaring the underlying
- * field, the method throws an {@code IllegalArgumentException}.
- *
- * <p>If this {@code Field} object is enforcing Java language access control, and
- * the underlying field is inaccessible, the method throws an
- * {@code IllegalAccessException}.
- *
- * <p>If the underlying field is final, the method throws an
- * {@code IllegalAccessException} unless {@code setAccessible(true)}
- * has succeeded for this {@code Field} object
- * and the field is non-static. Setting a final field in this way
- * is meaningful only during deserialization or reconstruction of
- * instances of classes with blank final fields, before they are
- * made available for access by other parts of a program. Use in
- * any other context may have unpredictable effects, including cases
- * in which other parts of a program continue to use the original
- * value of this field.
- *
- * <p>If the underlying field is of a primitive type, an unwrapping
- * conversion is attempted to convert the new value to a value of
- * a primitive type. If this attempt fails, the method throws an
- * {@code IllegalArgumentException}.
- *
- * <p>If, after possible unwrapping, the new value cannot be
- * converted to the type of the underlying field by an identity or
- * widening conversion, the method throws an
- * {@code IllegalArgumentException}.
- *
- * <p>If the underlying field is static, the class that declared the
- * field is initialized if it has not already been initialized.
- *
- * <p>The field is set to the possibly unwrapped and widened new value.
- *
- * <p>If the field is hidden in the type of {@code obj},
- * the field's value is set according to the preceding rules.
- *
- * @param obj the object whose field should be modified
- * @param value the new value for the field of {@code obj}
- * being modified
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is either inaccessible or final.
- * @exception IllegalArgumentException if the specified object is not an
- * instance of the class or interface declaring the underlying
- * field (or a subclass or implementor thereof),
- * or if an unwrapping conversion fails.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- */
- @CallerSensitive
- public void set(Object obj, Object value)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- getFieldAccessor(obj).set(obj, value);
- }
-
- /**
- * Sets the value of a field as a {@code boolean} on the specified object.
- * This method is equivalent to
- * {@code set(obj, zObj)},
- * where {@code zObj} is a {@code Boolean} object and
- * {@code zObj.booleanValue() == z}.
- *
- * @param obj the object whose field should be modified
- * @param z the new value for the field of {@code obj}
- * being modified
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is either inaccessible or final.
- * @exception IllegalArgumentException if the specified object is not an
- * instance of the class or interface declaring the underlying
- * field (or a subclass or implementor thereof),
- * or if an unwrapping conversion fails.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- * @see Field#set
- */
- @CallerSensitive
- public void setBoolean(Object obj, boolean z)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- getFieldAccessor(obj).setBoolean(obj, z);
- }
-
- /**
- * Sets the value of a field as a {@code byte} on the specified object.
- * This method is equivalent to
- * {@code set(obj, bObj)},
- * where {@code bObj} is a {@code Byte} object and
- * {@code bObj.byteValue() == b}.
- *
- * @param obj the object whose field should be modified
- * @param b the new value for the field of {@code obj}
- * being modified
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is either inaccessible or final.
- * @exception IllegalArgumentException if the specified object is not an
- * instance of the class or interface declaring the underlying
- * field (or a subclass or implementor thereof),
- * or if an unwrapping conversion fails.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- * @see Field#set
- */
- @CallerSensitive
- public void setByte(Object obj, byte b)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- getFieldAccessor(obj).setByte(obj, b);
- }
-
- /**
- * Sets the value of a field as a {@code char} on the specified object.
- * This method is equivalent to
- * {@code set(obj, cObj)},
- * where {@code cObj} is a {@code Character} object and
- * {@code cObj.charValue() == c}.
- *
- * @param obj the object whose field should be modified
- * @param c the new value for the field of {@code obj}
- * being modified
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is either inaccessible or final.
- * @exception IllegalArgumentException if the specified object is not an
- * instance of the class or interface declaring the underlying
- * field (or a subclass or implementor thereof),
- * or if an unwrapping conversion fails.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- * @see Field#set
- */
- @CallerSensitive
- public void setChar(Object obj, char c)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- getFieldAccessor(obj).setChar(obj, c);
- }
-
- /**
- * Sets the value of a field as a {@code short} on the specified object.
- * This method is equivalent to
- * {@code set(obj, sObj)},
- * where {@code sObj} is a {@code Short} object and
- * {@code sObj.shortValue() == s}.
- *
- * @param obj the object whose field should be modified
- * @param s the new value for the field of {@code obj}
- * being modified
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is either inaccessible or final.
- * @exception IllegalArgumentException if the specified object is not an
- * instance of the class or interface declaring the underlying
- * field (or a subclass or implementor thereof),
- * or if an unwrapping conversion fails.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- * @see Field#set
- */
- @CallerSensitive
- public void setShort(Object obj, short s)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- getFieldAccessor(obj).setShort(obj, s);
- }
-
- /**
- * Sets the value of a field as an {@code int} on the specified object.
- * This method is equivalent to
- * {@code set(obj, iObj)},
- * where {@code iObj} is a {@code Integer} object and
- * {@code iObj.intValue() == i}.
- *
- * @param obj the object whose field should be modified
- * @param i the new value for the field of {@code obj}
- * being modified
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is either inaccessible or final.
- * @exception IllegalArgumentException if the specified object is not an
- * instance of the class or interface declaring the underlying
- * field (or a subclass or implementor thereof),
- * or if an unwrapping conversion fails.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- * @see Field#set
- */
- @CallerSensitive
- public void setInt(Object obj, int i)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- getFieldAccessor(obj).setInt(obj, i);
- }
-
- /**
- * Sets the value of a field as a {@code long} on the specified object.
- * This method is equivalent to
- * {@code set(obj, lObj)},
- * where {@code lObj} is a {@code Long} object and
- * {@code lObj.longValue() == l}.
- *
- * @param obj the object whose field should be modified
- * @param l the new value for the field of {@code obj}
- * being modified
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is either inaccessible or final.
- * @exception IllegalArgumentException if the specified object is not an
- * instance of the class or interface declaring the underlying
- * field (or a subclass or implementor thereof),
- * or if an unwrapping conversion fails.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- * @see Field#set
- */
- @CallerSensitive
- public void setLong(Object obj, long l)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- getFieldAccessor(obj).setLong(obj, l);
- }
-
- /**
- * Sets the value of a field as a {@code float} on the specified object.
- * This method is equivalent to
- * {@code set(obj, fObj)},
- * where {@code fObj} is a {@code Float} object and
- * {@code fObj.floatValue() == f}.
- *
- * @param obj the object whose field should be modified
- * @param f the new value for the field of {@code obj}
- * being modified
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is either inaccessible or final.
- * @exception IllegalArgumentException if the specified object is not an
- * instance of the class or interface declaring the underlying
- * field (or a subclass or implementor thereof),
- * or if an unwrapping conversion fails.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- * @see Field#set
- */
- @CallerSensitive
- public void setFloat(Object obj, float f)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- getFieldAccessor(obj).setFloat(obj, f);
- }
-
- /**
- * Sets the value of a field as a {@code double} on the specified object.
- * This method is equivalent to
- * {@code set(obj, dObj)},
- * where {@code dObj} is a {@code Double} object and
- * {@code dObj.doubleValue() == d}.
- *
- * @param obj the object whose field should be modified
- * @param d the new value for the field of {@code obj}
- * being modified
- *
- * @exception IllegalAccessException if this {@code Field} object
- * is enforcing Java language access control and the underlying
- * field is either inaccessible or final.
- * @exception IllegalArgumentException if the specified object is not an
- * instance of the class or interface declaring the underlying
- * field (or a subclass or implementor thereof),
- * or if an unwrapping conversion fails.
- * @exception NullPointerException if the specified object is null
- * and the field is an instance field.
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails.
- * @see Field#set
- */
- @CallerSensitive
- public void setDouble(Object obj, double d)
- throws IllegalArgumentException, IllegalAccessException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
- }
- }
- getFieldAccessor(obj).setDouble(obj, d);
- }
-
- // security check is done before calling this method
- private FieldAccessor getFieldAccessor(Object obj)
- throws IllegalAccessException
- {
- boolean ov = override;
- FieldAccessor a = (ov) ? overrideFieldAccessor : fieldAccessor;
- return (a != null) ? a : acquireFieldAccessor(ov);
- }
-
- // NOTE that there is no synchronization used here. It is correct
- // (though not efficient) to generate more than one FieldAccessor
- // for a given Field. However, avoiding synchronization will
- // probably make the implementation more scalable.
- private FieldAccessor acquireFieldAccessor(boolean overrideFinalCheck) {
- // First check to see if one has been created yet, and take it
- // if so
- FieldAccessor tmp = null;
- if (root != null) tmp = root.getFieldAccessor(overrideFinalCheck);
- if (tmp != null) {
- if (overrideFinalCheck)
- overrideFieldAccessor = tmp;
- else
- fieldAccessor = tmp;
- } else {
- // Otherwise fabricate one and propagate it up to the root
- tmp = reflectionFactory.newFieldAccessor(this, overrideFinalCheck);
- setFieldAccessor(tmp, overrideFinalCheck);
- }
-
- return tmp;
- }
-
- // Returns FieldAccessor for this Field object, not looking up
- // the chain to the root
- private FieldAccessor getFieldAccessor(boolean overrideFinalCheck) {
- return (overrideFinalCheck)? overrideFieldAccessor : fieldAccessor;
- }
-
- // Sets the FieldAccessor for this Field object and
- // (recursively) its root
- private void setFieldAccessor(FieldAccessor accessor, boolean overrideFinalCheck) {
- if (overrideFinalCheck)
- overrideFieldAccessor = accessor;
- else
- fieldAccessor = accessor;
- // Propagate up
- if (root != null) {
- root.setFieldAccessor(accessor, overrideFinalCheck);
- }
- }
-
- /*
- * Utility routine to paper over array type names
- */
- static String getTypeName(Class<?> type) {
- if (type.isArray()) {
- try {
- Class<?> cl = type;
- int dimensions = 0;
- while (cl.isArray()) {
- dimensions++;
- cl = cl.getComponentType();
- }
- StringBuffer sb = new StringBuffer();
- sb.append(cl.getName());
- for (int i = 0; i < dimensions; i++) {
- sb.append("[]");
- }
- return sb.toString();
- } catch (Throwable e) { /*FALLTHRU*/ }
- }
- return type.getName();
- }
-
- /**
- * @throws NullPointerException {@inheritDoc}
- * @since 1.5
- */
- public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
- if (annotationClass == null)
- throw new NullPointerException();
-
- return (T) declaredAnnotations().get(annotationClass);
- }
-
- private static final Annotation[] EMPTY_ANNOTATION_ARRAY=new Annotation[0];
-
- /**
- * @since 1.5
- */
- public Annotation[] getDeclaredAnnotations() {
- return declaredAnnotations().values().toArray(EMPTY_ANNOTATION_ARRAY);
- }
-
- private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
-
- private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
- if (declaredAnnotations == null) {
- declaredAnnotations = getDeclaredAnnotationsImpl();
- }
- return declaredAnnotations;
- }
-
- private native Map<Class<? extends Annotation>, Annotation> getDeclaredAnnotationsImpl();
-}
diff --git a/openjdk/java/lang/reflect/Method.java b/openjdk/java/lang/reflect/Method.java
deleted file mode 100644
index dce789a4..00000000
--- a/openjdk/java/lang/reflect/Method.java
+++ /dev/null
@@ -1,749 +0,0 @@
-/*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.reflect;
-
-import ikvm.internal.CallerID;
-import sun.reflect.CallerSensitive;
-import sun.reflect.MethodAccessor;
-import sun.reflect.Reflection;
-import sun.reflect.generics.repository.MethodRepository;
-import sun.reflect.generics.factory.CoreReflectionFactory;
-import sun.reflect.generics.factory.GenericsFactory;
-import sun.reflect.generics.scope.MethodScope;
-import sun.reflect.annotation.AnnotationType;
-import sun.reflect.annotation.AnnotationParser;
-import java.lang.annotation.Annotation;
-import java.lang.annotation.AnnotationFormatError;
-import java.nio.ByteBuffer;
-import java.util.Map;
-
-/**
- * A {@code Method} provides information about, and access to, a single method
- * on a class or interface. The reflected method may be a class method
- * or an instance method (including an abstract method).
- *
- * <p>A {@code Method} permits widening conversions to occur when matching the
- * actual parameters to invoke with the underlying method's formal
- * parameters, but it throws an {@code IllegalArgumentException} if a
- * narrowing conversion would occur.
- *
- * @see Member
- * @see java.lang.Class
- * @see java.lang.Class#getMethods()
- * @see java.lang.Class#getMethod(String, Class[])
- * @see java.lang.Class#getDeclaredMethods()
- * @see java.lang.Class#getDeclaredMethod(String, Class[])
- *
- * @author Kenneth Russell
- * @author Nakul Saraiya
- */
-public final
- class Method extends AccessibleObject implements GenericDeclaration,
- Member {
- private Class<?> clazz;
- private int slot;
- // This is guaranteed to be interned by the VM in the 1.4
- // reflection implementation
- private String name;
- private Class<?> returnType;
- private Class<?>[] parameterTypes;
- private Class<?>[] exceptionTypes;
- private int modifiers;
- // Generics and annotations support
- private transient String signature;
- // generic info repository; lazily initialized
- private transient MethodRepository genericInfo;
- private volatile MethodAccessor methodAccessor;
- // For sharing of MethodAccessors. This branching structure is
- // currently only two levels deep (i.e., one root Method and
- // potentially many Method objects pointing to it.)
- private Method root;
-
- // Generics infrastructure
-
- private String getGenericSignature() {return signature;}
-
- // Accessor for factory
- private GenericsFactory getFactory() {
- // create scope and factory
- return CoreReflectionFactory.make(this, MethodScope.make(this));
- }
-
- // Accessor for generic info repository
- private MethodRepository getGenericInfo() {
- // lazily initialize repository if necessary
- if (genericInfo == null) {
- // create and cache generic info repository
- genericInfo = MethodRepository.make(getGenericSignature(),
- getFactory());
- }
- return genericInfo; //return cached repository
- }
-
- /**
- * Package-private constructor used by ReflectAccess to enable
- * instantiation of these objects in Java code from the java.lang
- * package via sun.reflect.LangReflectAccess.
- */
- Method(Class<?> declaringClass,
- String name,
- Class<?>[] parameterTypes,
- Class<?> returnType,
- Class<?>[] checkedExceptions,
- int modifiers,
- int slot,
- String signature,
- byte[] unused1,
- byte[] unused2,
- byte[] unused3)
- {
- this.clazz = declaringClass;
- this.name = name;
- this.parameterTypes = parameterTypes;
- this.returnType = returnType;
- this.exceptionTypes = checkedExceptions;
- this.modifiers = modifiers;
- this.slot = slot;
- this.signature = signature;
- }
-
- /**
- * Package-private routine (exposed to java.lang.Class via
- * ReflectAccess) which returns a copy of this Method. The copy's
- * "root" field points to this Method.
- */
- Method copy() {
- // This routine enables sharing of MethodAccessor objects
- // among Method objects which refer to the same underlying
- // method in the VM. (All of this contortion is only necessary
- // because of the "accessibility" bit in AccessibleObject,
- // which implicitly requires that new java.lang.reflect
- // objects be fabricated for each reflective call on Class
- // objects.)
- Method res = new Method(clazz, name, parameterTypes, returnType,
- exceptionTypes, modifiers, slot, signature,
- null, null, null);
- res.root = this;
- // Might as well eagerly propagate this if already present
- res.methodAccessor = methodAccessor;
- return res;
- }
-
- /**
- * Returns the {@code Class} object representing the class or interface
- * that declares the method represented by this {@code Method} object.
- */
- public Class<?> getDeclaringClass() {
- return clazz;
- }
-
- /**
- * Returns the name of the method represented by this {@code Method}
- * object, as a {@code String}.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns the Java language modifiers for the method represented
- * by this {@code Method} object, as an integer. The {@code Modifier} class should
- * be used to decode the modifiers.
- *
- * @see Modifier
- */
- public int getModifiers() {
- return modifiers;
- }
-
- /**
- * Returns an array of {@code TypeVariable} objects that represent the
- * type variables declared by the generic declaration represented by this
- * {@code GenericDeclaration} object, in declaration order. Returns an
- * array of length 0 if the underlying generic declaration declares no type
- * variables.
- *
- * @return an array of {@code TypeVariable} objects that represent
- * the type variables declared by this generic declaration
- * @throws GenericSignatureFormatError if the generic
- * signature of this generic declaration does not conform to
- * the format specified in
- * <cite>The Java&trade; Virtual Machine Specification</cite>
- * @since 1.5
- */
- public TypeVariable<Method>[] getTypeParameters() {
- if (getGenericSignature() != null)
- return (TypeVariable<Method>[])getGenericInfo().getTypeParameters();
- else
- return (TypeVariable<Method>[])new TypeVariable[0];
- }
-
- /**
- * Returns a {@code Class} object that represents the formal return type
- * of the method represented by this {@code Method} object.
- *
- * @return the return type for the method this object represents
- */
- public Class<?> getReturnType() {
- return returnType;
- }
-
- /**
- * Returns a {@code Type} object that represents the formal return
- * type of the method represented by this {@code Method} object.
- *
- * <p>If the return type is a parameterized type,
- * the {@code Type} object returned must accurately reflect
- * the actual type parameters used in the source code.
- *
- * <p>If the return type is a type variable or a parameterized type, it
- * is created. Otherwise, it is resolved.
- *
- * @return a {@code Type} object that represents the formal return
- * type of the underlying method
- * @throws GenericSignatureFormatError
- * if the generic method signature does not conform to the format
- * specified in
- * <cite>The Java&trade; Virtual Machine Specification</cite>
- * @throws TypeNotPresentException if the underlying method's
- * return type refers to a non-existent type declaration
- * @throws MalformedParameterizedTypeException if the
- * underlying method's return typed refers to a parameterized
- * type that cannot be instantiated for any reason
- * @since 1.5
- */
- public Type getGenericReturnType() {
- if (getGenericSignature() != null) {
- return getGenericInfo().getReturnType();
- } else { return getReturnType();}
- }
-
-
- /**
- * Returns an array of {@code Class} objects that represent the formal
- * parameter types, in declaration order, of the method
- * represented by this {@code Method} object. Returns an array of length
- * 0 if the underlying method takes no parameters.
- *
- * @return the parameter types for the method this object
- * represents
- */
- public Class<?>[] getParameterTypes() {
- return (Class<?>[]) parameterTypes.clone();
- }
-
- /**
- * Returns an array of {@code Type} objects that represent the formal
- * parameter types, in declaration order, of the method represented by
- * this {@code Method} object. Returns an array of length 0 if the
- * underlying method takes no parameters.
- *
- * <p>If a formal parameter type is a parameterized type,
- * the {@code Type} object returned for it must accurately reflect
- * the actual type parameters used in the source code.
- *
- * <p>If a formal parameter type is a type variable or a parameterized
- * type, it is created. Otherwise, it is resolved.
- *
- * @return an array of Types that represent the formal
- * parameter types of the underlying method, in declaration order
- * @throws GenericSignatureFormatError
- * if the generic method signature does not conform to the format
- * specified in
- * <cite>The Java&trade; Virtual Machine Specification</cite>
- * @throws TypeNotPresentException if any of the parameter
- * types of the underlying method refers to a non-existent type
- * declaration
- * @throws MalformedParameterizedTypeException if any of
- * the underlying method's parameter types refer to a parameterized
- * type that cannot be instantiated for any reason
- * @since 1.5
- */
- public Type[] getGenericParameterTypes() {
- if (getGenericSignature() != null)
- return getGenericInfo().getParameterTypes();
- else
- return getParameterTypes();
- }
-
-
- /**
- * Returns an array of {@code Class} objects that represent
- * the types of the exceptions declared to be thrown
- * by the underlying method
- * represented by this {@code Method} object. Returns an array of length
- * 0 if the method declares no exceptions in its {@code throws} clause.
- *
- * @return the exception types declared as being thrown by the
- * method this object represents
- */
- public Class<?>[] getExceptionTypes() {
- return (Class<?>[]) exceptionTypes.clone();
- }
-
- /**
- * Returns an array of {@code Type} objects that represent the
- * exceptions declared to be thrown by this {@code Method} object.
- * Returns an array of length 0 if the underlying method declares
- * no exceptions in its {@code throws} clause.
- *
- * <p>If an exception type is a type variable or a parameterized
- * type, it is created. Otherwise, it is resolved.
- *
- * @return an array of Types that represent the exception types
- * thrown by the underlying method
- * @throws GenericSignatureFormatError
- * if the generic method signature does not conform to the format
- * specified in
- * <cite>The Java&trade; Virtual Machine Specification</cite>
- * @throws TypeNotPresentException if the underlying method's
- * {@code throws} clause refers to a non-existent type declaration
- * @throws MalformedParameterizedTypeException if
- * the underlying method's {@code throws} clause refers to a
- * parameterized type that cannot be instantiated for any reason
- * @since 1.5
- */
- public Type[] getGenericExceptionTypes() {
- Type[] result;
- if (getGenericSignature() != null &&
- ((result = getGenericInfo().getExceptionTypes()).length > 0))
- return result;
- else
- return getExceptionTypes();
- }
-
- /**
- * Compares this {@code Method} against the specified object. Returns
- * true if the objects are the same. Two {@code Methods} are the same if
- * they were declared by the same class and have the same name
- * and formal parameter types and return type.
- */
- public boolean equals(Object obj) {
- if (obj != null && obj instanceof Method) {
- Method other = (Method)obj;
- if ((getDeclaringClass() == other.getDeclaringClass())
- && (getName() == other.getName())) {
- if (!returnType.equals(other.getReturnType()))
- return false;
- /* Avoid unnecessary cloning */
- Class<?>[] params1 = parameterTypes;
- Class<?>[] params2 = other.parameterTypes;
- if (params1.length == params2.length) {
- for (int i = 0; i < params1.length; i++) {
- if (params1[i] != params2[i])
- return false;
- }
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Returns a hashcode for this {@code Method}. The hashcode is computed
- * as the exclusive-or of the hashcodes for the underlying
- * method's declaring class name and the method's name.
- */
- public int hashCode() {
- return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
- }
-
- /**
- * Returns a string describing this {@code Method}. The string is
- * formatted as the method access modifiers, if any, followed by
- * the method return type, followed by a space, followed by the
- * class declaring the method, followed by a period, followed by
- * the method name, followed by a parenthesized, comma-separated
- * list of the method's formal parameter types. If the method
- * throws checked exceptions, the parameter list is followed by a
- * space, followed by the word throws followed by a
- * comma-separated list of the thrown exception types.
- * For example:
- * <pre>
- * public boolean java.lang.Object.equals(java.lang.Object)
- * </pre>
- *
- * <p>The access modifiers are placed in canonical order as
- * specified by "The Java Language Specification". This is
- * {@code public}, {@code protected} or {@code private} first,
- * and then other modifiers in the following order:
- * {@code abstract}, {@code static}, {@code final},
- * {@code synchronized}, {@code native}, {@code strictfp}.
- */
- public String toString() {
- try {
- StringBuilder sb = new StringBuilder();
- int mod = getModifiers() & Modifier.methodModifiers();
- if (mod != 0) {
- sb.append(Modifier.toString(mod)).append(' ');
- }
- sb.append(Field.getTypeName(getReturnType())).append(' ');
- sb.append(Field.getTypeName(getDeclaringClass())).append('.');
- sb.append(getName()).append('(');
- Class<?>[] params = parameterTypes; // avoid clone
- for (int j = 0; j < params.length; j++) {
- sb.append(Field.getTypeName(params[j]));
- if (j < (params.length - 1))
- sb.append(',');
- }
- sb.append(')');
- Class<?>[] exceptions = exceptionTypes; // avoid clone
- if (exceptions.length > 0) {
- sb.append(" throws ");
- for (int k = 0; k < exceptions.length; k++) {
- sb.append(exceptions[k].getName());
- if (k < (exceptions.length - 1))
- sb.append(',');
- }
- }
- return sb.toString();
- } catch (Exception e) {
- return "<" + e + ">";
- }
- }
-
- /**
- * Returns a string describing this {@code Method}, including
- * type parameters. The string is formatted as the method access
- * modifiers, if any, followed by an angle-bracketed
- * comma-separated list of the method's type parameters, if any,
- * followed by the method's generic return type, followed by a
- * space, followed by the class declaring the method, followed by
- * a period, followed by the method name, followed by a
- * parenthesized, comma-separated list of the method's generic
- * formal parameter types.
- *
- * If this method was declared to take a variable number of
- * arguments, instead of denoting the last parameter as
- * "<tt><i>Type</i>[]</tt>", it is denoted as
- * "<tt><i>Type</i>...</tt>".
- *
- * A space is used to separate access modifiers from one another
- * and from the type parameters or return type. If there are no
- * type parameters, the type parameter list is elided; if the type
- * parameter list is present, a space separates the list from the
- * class name. If the method is declared to throw exceptions, the
- * parameter list is followed by a space, followed by the word
- * throws followed by a comma-separated list of the generic thrown
- * exception types. If there are no type parameters, the type
- * parameter list is elided.
- *
- * <p>The access modifiers are placed in canonical order as
- * specified by "The Java Language Specification". This is
- * {@code public}, {@code protected} or {@code private} first,
- * and then other modifiers in the following order:
- * {@code abstract}, {@code static}, {@code final},
- * {@code synchronized}, {@code native}, {@code strictfp}.
- *
- * @return a string describing this {@code Method},
- * include type parameters
- *
- * @since 1.5
- */
- public String toGenericString() {
- try {
- StringBuilder sb = new StringBuilder();
- int mod = getModifiers() & Modifier.methodModifiers();
- if (mod != 0) {
- sb.append(Modifier.toString(mod)).append(' ');
- }
- TypeVariable<?>[] typeparms = getTypeParameters();
- if (typeparms.length > 0) {
- boolean first = true;
- sb.append('<');
- for(TypeVariable<?> typeparm: typeparms) {
- if (!first)
- sb.append(',');
- // Class objects can't occur here; no need to test
- // and call Class.getName().
- sb.append(typeparm.toString());
- first = false;
- }
- sb.append("> ");
- }
-
- Type genRetType = getGenericReturnType();
- sb.append( ((genRetType instanceof Class<?>)?
- Field.getTypeName((Class<?>)genRetType):genRetType.toString()))
- .append(' ');
-
- sb.append(Field.getTypeName(getDeclaringClass())).append('.');
- sb.append(getName()).append('(');
- Type[] params = getGenericParameterTypes();
- for (int j = 0; j < params.length; j++) {
- String param = (params[j] instanceof Class)?
- Field.getTypeName((Class)params[j]):
- (params[j].toString());
- if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
- param = param.replaceFirst("\\[\\]$", "...");
- sb.append(param);
- if (j < (params.length - 1))
- sb.append(',');
- }
- sb.append(')');
- Type[] exceptions = getGenericExceptionTypes();
- if (exceptions.length > 0) {
- sb.append(" throws ");
- for (int k = 0; k < exceptions.length; k++) {
- sb.append((exceptions[k] instanceof Class)?
- ((Class)exceptions[k]).getName():
- exceptions[k].toString());
- if (k < (exceptions.length - 1))
- sb.append(',');
- }
- }
- return sb.toString();
- } catch (Exception e) {
- return "<" + e + ">";
- }
- }
-
- /**
- * Invokes the underlying method represented by this {@code Method}
- * object, on the specified object with the specified parameters.
- * Individual parameters are automatically unwrapped to match
- * primitive formal parameters, and both primitive and reference
- * parameters are subject to method invocation conversions as
- * necessary.
- *
- * <p>If the underlying method is static, then the specified {@code obj}
- * argument is ignored. It may be null.
- *
- * <p>If the number of formal parameters required by the underlying method is
- * 0, the supplied {@code args} array may be of length 0 or null.
- *
- * <p>If the underlying method is an instance method, it is invoked
- * using dynamic method lookup as documented in The Java Language
- * Specification, Second Edition, section 15.12.4.4; in particular,
- * overriding based on the runtime type of the target object will occur.
- *
- * <p>If the underlying method is static, the class that declared
- * the method is initialized if it has not already been initialized.
- *
- * <p>If the method completes normally, the value it returns is
- * returned to the caller of invoke; if the value has a primitive
- * type, it is first appropriately wrapped in an object. However,
- * if the value has the type of an array of a primitive type, the
- * elements of the array are <i>not</i> wrapped in objects; in
- * other words, an array of primitive type is returned. If the
- * underlying method return type is void, the invocation returns
- * null.
- *
- * @param obj the object the underlying method is invoked from
- * @param args the arguments used for the method call
- * @return the result of dispatching the method represented by
- * this object on {@code obj} with parameters
- * {@code args}
- *
- * @exception IllegalAccessException if this {@code Method} object
- * is enforcing Java language access control and the underlying
- * method is inaccessible.
- * @exception IllegalArgumentException if the method is an
- * instance method and the specified object argument
- * is not an instance of the class or interface
- * declaring the underlying method (or of a subclass
- * or implementor thereof); if the number of actual
- * and formal parameters differ; if an unwrapping
- * conversion for primitive arguments fails; or if,
- * after possible unwrapping, a parameter value
- * cannot be converted to the corresponding formal
- * parameter type by a method invocation conversion.
- * @exception InvocationTargetException if the underlying method
- * throws an exception.
- * @exception NullPointerException if the specified object is null
- * and the method is an instance method.
- * @exception ExceptionInInitializerError if the initialization
- * provoked by this method fails.
- */
- @CallerSensitive
- public Object invoke(Object obj, Object... args)
- throws IllegalAccessException, IllegalArgumentException,
- InvocationTargetException
- {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
- }
- }
- MethodAccessor ma = methodAccessor; // read volatile
- if (ma == null) {
- ma = acquireMethodAccessor();
- }
- return ma.invoke(obj, args, CallerID.getCallerID());
- }
-
- /**
- * Returns {@code true} if this method is a bridge
- * method; returns {@code false} otherwise.
- *
- * @return true if and only if this method is a bridge
- * method as defined by the Java Language Specification.
- * @since 1.5
- */
- public boolean isBridge() {
- return (getModifiers() & Modifier.BRIDGE) != 0;
- }
-
- /**
- * Returns {@code true} if this method was declared to take
- * a variable number of arguments; returns {@code false}
- * otherwise.
- *
- * @return {@code true} if an only if this method was declared to
- * take a variable number of arguments.
- * @since 1.5
- */
- public boolean isVarArgs() {
- return (getModifiers() & Modifier.VARARGS) != 0;
- }
-
- /**
- * Returns {@code true} if this method is a synthetic
- * method; returns {@code false} otherwise.
- *
- * @return true if and only if this method is a synthetic
- * method as defined by the Java Language Specification.
- * @since 1.5
- */
- public boolean isSynthetic() {
- return Modifier.isSynthetic(getModifiers());
- }
-
- // NOTE that there is no synchronization used here. It is correct
- // (though not efficient) to generate more than one MethodAccessor
- // for a given Method. However, avoiding synchronization will
- // probably make the implementation more scalable.
- private MethodAccessor acquireMethodAccessor() {
- // First check to see if one has been created yet, and take it
- // if so
- MethodAccessor tmp = null;
- if (root != null) tmp = root.getMethodAccessor();
- if (tmp != null) {
- methodAccessor = tmp;
- } else {
- // Otherwise fabricate one and propagate it up to the root
- tmp = reflectionFactory.newMethodAccessor(this);
- setMethodAccessor(tmp);
- }
-
- return tmp;
- }
-
- // Returns MethodAccessor for this Method object, not looking up
- // the chain to the root
- MethodAccessor getMethodAccessor() {
- return methodAccessor;
- }
-
- // Sets the MethodAccessor for this Method object and
- // (recursively) its root
- void setMethodAccessor(MethodAccessor accessor) {
- methodAccessor = accessor;
- // Propagate up
- if (root != null) {
- root.setMethodAccessor(accessor);
- }
- }
-
- /**
- * @throws NullPointerException {@inheritDoc}
- * @since 1.5
- */
- public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
- if (annotationClass == null)
- throw new NullPointerException();
-
- return (T) declaredAnnotations().get(annotationClass);
- }
-
- private static final Annotation[] EMPTY_ANNOTATION_ARRAY=new Annotation[0];
-
- /**
- * @since 1.5
- */
- public Annotation[] getDeclaredAnnotations() {
- return declaredAnnotations().values().toArray(EMPTY_ANNOTATION_ARRAY);
- }
-
- private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
-
- private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
- if (declaredAnnotations == null) {
- declaredAnnotations = getDeclaredAnnotationsImpl(this);
- }
- return declaredAnnotations;
- }
-
- static native Map<Class<? extends Annotation>, Annotation> getDeclaredAnnotationsImpl(Object methodOrConstructor);
-
- /**
- * Returns the default value for the annotation member represented by
- * this {@code Method} instance. If the member is of a primitive type,
- * an instance of the corresponding wrapper type is returned. Returns
- * null if no default is associated with the member, or if the method
- * instance does not represent a declared member of an annotation type.
- *
- * @return the default value for the annotation member represented
- * by this {@code Method} instance.
- * @throws TypeNotPresentException if the annotation is of type
- * {@link Class} and no definition can be found for the
- * default class value.
- * @since 1.5
- */
- public native Object getDefaultValue();
-
- /**
- * Returns an array of arrays that represent the annotations on the formal
- * parameters, in declaration order, of the method represented by
- * this {@code Method} object. (Returns an array of length zero if the
- * underlying method is parameterless. If the method has one or more
- * parameters, a nested array of length zero is returned for each parameter
- * with no annotations.) The annotation objects contained in the returned
- * arrays are serializable. The caller of this method is free to modify
- * the returned arrays; it will have no effect on the arrays returned to
- * other callers.
- *
- * @return an array of arrays that represent the annotations on the formal
- * parameters, in declaration order, of the method represented by this
- * Method object
- * @since 1.5
- */
- public Annotation[][] getParameterAnnotations() {
- Annotation[][] result = getParameterAnnotationsImpl(this);
- int numParameters = parameterTypes.length;
- if (result == null)
- return new Annotation[numParameters][0];
-
- if (result.length != numParameters)
- throw new java.lang.annotation.AnnotationFormatError(
- "Parameter annotations don't match number of parameters");
- return result;
- }
-
- static native Annotation[][] getParameterAnnotationsImpl(Object methodOrConstructor);
-}
diff --git a/openjdk/java/lang/reflect/Proxy.java b/openjdk/java/lang/reflect/Proxy.java
deleted file mode 100644
index 3d9850e0..00000000
--- a/openjdk/java/lang/reflect/Proxy.java
+++ /dev/null
@@ -1,815 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.reflect;
-
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-import java.security.AccessController;
-import java.security.Permission;
-import java.security.PrivilegedAction;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.List;
-import java.util.WeakHashMap;
-import sun.misc.ProxyGenerator;
-import sun.reflect.CallerSensitive;
-import sun.reflect.Reflection;
-import sun.reflect.misc.ReflectUtil;
-import sun.security.util.SecurityConstants;
-
-/**
- * {@code Proxy} provides static methods for creating dynamic proxy
- * classes and instances, and it is also the superclass of all
- * dynamic proxy classes created by those methods.
- *
- * <p>To create a proxy for some interface {@code Foo}:
- * <pre>
- * InvocationHandler handler = new MyInvocationHandler(...);
- * Class proxyClass = Proxy.getProxyClass(
- * Foo.class.getClassLoader(), new Class[] { Foo.class });
- * Foo f = (Foo) proxyClass.
- * getConstructor(new Class[] { InvocationHandler.class }).
- * newInstance(new Object[] { handler });
- * </pre>
- * or more simply:
- * <pre>
- * Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
- * new Class[] { Foo.class },
- * handler);
- * </pre>
- *
- * <p>A <i>dynamic proxy class</i> (simply referred to as a <i>proxy
- * class</i> below) is a class that implements a list of interfaces
- * specified at runtime when the class is created, with behavior as
- * described below.
- *
- * A <i>proxy interface</i> is such an interface that is implemented
- * by a proxy class.
- *
- * A <i>proxy instance</i> is an instance of a proxy class.
- *
- * Each proxy instance has an associated <i>invocation handler</i>
- * object, which implements the interface {@link InvocationHandler}.
- * A method invocation on a proxy instance through one of its proxy
- * interfaces will be dispatched to the {@link InvocationHandler#invoke
- * invoke} method of the instance's invocation handler, passing the proxy
- * instance, a {@code java.lang.reflect.Method} object identifying
- * the method that was invoked, and an array of type {@code Object}
- * containing the arguments. The invocation handler processes the
- * encoded method invocation as appropriate and the result that it
- * returns will be returned as the result of the method invocation on
- * the proxy instance.
- *
- * <p>A proxy class has the following properties:
- *
- * <ul>
- * <li>Proxy classes are public, final, and not abstract.
- *
- * <li>The unqualified name of a proxy class is unspecified. The space
- * of class names that begin with the string {@code "$Proxy"}
- * should be, however, reserved for proxy classes.
- *
- * <li>A proxy class extends {@code java.lang.reflect.Proxy}.
- *
- * <li>A proxy class implements exactly the interfaces specified at its
- * creation, in the same order.
- *
- * <li>If a proxy class implements a non-public interface, then it will
- * be defined in the same package as that interface. Otherwise, the
- * package of a proxy class is also unspecified. Note that package
- * sealing will not prevent a proxy class from being successfully defined
- * in a particular package at runtime, and neither will classes already
- * defined by the same class loader and the same package with particular
- * signers.
- *
- * <li>Since a proxy class implements all of the interfaces specified at
- * its creation, invoking {@code getInterfaces} on its
- * {@code Class} object will return an array containing the same
- * list of interfaces (in the order specified at its creation), invoking
- * {@code getMethods} on its {@code Class} object will return
- * an array of {@code Method} objects that include all of the
- * methods in those interfaces, and invoking {@code getMethod} will
- * find methods in the proxy interfaces as would be expected.
- *
- * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method will
- * return true if it is passed a proxy class-- a class returned by
- * {@code Proxy.getProxyClass} or the class of an object returned by
- * {@code Proxy.newProxyInstance}-- and false otherwise.
- *
- * <li>The {@code java.security.ProtectionDomain} of a proxy class
- * is the same as that of system classes loaded by the bootstrap class
- * loader, such as {@code java.lang.Object}, because the code for a
- * proxy class is generated by trusted system code. This protection
- * domain will typically be granted
- * {@code java.security.AllPermission}.
- *
- * <li>Each proxy class has one public constructor that takes one argument,
- * an implementation of the interface {@link InvocationHandler}, to set
- * the invocation handler for a proxy instance. Rather than having to use
- * the reflection API to access the public constructor, a proxy instance
- * can be also be created by calling the {@link Proxy#newProxyInstance
- * Proxy.newProxyInstance} method, which combines the actions of calling
- * {@link Proxy#getProxyClass Proxy.getProxyClass} with invoking the
- * constructor with an invocation handler.
- * </ul>
- *
- * <p>A proxy instance has the following properties:
- *
- * <ul>
- * <li>Given a proxy instance {@code proxy} and one of the
- * interfaces implemented by its proxy class {@code Foo}, the
- * following expression will return true:
- * <pre>
- * {@code proxy instanceof Foo}
- * </pre>
- * and the following cast operation will succeed (rather than throwing
- * a {@code ClassCastException}):
- * <pre>
- * {@code (Foo) proxy}
- * </pre>
- *
- * <li>Each proxy instance has an associated invocation handler, the one
- * that was passed to its constructor. The static
- * {@link Proxy#getInvocationHandler Proxy.getInvocationHandler} method
- * will return the invocation handler associated with the proxy instance
- * passed as its argument.
- *
- * <li>An interface method invocation on a proxy instance will be
- * encoded and dispatched to the invocation handler's {@link
- * InvocationHandler#invoke invoke} method as described in the
- * documentation for that method.
- *
- * <li>An invocation of the {@code hashCode},
- * {@code equals}, or {@code toString} methods declared in
- * {@code java.lang.Object} on a proxy instance will be encoded and
- * dispatched to the invocation handler's {@code invoke} method in
- * the same manner as interface method invocations are encoded and
- * dispatched, as described above. The declaring class of the
- * {@code Method} object passed to {@code invoke} will be
- * {@code java.lang.Object}. Other public methods of a proxy
- * instance inherited from {@code java.lang.Object} are not
- * overridden by a proxy class, so invocations of those methods behave
- * like they do for instances of {@code java.lang.Object}.
- * </ul>
- *
- * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3>
- *
- * <p>When two or more interfaces of a proxy class contain a method with
- * the same name and parameter signature, the order of the proxy class's
- * interfaces becomes significant. When such a <i>duplicate method</i>
- * is invoked on a proxy instance, the {@code Method} object passed
- * to the invocation handler will not necessarily be the one whose
- * declaring class is assignable from the reference type of the interface
- * that the proxy's method was invoked through. This limitation exists
- * because the corresponding method implementation in the generated proxy
- * class cannot determine which interface it was invoked through.
- * Therefore, when a duplicate method is invoked on a proxy instance,
- * the {@code Method} object for the method in the foremost interface
- * that contains the method (either directly or inherited through a
- * superinterface) in the proxy class's list of interfaces is passed to
- * the invocation handler's {@code invoke} method, regardless of the
- * reference type through which the method invocation occurred.
- *
- * <p>If a proxy interface contains a method with the same name and
- * parameter signature as the {@code hashCode}, {@code equals},
- * or {@code toString} methods of {@code java.lang.Object},
- * when such a method is invoked on a proxy instance, the
- * {@code Method} object passed to the invocation handler will have
- * {@code java.lang.Object} as its declaring class. In other words,
- * the public, non-final methods of {@code java.lang.Object}
- * logically precede all of the proxy interfaces for the determination of
- * which {@code Method} object to pass to the invocation handler.
- *
- * <p>Note also that when a duplicate method is dispatched to an
- * invocation handler, the {@code invoke} method may only throw
- * checked exception types that are assignable to one of the exception
- * types in the {@code throws} clause of the method in <i>all</i> of
- * the proxy interfaces that it can be invoked through. If the
- * {@code invoke} method throws a checked exception that is not
- * assignable to any of the exception types declared by the method in one
- * of the proxy interfaces that it can be invoked through, then an
- * unchecked {@code UndeclaredThrowableException} will be thrown by
- * the invocation on the proxy instance. This restriction means that not
- * all of the exception types returned by invoking
- * {@code getExceptionTypes} on the {@code Method} object
- * passed to the {@code invoke} method can necessarily be thrown
- * successfully by the {@code invoke} method.
- *
- * @author Peter Jones
- * @see InvocationHandler
- * @since 1.3
- */
-public class Proxy implements java.io.Serializable {
-
- private static final long serialVersionUID = -2222568056686623797L;
-
- /** prefix for all proxy class names */
- private final static String proxyClassNamePrefix = "$Proxy";
-
- /** parameter types of a proxy class constructor */
- private final static Class[] constructorParams =
- { InvocationHandler.class };
-
- /** maps a class loader to the proxy class cache for that loader */
- private static Map<ClassLoader, Map<List<String>, Object>> loaderToCache
- = new WeakHashMap<>();
-
- /** marks that a particular proxy class is currently being generated */
- private static Object pendingGenerationMarker = new Object();
-
- /** next number to use for generation of unique proxy class names */
- private static long nextUniqueNumber = 0;
- private static Object nextUniqueNumberLock = new Object();
-
- /** set of all generated proxy classes, for isProxyClass implementation */
- private static Map<Class<?>, Void> proxyClasses =
- Collections.synchronizedMap(new WeakHashMap<Class<?>, Void>());
-
- /**
- * the invocation handler for this proxy instance.
- * @serial
- */
- protected InvocationHandler h;
-
- /**
- * Prohibits instantiation.
- */
- private Proxy() {
- }
-
- /**
- * Constructs a new {@code Proxy} instance from a subclass
- * (typically, a dynamic proxy class) with the specified value
- * for its invocation handler.
- *
- * @param h the invocation handler for this proxy instance
- */
- protected Proxy(InvocationHandler h) {
- doNewInstanceCheck();
- this.h = h;
- }
-
- private static class ProxyAccessHelper {
- // The permission is implementation specific.
- static final Permission PROXY_PERMISSION =
- new ReflectPermission("proxyConstructorNewInstance");
- // These system properties are defined to provide a short-term
- // workaround if customers need to disable the new security checks.
- static final boolean allowNewInstance;
- static final boolean allowNullLoader;
- static {
- allowNewInstance = getBooleanProperty("sun.reflect.proxy.allowsNewInstance");
- allowNullLoader = getBooleanProperty("sun.reflect.proxy.allowsNullLoader");
- }
-
- private static boolean getBooleanProperty(final String key) {
- String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
- public String run() {
- return System.getProperty(key);
- }
- });
- return Boolean.valueOf(s);
- }
-
- static boolean needsNewInstanceCheck(Class<?> proxyClass) {
- if (!Proxy.isProxyClass(proxyClass) || allowNewInstance) {
- return false;
- }
-
- if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
- for (Class<?> intf : proxyClass.getInterfaces()) {
- if (!Modifier.isPublic(intf.getModifiers())) {
- return true;
- }
- }
- }
- return false;
- }
- }
-
- /*
- * Access check on a proxy class that implements any non-public interface.
- *
- * @throws SecurityException if a security manager exists, and
- * the caller does not have the permission.
- */
- private void doNewInstanceCheck() {
- SecurityManager sm = System.getSecurityManager();
- Class<?> proxyClass = this.getClass();
- if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(proxyClass)) {
- try {
- sm.checkPermission(ProxyAccessHelper.PROXY_PERMISSION);
- } catch (SecurityException e) {
- throw new SecurityException("Not allowed to construct a Proxy "
- + "instance that implements a non-public interface", e);
- }
- }
- }
-
- /**
- * Returns the {@code java.lang.Class} object for a proxy class
- * given a class loader and an array of interfaces. The proxy class
- * will be defined by the specified class loader and will implement
- * all of the supplied interfaces. If a proxy class for the same
- * permutation of interfaces has already been defined by the class
- * loader, then the existing proxy class will be returned; otherwise,
- * a proxy class for those interfaces will be generated dynamically
- * and defined by the class loader.
- *
- * <p>There are several restrictions on the parameters that may be
- * passed to {@code Proxy.getProxyClass}:
- *
- * <ul>
- * <li>All of the {@code Class} objects in the
- * {@code interfaces} array must represent interfaces, not
- * classes or primitive types.
- *
- * <li>No two elements in the {@code interfaces} array may
- * refer to identical {@code Class} objects.
- *
- * <li>All of the interface types must be visible by name through the
- * specified class loader. In other words, for class loader
- * {@code cl} and every interface {@code i}, the following
- * expression must be true:
- * <pre>
- * Class.forName(i.getName(), false, cl) == i
- * </pre>
- *
- * <li>All non-public interfaces must be in the same package;
- * otherwise, it would not be possible for the proxy class to
- * implement all of the interfaces, regardless of what package it is
- * defined in.
- *
- * <li>For any set of member methods of the specified interfaces
- * that have the same signature:
- * <ul>
- * <li>If the return type of any of the methods is a primitive
- * type or void, then all of the methods must have that same
- * return type.
- * <li>Otherwise, one of the methods must have a return type that
- * is assignable to all of the return types of the rest of the
- * methods.
- * </ul>
- *
- * <li>The resulting proxy class must not exceed any limits imposed
- * on classes by the virtual machine. For example, the VM may limit
- * the number of interfaces that a class may implement to 65535; in
- * that case, the size of the {@code interfaces} array must not
- * exceed 65535.
- * </ul>
- *
- * <p>If any of these restrictions are violated,
- * {@code Proxy.getProxyClass} will throw an
- * {@code IllegalArgumentException}. If the {@code interfaces}
- * array argument or any of its elements are {@code null}, a
- * {@code NullPointerException} will be thrown.
- *
- * <p>Note that the order of the specified proxy interfaces is
- * significant: two requests for a proxy class with the same combination
- * of interfaces but in a different order will result in two distinct
- * proxy classes.
- *
- * @param loader the class loader to define the proxy class
- * @param interfaces the list of interfaces for the proxy class
- * to implement
- * @return a proxy class that is defined in the specified class loader
- * and that implements the specified interfaces
- * @throws IllegalArgumentException if any of the restrictions on the
- * parameters that may be passed to {@code getProxyClass}
- * are violated
- * @throws NullPointerException if the {@code interfaces} array
- * argument or any of its elements are {@code null}
- */
- @CallerSensitive
- public static Class<?> getProxyClass(ClassLoader loader,
- Class<?>... interfaces)
- throws IllegalArgumentException
- {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
- }
-
- return getProxyClass0(loader, interfaces);
- }
-
- /*
- * Check permissions required to create a Proxy class.
- *
- * To define a proxy class, it performs the access checks as in
- * Class.forName (VM will invoke ClassLoader.checkPackageAccess):
- * 1. "getClassLoader" permission check if loader == null
- * 2. checkPackageAccess on the interfaces it implements
- *
- * To get a constructor and new instance of a proxy class, it performs
- * the package access check on the interfaces it implements
- * as in Class.getConstructor.
- *
- * If an interface is non-public, the proxy class must be defined by
- * the defining loader of the interface. If the caller's class loader
- * is not the same as the defining loader of the interface, the VM
- * will throw IllegalAccessError when the generated proxy class is
- * being defined via the defineClass0 method.
- */
- private static void checkProxyAccess(Class<?> caller,
- ClassLoader loader,
- Class<?>... interfaces)
- {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- ClassLoader ccl = caller.getClassLoader();
- if (loader == null && ccl != null) {
- if (!ProxyAccessHelper.allowNullLoader) {
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
- }
- ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
- }
- }
-
- /**
- * Generate a proxy class. Must call the checkProxyAccess method
- * to perform permission checks before calling this.
- */
- private static Class<?> getProxyClass0(ClassLoader loader,
- Class<?>... interfaces) {
- if (interfaces.length > 65535) {
- throw new IllegalArgumentException("interface limit exceeded");
- }
-
- Class<?> proxyClass = null;
-
- /* collect interface names to use as key for proxy class cache */
- String[] interfaceNames = new String[interfaces.length];
-
- // for detecting duplicates
- Set<Class<?>> interfaceSet = new HashSet<>();
-
- for (int i = 0; i < interfaces.length; i++) {
- /*
- * Verify that the class loader resolves the name of this
- * interface to the same Class object.
- */
- String interfaceName = interfaces[i].getName();
- Class<?> interfaceClass = null;
- try {
- interfaceClass = Class.forName(interfaceName, false, loader);
- } catch (ClassNotFoundException e) {
- }
- if (interfaceClass != interfaces[i]) {
- throw new IllegalArgumentException(
- interfaces[i] + " is not visible from class loader");
- }
-
- /*
- * Verify that the Class object actually represents an
- * interface.
- */
- if (!interfaceClass.isInterface()) {
- throw new IllegalArgumentException(
- interfaceClass.getName() + " is not an interface");
- }
-
- /*
- * Verify that this interface is not a duplicate.
- */
- if (interfaceSet.contains(interfaceClass)) {
- throw new IllegalArgumentException(
- "repeated interface: " + interfaceClass.getName());
- }
- interfaceSet.add(interfaceClass);
-
- interfaceNames[i] = interfaceName;
- }
-
- /*
- * Using string representations of the proxy interfaces as
- * keys in the proxy class cache (instead of their Class
- * objects) is sufficient because we require the proxy
- * interfaces to be resolvable by name through the supplied
- * class loader, and it has the advantage that using a string
- * representation of a class makes for an implicit weak
- * reference to the class.
- */
- List<String> key = Arrays.asList(interfaceNames);
-
- /*
- * Find or create the proxy class cache for the class loader.
- */
- Map<List<String>, Object> cache;
- synchronized (loaderToCache) {
- cache = loaderToCache.get(loader);
- if (cache == null) {
- cache = new HashMap<>();
- loaderToCache.put(loader, cache);
- }
- /*
- * This mapping will remain valid for the duration of this
- * method, without further synchronization, because the mapping
- * will only be removed if the class loader becomes unreachable.
- */
- }
-
- /*
- * Look up the list of interfaces in the proxy class cache using
- * the key. This lookup will result in one of three possible
- * kinds of values:
- * null, if there is currently no proxy class for the list of
- * interfaces in the class loader,
- * the pendingGenerationMarker object, if a proxy class for the
- * list of interfaces is currently being generated,
- * or a weak reference to a Class object, if a proxy class for
- * the list of interfaces has already been generated.
- */
- synchronized (cache) {
- /*
- * Note that we need not worry about reaping the cache for
- * entries with cleared weak references because if a proxy class
- * has been garbage collected, its class loader will have been
- * garbage collected as well, so the entire cache will be reaped
- * from the loaderToCache map.
- */
- do {
- Object value = cache.get(key);
- if (value instanceof Reference) {
- proxyClass = (Class<?>) ((Reference) value).get();
- }
- if (proxyClass != null) {
- // proxy class already generated: return it
- return proxyClass;
- } else if (value == pendingGenerationMarker) {
- // proxy class being generated: wait for it
- try {
- cache.wait();
- } catch (InterruptedException e) {
- /*
- * The class generation that we are waiting for should
- * take a small, bounded time, so we can safely ignore
- * thread interrupts here.
- */
- }
- continue;
- } else {
- /*
- * No proxy class for this list of interfaces has been
- * generated or is being generated, so we will go and
- * generate it now. Mark it as pending generation.
- */
- cache.put(key, pendingGenerationMarker);
- break;
- }
- } while (true);
- }
-
- try {
- String proxyPkg = null; // package to define proxy class in
-
- /*
- * Record the package of a non-public proxy interface so that the
- * proxy class will be defined in the same package. Verify that
- * all non-public proxy interfaces are in the same package.
- */
- for (int i = 0; i < interfaces.length; i++) {
- int flags = interfaces[i].getModifiers();
- if (!Modifier.isPublic(flags)) {
- String name = interfaces[i].getName();
- int n = name.lastIndexOf('.');
- String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
- if (proxyPkg == null) {
- proxyPkg = pkg;
- } else if (!pkg.equals(proxyPkg)) {
- throw new IllegalArgumentException(
- "non-public interfaces from different packages");
- }
- }
- }
-
- if (proxyPkg == null) {
- // if no non-public proxy interfaces, use com.sun.proxy package
- proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
- }
-
-generate: do
- {
- /*
- * Choose a name for the proxy class to generate.
- */
- long num;
- synchronized (nextUniqueNumberLock) {
- num = nextUniqueNumber++;
- }
- String proxyName = proxyPkg + proxyClassNamePrefix + num;
- /*
- * Verify that the class loader hasn't already
- * defined a class with the chosen name.
- */
-
- proxyClass = getPrecompiledProxy(loader, proxyName, interfaces);
- if (proxyClass != null)
- break generate;
-
- /*
- * Generate the specified proxy class.
- */
- byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
- proxyName, interfaces);
- try {
- proxyClass = defineClass0(loader, proxyName,
- proxyClassFile, 0, proxyClassFile.length);
- } catch (ClassFormatError e) {
- /*
- * A ClassFormatError here means that (barring bugs in the
- * proxy class generation code) there was some other
- * invalid aspect of the arguments supplied to the proxy
- * class creation (such as virtual machine limitations
- * exceeded).
- */
- throw new IllegalArgumentException(e.toString());
- }
- }
- while (false);
- // add to set of all generated proxy classes, for isProxyClass
- proxyClasses.put(proxyClass, null);
-
- } finally {
- /*
- * We must clean up the "pending generation" state of the proxy
- * class cache entry somehow. If a proxy class was successfully
- * generated, store it in the cache (with a weak reference);
- * otherwise, remove the reserved entry. In all cases, notify
- * all waiters on reserved entries in this cache.
- */
- synchronized (cache) {
- if (proxyClass != null) {
- cache.put(key, new WeakReference<Class<?>>(proxyClass));
- } else {
- cache.remove(key);
- }
- cache.notifyAll();
- }
- }
- return proxyClass;
- }
-
- /**
- * Returns an instance of a proxy class for the specified interfaces
- * that dispatches method invocations to the specified invocation
- * handler. This method is equivalent to:
- * <pre>
- * Proxy.getProxyClass(loader, interfaces).
- * getConstructor(new Class[] { InvocationHandler.class }).
- * newInstance(new Object[] { handler });
- * </pre>
- *
- * <p>{@code Proxy.newProxyInstance} throws
- * {@code IllegalArgumentException} for the same reasons that
- * {@code Proxy.getProxyClass} does.
- *
- * @param loader the class loader to define the proxy class
- * @param interfaces the list of interfaces for the proxy class
- * to implement
- * @param h the invocation handler to dispatch method invocations to
- * @return a proxy instance with the specified invocation handler of a
- * proxy class that is defined by the specified class loader
- * and that implements the specified interfaces
- * @throws IllegalArgumentException if any of the restrictions on the
- * parameters that may be passed to {@code getProxyClass}
- * are violated
- * @throws NullPointerException if the {@code interfaces} array
- * argument or any of its elements are {@code null}, or
- * if the invocation handler, {@code h}, is
- * {@code null}
- */
- @CallerSensitive
- public static Object newProxyInstance(ClassLoader loader,
- Class<?>[] interfaces,
- InvocationHandler h)
- throws IllegalArgumentException
- {
- if (h == null) {
- throw new NullPointerException();
- }
-
- final SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
- }
-
- /*
- * Look up or generate the designated proxy class.
- */
- Class<?> cl = getProxyClass0(loader, interfaces);
-
- /*
- * Invoke its constructor with the designated invocation handler.
- */
- try {
- final Constructor<?> cons = cl.getConstructor(constructorParams);
- final InvocationHandler ih = h;
- if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
- // create proxy instance with doPrivilege as the proxy class may
- // implement non-public interfaces that requires a special permission
- return AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- return newInstance(cons, ih);
- }
- });
- } else {
- return newInstance(cons, ih);
- }
- } catch (NoSuchMethodException e) {
- throw new InternalError(e.toString());
- }
- }
-
- private static Object newInstance(Constructor<?> cons, InvocationHandler h) {
- try {
- return cons.newInstance(new Object[] {h} );
- } catch (IllegalAccessException | InstantiationException e) {
- throw new InternalError(e.toString());
- } catch (InvocationTargetException e) {
- Throwable t = e.getCause();
- if (t instanceof RuntimeException) {
- throw (RuntimeException) t;
- } else {
- throw new InternalError(t.toString());
- }
- }
- }
-
- /**
- * Returns true if and only if the specified class was dynamically
- * generated to be a proxy class using the {@code getProxyClass}
- * method or the {@code newProxyInstance} method.
- *
- * <p>The reliability of this method is important for the ability
- * to use it to make security decisions, so its implementation should
- * not just test if the class in question extends {@code Proxy}.
- *
- * @param cl the class to test
- * @return {@code true} if the class is a proxy class and
- * {@code false} otherwise
- * @throws NullPointerException if {@code cl} is {@code null}
- */
- public static boolean isProxyClass(Class<?> cl) {
- if (cl == null) {
- throw new NullPointerException();
- }
-
- return proxyClasses.containsKey(cl);
- }
-
- /**
- * Returns the invocation handler for the specified proxy instance.
- *
- * @param proxy the proxy instance to return the invocation handler for
- * @return the invocation handler for the proxy instance
- * @throws IllegalArgumentException if the argument is not a
- * proxy instance
- */
- public static InvocationHandler getInvocationHandler(Object proxy)
- throws IllegalArgumentException
- {
- /*
- * Verify that the object is actually a proxy instance.
- */
- if (!isProxyClass(proxy.getClass())) {
- throw new IllegalArgumentException("not a proxy instance");
- }
-
- Proxy p = (Proxy) proxy;
- return p.h;
- }
-
- private static native Class defineClass0(ClassLoader loader, String name,
- byte[] b, int off, int len);
-
- private static native Class<?> getPrecompiledProxy(ClassLoader loader, String proxyName, Class[] interfaces);
-}
diff --git a/openjdk/java/lang/reflect/ReflectHelper.java b/openjdk/java/lang/reflect/ReflectHelper.java
deleted file mode 100644
index e0eb38cb..00000000
--- a/openjdk/java/lang/reflect/ReflectHelper.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- Copyright (C) 2007-2012 Jeroen Frijters
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jeroen Frijters
- jeroen@frijters.net
-
-*/
-
-package java.lang.reflect;
-
-@ikvm.lang.Internal
-public final class ReflectHelper
-{
- private ReflectHelper() {}
-
- public static Field copyFieldAndMakeAccessible(Field field)
- {
- field = field.copy();
- field.override = true;
- return field;
- }
-
- public static Field createFieldAndMakeAccessible(Class c, String name)
- {
- // we pass in ReflectHelper.class as the field type (which isn't used)
- // to make Field.toString() return something "meaningful" instead of crash
- Field field = new Field(c, name, ReflectHelper.class, 0, -1, null, null);
- field.override = true;
- return field;
- }
-}