summaryrefslogtreecommitdiff
path: root/libjava/classpath/vm/reference
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/vm/reference
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'libjava/classpath/vm/reference')
-rw-r--r--libjava/classpath/vm/reference/.cvsignore2
-rw-r--r--libjava/classpath/vm/reference/Makefile.am3
-rw-r--r--libjava/classpath/vm/reference/gnu/classpath/VMStackWalker.java131
-rw-r--r--libjava/classpath/vm/reference/gnu/classpath/VMSystemProperties.java97
-rw-r--r--libjava/classpath/vm/reference/gnu/classpath/jdwp/VMFrame.java135
-rw-r--r--libjava/classpath/vm/reference/gnu/classpath/jdwp/VMIdManager.java435
-rw-r--r--libjava/classpath/vm/reference/gnu/classpath/jdwp/VMMethod.java189
-rw-r--r--libjava/classpath/vm/reference/gnu/classpath/jdwp/VMVirtualMachine.java425
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/VMCPStringBuilder.java112
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/VMInstrumentationImpl.java108
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMClassLoadingMXBeanImpl.java89
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMCompilationMXBeanImpl.java66
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMGarbageCollectorMXBeanImpl.java80
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryMXBeanImpl.java156
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryManagerMXBeanImpl.java95
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryPoolMXBeanImpl.java195
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMOperatingSystemMXBeanImpl.java68
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMRuntimeMXBeanImpl.java89
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMThreadMXBeanImpl.java236
-rw-r--r--libjava/classpath/vm/reference/gnu/java/net/VMPlainDatagramSocketImpl.java260
-rw-r--r--libjava/classpath/vm/reference/gnu/java/net/VMPlainSocketImpl.java511
-rw-r--r--libjava/classpath/vm/reference/gnu/java/nio/VMChannel.java749
-rw-r--r--libjava/classpath/vm/reference/gnu/java/nio/VMPipe.java80
-rw-r--r--libjava/classpath/vm/reference/gnu/java/nio/VMSelector.java59
-rw-r--r--libjava/classpath/vm/reference/gnu/java/security/jce/prng/VMSecureRandom.java129
-rw-r--r--libjava/classpath/vm/reference/java/io/VMFile.java367
-rw-r--r--libjava/classpath/vm/reference/java/io/VMObjectInputStream.java64
-rw-r--r--libjava/classpath/vm/reference/java/io/VMObjectStreamClass.java168
-rw-r--r--libjava/classpath/vm/reference/java/lang/VMClass.java469
-rw-r--r--libjava/classpath/vm/reference/java/lang/VMClassLoader.java431
-rw-r--r--libjava/classpath/vm/reference/java/lang/VMCompiler.java112
-rw-r--r--libjava/classpath/vm/reference/java/lang/VMDouble.java115
-rw-r--r--libjava/classpath/vm/reference/java/lang/VMFloat.java118
-rw-r--r--libjava/classpath/vm/reference/java/lang/VMMath.java493
-rw-r--r--libjava/classpath/vm/reference/java/lang/VMObject.java105
-rw-r--r--libjava/classpath/vm/reference/java/lang/VMProcess.java402
-rw-r--r--libjava/classpath/vm/reference/java/lang/VMRuntime.java192
-rw-r--r--libjava/classpath/vm/reference/java/lang/VMString.java91
-rw-r--r--libjava/classpath/vm/reference/java/lang/VMSystem.java220
-rw-r--r--libjava/classpath/vm/reference/java/lang/VMThread.java461
-rw-r--r--libjava/classpath/vm/reference/java/lang/VMThrowable.java82
-rw-r--r--libjava/classpath/vm/reference/java/lang/management/VMManagementFactory.java75
-rw-r--r--libjava/classpath/vm/reference/java/lang/reflect/VMArray.java65
-rw-r--r--libjava/classpath/vm/reference/java/lang/reflect/VMConstructor.java169
-rw-r--r--libjava/classpath/vm/reference/java/lang/reflect/VMField.java549
-rw-r--r--libjava/classpath/vm/reference/java/lang/reflect/VMMethod.java208
-rw-r--r--libjava/classpath/vm/reference/java/lang/reflect/VMProxy.java135
-rw-r--r--libjava/classpath/vm/reference/java/net/VMInetAddress.java97
-rw-r--r--libjava/classpath/vm/reference/java/net/VMNetworkInterface.java131
-rw-r--r--libjava/classpath/vm/reference/java/net/VMURLConnection.java79
-rw-r--r--libjava/classpath/vm/reference/java/nio/VMDirectByteBuffer.java63
-rw-r--r--libjava/classpath/vm/reference/java/nio/channels/VMChannels.java116
-rw-r--r--libjava/classpath/vm/reference/java/security/VMAccessController.java280
-rw-r--r--libjava/classpath/vm/reference/java/security/VMSecureRandom.java129
-rw-r--r--libjava/classpath/vm/reference/java/util/VMTimeZone.java300
-rw-r--r--libjava/classpath/vm/reference/sun/misc/Unsafe.java328
-rw-r--r--libjava/classpath/vm/reference/sun/reflect/Reflection.java51
-rw-r--r--libjava/classpath/vm/reference/sun/reflect/misc/ReflectUtil.java113
58 files changed, 11277 insertions, 0 deletions
diff --git a/libjava/classpath/vm/reference/.cvsignore b/libjava/classpath/vm/reference/.cvsignore
new file mode 100644
index 000000000..282522db0
--- /dev/null
+++ b/libjava/classpath/vm/reference/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/libjava/classpath/vm/reference/Makefile.am b/libjava/classpath/vm/reference/Makefile.am
new file mode 100644
index 000000000..84b035044
--- /dev/null
+++ b/libjava/classpath/vm/reference/Makefile.am
@@ -0,0 +1,3 @@
+# used by automake to generate Makefile.in
+
+SUBDIRS = java gnu
diff --git a/libjava/classpath/vm/reference/gnu/classpath/VMStackWalker.java b/libjava/classpath/vm/reference/gnu/classpath/VMStackWalker.java
new file mode 100644
index 000000000..2214e7571
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/classpath/VMStackWalker.java
@@ -0,0 +1,131 @@
+/* VMStackWalker.java -- Reference implementation of VM hooks for stack access
+ Copyright (C) 2005, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.classpath;
+
+/**
+ * This class provides access to the classes on the Java stack
+ * for reflection and security purposes.
+ *
+ * <p>
+ * This class is only available to privileged code (i.e., code loaded
+ * by the bootstrap loader).
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Archie Cobbs
+ */
+public final class VMStackWalker
+{
+ /**
+ * Get a list of all the classes currently executing methods on the
+ * Java stack. <code>getClassContext()[0]</code> is the class associated
+ * with the currently executing method, i.e., the method that called
+ * <code>VMStackWalker.getClassContext()</code> (possibly through
+ * reflection). So you may need to pop off these stack frames from
+ * the top of the stack:
+ * <ul>
+ * <li><code>VMStackWalker.getClassContext()</code>
+ * <li><code>Method.invoke()</code>
+ * </ul>
+ *
+ * @return an array of the declaring classes of each stack frame
+ */
+ public static native Class[] getClassContext();
+
+ /**
+ * Get the class associated with the method invoking the method
+ * invoking this method, or <code>null</code> if the stack is not
+ * that deep (e.g., invoked via JNI invocation API). This method
+ * is an optimization for the expression <code>getClassContext()[1]</code>
+ * and should return the same result.
+ *
+ * <p>
+ * VM implementers are encouraged to provide a more efficient
+ * version of this method.
+ */
+ public static Class getCallingClass()
+ {
+ Class[] ctx = getClassContext();
+ if (ctx.length < 3)
+ return null;
+ return ctx[2];
+ }
+
+ /**
+ * Get the class loader associated with the Class returned by
+ * <code>getCallingClass()</code>, or <code>null</code> if no such class
+ * exists or it is the boot loader. This method is an optimization for the
+ * expression <code>VMStackWalker.getClassLoader(getClassContext()[1])</code>
+ * and should return the same result.
+ *
+ * <p>
+ * VM implementers are encouraged to provide a more efficient
+ * version of this method.
+ */
+ public static ClassLoader getCallingClassLoader()
+ {
+ Class[] ctx = getClassContext();
+ if (ctx.length < 3)
+ return null;
+ return getClassLoader(ctx[2]);
+ }
+
+ /**
+ * Retrieve the class's ClassLoader, or <code>null</code> if loaded
+ * by the bootstrap loader. I.e., this should return the same thing
+ * as {@link java.lang.VMClass#getClassLoader}. This duplicate version
+ * is here to work around access permissions.
+ */
+ public static native ClassLoader getClassLoader(Class cl);
+
+ /**
+ * Walk up the stack and return the first non-null class loader.
+ * If there aren't any non-null class loaders on the stack, return null.
+ */
+ public static ClassLoader firstNonNullClassLoader()
+ {
+ Class[] stack = getClassContext();
+ for (int i = 0; i < stack.length; i++)
+ {
+ ClassLoader loader = getClassLoader(stack[i]);
+ if (loader != null)
+ return loader;
+ }
+ return null;
+ }
+}
diff --git a/libjava/classpath/vm/reference/gnu/classpath/VMSystemProperties.java b/libjava/classpath/vm/reference/gnu/classpath/VMSystemProperties.java
new file mode 100644
index 000000000..1e0dd4e26
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/classpath/VMSystemProperties.java
@@ -0,0 +1,97 @@
+/* VMSystemProperties.java -- Allow the VM to set System properties.
+ Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.classpath;
+
+import java.util.Properties;
+
+class VMSystemProperties
+{
+ /**
+ * Get the system properties. This is done here, instead of in System,
+ * because of the bootstrap sequence. Note that the native code should
+ * not try to use the Java I/O classes yet, as they rely on the properties
+ * already existing. The only safe method to use to insert these default
+ * system properties is {@link Properties#setProperty(String, String)}.
+ *
+ * <p>These properties MUST include:
+ * <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.vm.specification.version <dd>VM Spec version
+ * <dt>java.vm.specification.vendor <dd>VM Spec vendor
+ * <dt>java.vm.specification.name <dd>VM Spec name
+ * <dt>java.vm.version <dd>VM implementation version
+ * <dt>java.vm.vendor <dd>VM implementation vendor
+ * <dt>java.vm.name <dd>VM implementation name
+ * <dt>java.specification.version <dd>Java Runtime Environment version
+ * <dt>java.specification.vendor <dd>Java Runtime Environment vendor
+ * <dt>java.specification.name <dd>Java Runtime Environment name
+ * <dt>java.class.version <dd>Java class version number
+ * <dt>java.class.path <dd>Java classpath
+ * <dt>java.library.path <dd>Path for finding Java libraries
+ * <dt>java.io.tmpdir <dd>Default temp file path
+ * <dt>java.compiler <dd>Name of JIT to use
+ * <dt>java.ext.dirs <dd>Java extension path
+ * <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
+ * <dt>gnu.cpu.endian <dd>"big" or "little"
+ * </dl>
+ *
+ * @param properties the Properties object to insert the system properties into
+ */
+ static native void preInit(Properties properties);
+
+ /**
+ * Here you get a chance to overwrite some of the properties set by
+ * the common SystemProperties code. For example, it might be
+ * a good idea to process the properties specified on the command
+ * line here.
+ */
+ static void postInit(Properties properties)
+ {
+ }
+}
diff --git a/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMFrame.java b/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMFrame.java
new file mode 100644
index 000000000..6419d3ee9
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMFrame.java
@@ -0,0 +1,135 @@
+/* VMFrame.java -- Reference implementation of VM hooks for JDWP Frame access.
+ Copyright (C) 2005, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.classpath.jdwp;
+
+import gnu.classpath.jdwp.util.Location;
+import gnu.classpath.jdwp.value.Value;
+
+/**
+ * Reference implementation of VM hooks for JDWP Frame access.
+ *
+ * @author aluchko
+ */
+
+public class VMFrame
+{
+ /**
+ * Returns the size of a frame ID over JDWP
+ */
+ public static final int SIZE = 8;
+
+ //The thread this frame resides in
+ private Thread thread;
+
+ // The object this frame resides in
+ private Object obj;
+
+ // The current location of this frame
+ private Location loc;
+
+ // id of this frame
+ private long id;
+
+ /**
+ * Create a new VMFrame object.
+ *
+ * @param thr a Thread, the thread this frame is in
+ * @param frame_id a long, the jframeID of this frame
+ * @param frame_loc a Location, the location of this frame
+ * @param frame_obj the "this" object of this frame
+ */
+ public VMFrame(Thread thr, long frame_id, Location frame_loc,
+ Object frame_obj)
+ {
+ thread = thr;
+ id = frame_id;
+ loc = frame_loc;
+ obj = frame_obj;
+ }
+
+ /**
+ * Gets the current location of the frame.
+ */
+ public Location getLocation()
+ {
+ return loc;
+ }
+
+ /**
+ * Returns the value of the variable in the given slot.
+ *
+ * @param slot the slot containing the variable
+ */
+ public native Value getValue(int slot, byte sig);
+
+ /**
+ * Assigns the given variable to the given value.
+ * @param slot The slot which contains the variable
+ * @param value The value to assign the variable to
+ */
+ public native void setValue(int slot, Value value);
+
+ /**
+ * Get the thread this frame is in.
+ */
+ public Thread getThread()
+ {
+ return thread;
+ }
+
+ /**
+ * Get the object which is represented by 'this' in the context of the frame,
+ * returns null if the method is native or static.
+ */
+ public Object getObject()
+ {
+ return obj;
+ }
+
+ /**
+ * Get the frameID
+ * @return an id which is unique within the scope of the VM
+ */
+ public long getId()
+ {
+ return id;
+ }
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMIdManager.java b/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMIdManager.java
new file mode 100644
index 000000000..ac3e05a7c
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMIdManager.java
@@ -0,0 +1,435 @@
+/* VMIdManager.java -- A reference/example implementation of a manager for
+ JDWP object/reference type IDs
+
+ Copyright (C) 2005, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.classpath.jdwp;
+
+import gnu.classpath.jdwp.exception.InvalidClassException;
+import gnu.classpath.jdwp.exception.InvalidObjectException;
+import gnu.classpath.jdwp.id.*;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Hashtable;
+
+/**
+ * This class manages objects and referencetypes that are reported
+ * to the debugger. All objects and referencetypes reported to the
+ * debugger should go through this manager.
+ *
+ * A brief summary of what an <code>IdManager</code> must provide:
+ *
+ * <code>
+ * public ObjectId getObjectId (Object theObject);
+ * public ObjectId get (long id);
+ * public ObjectId readObjectId (ByteBuffer bb);
+ * public ReferenceTypeId getReferenceTypeId (Class clazz);
+ * public ReferenceTypeId getReferenceType (long id);
+ * public ReferenceTypeId readReferenceTypeId (ByteBuffer bb);
+ * </code>
+ *
+ * See the javadoc on these methods later in this file for more
+ * information on these functions.
+ *
+ * <b>NOTE:</b> All IDs handled by the ID manager (all object and reference
+ * type IDs) are assumed to be of type <code>long</code>.
+ *
+ * <b>NOTE:</b> This class does not manage virtual machine-specific types,
+ * like methods, fields, and frames. These already have unique IDs within
+ * the virtual machine and do not need further abstraction here.
+ *
+ * @author Keith Seitz (keiths@redhat.com)
+ */
+public class VMIdManager
+{
+ // This factory generates ids for objects and types that may
+ // be sent to a debugger.
+ private static class IdFactory
+ {
+ // ID of last object / referencetype
+ private static Object _idLock = new Object ();
+ private static Object _ridLock = new Object ();
+ private static long _lastId = 0;
+ private static long _lastRid = 0;
+
+ // A list of all ID types
+ private static HashMap _idList = new HashMap ();
+
+ // Initialize the id list with known types
+ static
+ {
+ // ObjectId and ArrayId are special cases. See newObjectId.
+ _idList.put (ClassLoaderId.typeClass, ClassLoaderId.class);
+ _idList.put (ClassObjectId.typeClass, ClassObjectId.class);
+ _idList.put (StringId.typeClass, StringId.class);
+ _idList.put (ThreadId.typeClass, ThreadId.class);
+ _idList.put (ThreadGroupId.typeClass, ThreadGroupId.class);
+ }
+
+ /**
+ * Returns a new id for the given object
+ *
+ * @param obj SoftReference of the object for which an id is desired
+ * @returns a suitable object id
+ */
+ public static ObjectId newObjectId (SoftReference obj)
+ {
+ ObjectId id = null;
+ Object object = obj.get ();
+
+ // Special case: arrays
+ if (object.getClass ().isArray ())
+ id = new ArrayId ();
+ else
+ {
+ // Loop through all classes until we hit baseclass
+ Class myClass;
+ for (myClass = object.getClass (); myClass != null;
+ myClass = myClass.getSuperclass ())
+ {
+ Class clz = (Class) _idList.get (myClass);
+ if (clz != null)
+ {
+ try
+ {
+ id = (ObjectId) clz.newInstance ();
+ synchronized (_idLock)
+ {
+ id.setId (++_lastId);
+ }
+ id.setReference (obj);
+ return id;
+ }
+ catch (InstantiationException ie)
+ {
+ // This really should not happen
+ throw new RuntimeException ("cannot create new ID", ie);
+ }
+ catch (IllegalAccessException iae)
+ {
+ // This really should not happen
+ throw new RuntimeException ("illegal access of ID", iae);
+ }
+ }
+ }
+
+ /* getSuperclass returned null and no matching ID type found.
+ So it must derive from Object. */
+ id = new ObjectId ();
+ }
+
+ synchronized (_idLock)
+ {
+ id.setId (++_lastId);
+ }
+ id.setReference (obj);
+ return id;
+ }
+
+ /**
+ * Returns a new reference type id for the given class
+ *
+ * @param ref SoftReference to the desired type
+ * @returns a suitable reference type id or null when the
+ * reference is cleared.
+ */
+ public static ReferenceTypeId newReferenceTypeId (SoftReference ref)
+ {
+ ReferenceTypeId id;
+ Class clazz = (Class) ref.get ();
+ if (clazz == null)
+ return null;
+
+ if (clazz.isArray ())
+ id = new ArrayReferenceTypeId ();
+ else if (clazz.isInterface ())
+ id = new InterfaceReferenceTypeId ();
+ else
+ id = new ClassReferenceTypeId ();
+ id.setReference (ref);
+ synchronized (_ridLock)
+ {
+ id.setId (++_lastRid);
+ }
+ return id;
+ }
+ }
+
+ /**
+ * This class is a SoftReferenceIdentity type that is used by
+ * the ID manager.
+ */
+ class ReferenceKey extends SoftReference
+ {
+ // Hash code of referent
+ private int _hash;
+
+ /**
+ * Constructs a new <code>ReferenceKey</code> object
+ * with the given referent.
+ *
+ * <p>This constructor should only be used for object lookups
+ * by the backend.
+ *
+ * @param referent the object to reference
+ */
+ public ReferenceKey (Object referent)
+ {
+ super (referent);
+ _hash = referent.hashCode ();
+ }
+
+ /**
+ * Constructs a new <code>ReferenceKey</code> object
+ * with the given referent and reference queue.
+ *
+ * <p>The JDWP back-end stores a <code>ReferenceKey</code>
+ * with its corresponding <code>JdwpId</code>. This constructor
+ * is used by the back-end when adding new IDs to be managed.
+ *
+ * @param referent the object to reference
+ * @param queue the queue to which to report garbage collections
+ */
+ public ReferenceKey (Object referent, ReferenceQueue queue)
+ {
+ super (referent, queue);
+ _hash = referent.hashCode ();
+ }
+
+ /**
+ * Returns the hash code of the referent.
+ * This seems hacky, but is required in order to use this class
+ * as a hash table key.
+ *
+ * @returns the hash code of the referent
+ */
+ public int hashCode ()
+ {
+ return _hash;
+ }
+
+ /**
+ * Comparator for keys
+ *
+ * This method can be used in two ways:
+ *
+ * <ol>
+ * <li>For table lookups, where we want to compare referents</li>
+ * <li>For clearing GCd objects, where we want to compare the actual
+ * key object (not the referent)</li>
+ * </ol>
+ */
+ public boolean equals (Object obj)
+ {
+ if (obj instanceof ReferenceKey)
+ {
+ ReferenceKey ref = (ReferenceKey) obj;
+
+ /* First check if the two references are the same.
+ If they are, that means we must be clearing GCd objects. */
+ if (this == obj)
+ return true;
+
+ return (ref.get () == get ());
+ }
+
+ return false;
+ }
+ }
+
+ // instance of VMIdManager
+ private static VMIdManager _idm = new VMIdManager ();
+
+ // A reference queue for our objects
+ private ReferenceQueue _refQueue;
+
+ // Mapping of objects (ReferenceKey) to IDs (ObjectId)
+ private Hashtable _oidTable;
+
+ // Mapping of ID numbers (Long) to IDs (ObjectId)
+ private Hashtable _idTable;
+
+ /* Mapping of class (ReferenceKey) to IDs (ReferenceTypeId) for reference
+ types. Unlike other types, reference id types are NEVER released. */
+ private Hashtable _classTable;
+
+ // Mapping of ID numbers (Long) to reference type IDs (ReferenceTypeId)
+ private Hashtable _ridTable;
+
+ /**
+ * Gets the instance of VMIdManager, constructing a new one
+ * if none currently exists.
+ */
+ public static VMIdManager getDefault ()
+ {
+ return _idm;
+ }
+
+ // Constructs a new <code>IdManager</code>
+ private VMIdManager ()
+ {
+ _refQueue = new ReferenceQueue ();
+ _oidTable = new Hashtable (50);
+ _idTable = new Hashtable (50);
+ _classTable = new Hashtable (20);
+ _ridTable = new Hashtable (20);
+ }
+
+ // Updates the object ID table, removing IDs whose objects have
+ // been garbage collected.
+ private void _update ()
+ {
+ Reference ref;
+ while ((ref = _refQueue.poll ()) != null)
+ {
+ ObjectId id = (ObjectId) _oidTable.get (ref);
+ _oidTable.remove (ref);
+ _idTable.remove (new Long (id.getId ()));
+ }
+ }
+
+ /**
+ * Returns an id for the given object, adding it
+ * if it does not have an id.
+ *
+ * @param theObject the object to get an ID/add
+ * @returns the ID of the object
+ */
+ public ObjectId getObjectId (Object theObject)
+ {
+ // Special case: null
+ if (theObject == null)
+ return new NullObjectId ();
+
+ ReferenceKey ref = new ReferenceKey (theObject, _refQueue);
+ ObjectId id = (ObjectId) _oidTable.get (ref);
+ if (id == null)
+ {
+ // update the tables -- this is an arbitrary place to put this
+ _update ();
+
+ // Object not found. Make new id for it
+ id = IdFactory.newObjectId (ref);
+ _oidTable.put (ref, id);
+ _idTable.put (new Long (id.getId ()), id);
+ }
+
+ return id;
+ }
+
+ /**
+ * Returns the <code>JdwpId</code> for a given ID. Unlike
+ * <code>getId</code>, it throws an exception if the ID is not
+ * known.
+ *
+ * @param id the numerical ID of the desired <code>JdwpId</code>
+ * @throws InvalidObjectException if the ID is not found
+ */
+ public ObjectId get (long id)
+ throws InvalidObjectException
+ {
+ // Special case: null
+ if (id == 0)
+ return new NullObjectId ();
+
+ ObjectId oid = (ObjectId) _idTable.get (new Long (id));
+ if (oid == null)
+ throw new InvalidObjectException (id);
+
+ return oid;
+ }
+
+ public ObjectId readObjectId (ByteBuffer bb)
+ throws InvalidObjectException
+ {
+ long id = bb.getLong ();
+ return get (id);
+ }
+
+ /**
+ * Gets the reference type id for the given class, creating
+ * a new one if it does not already have an id
+ *
+ * @param clazz the class for which to get an ID
+ * @returns the ID of the class
+ */
+ public ReferenceTypeId getReferenceTypeId (Class clazz)
+ {
+ ReferenceKey ref = new ReferenceKey (clazz);
+ ReferenceTypeId id = (ReferenceTypeId)_classTable.get (ref);
+ if (id == null)
+ {
+ // Object not found. Make new id for it
+ id = IdFactory.newReferenceTypeId (ref);
+ _classTable.put (ref, id);
+ _ridTable.put (new Long (id.getId ()), id);
+ }
+
+ return id;
+ }
+
+ /**
+ * Returns the <code>ReferenceTypeId</code> for a given ID. Unlike
+ * <code>getReferenceTypeId</code>, it throws an exception if the ID is not
+ * known.
+ *
+ * @param id the numerical ID of the desired reference type
+ * @throws InvalidClassException if the ID is not found
+ */
+ public ReferenceTypeId getReferenceType (long id)
+ throws InvalidClassException
+ {
+ ReferenceTypeId rid = (ReferenceTypeId) _ridTable.get (new Long (id));
+ if (rid == null)
+ throw new InvalidClassException (id);
+
+ return rid;
+ }
+
+ public ReferenceTypeId readReferenceTypeId (ByteBuffer bb)
+ throws InvalidClassException
+ {
+ long id = bb.getLong ();
+ return getReferenceType (id);
+ }
+}
diff --git a/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMMethod.java b/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMMethod.java
new file mode 100644
index 000000000..8e15a48d1
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMMethod.java
@@ -0,0 +1,189 @@
+/* VMMethod.java -- a method in a virtual machine
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.classpath.jdwp;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import gnu.classpath.jdwp.exception.JdwpException;
+import gnu.classpath.jdwp.util.LineTable;
+import gnu.classpath.jdwp.util.VariableTable;
+
+/**
+ * This class is really an amalgamation of two classes: one class
+ * represents a virtual machine method and the other represents
+ * the JDWP back-end's ID for the method.
+ *
+ * @author Keith Seitz (keiths@redhat.com)
+ */
+public class VMMethod
+{
+ /**
+ * Returns the size of a JDWP method ID
+ * @see gnu.classpath.jdwp.id.JdwpId#SIZE
+ */
+ public static final int SIZE = 8;
+
+ // The class in which this method is declared
+ private Class _class;
+
+ // The method's ID
+ private long _methodId;
+
+ /**
+ * Constructs a new VMMethod object. This constructor is protected
+ * so that only the factory methods of VMVirtualMachine can be used
+ * to create VMMethods.
+ *
+ * @param klass the method's containing class
+ * @param id method identifier, e.g., jmethodID
+ * @see gnu.classpath.jdwp.VMVirtualMachine#getAllClassMethods
+ * @see gnu.classpath.jdwp.VMVirtualMachine#getClassMethod
+ */
+ protected VMMethod(Class klass, long id)
+ {
+ _class = klass;
+ _methodId = id;
+ }
+
+ /**
+ * Returns the internal method ID for this method
+ */
+ public long getId()
+ {
+ return _methodId;
+ }
+
+ /**
+ * Returns the method's declaring class
+ */
+ public Class getDeclaringClass()
+ {
+ return _class;
+ }
+
+ /**
+ * Returns the name of this method
+ */
+ public native String getName();
+
+ /**
+ * Returns the signature of this method
+ */
+ public native String getSignature();
+
+ /**
+ * Returns the method's modifier flags
+ */
+ public native int getModifiers();
+
+ /**
+ * "Returns line number information for the method, if present. The line
+ * table maps source line numbers to the initial code index of the line.
+ * The line table is ordered by code index (from lowest to highest). The
+ * line number information is constant unless a new class definition is
+ * installed using RedefineClasses."
+ *
+ * @return the line table
+ * @throws JdwpException
+ */
+ public native LineTable getLineTable()
+ throws JdwpException;
+
+ /**
+ * "Returns variable information for the method. The variable table
+ * includes arguments and locals declared within the method. For instance
+ * methods, the "this" reference is included in the table. Also, synthetic
+ * variables may be present."
+ *
+ * @return the variable table
+ * @throws JdwpException
+ */
+ public native VariableTable getVariableTable()
+ throws JdwpException;
+
+ /**
+ * Returns a string representation of this method (not
+ * required but nice for debugging).
+ */
+ public String toString()
+ {
+ return getDeclaringClass().getName() + "." + getName();
+ }
+
+ /**
+ * Writes the method's ID to the output stream
+ *
+ * @param ostream the output stream to which to write
+ * @throws IOException for any errors writing to the stream
+ * @see gnu.classpath.jdwp.id.JdwpId#write
+ */
+ public void writeId(DataOutputStream ostream)
+ throws IOException
+ {
+ ostream.writeLong(getId());
+ }
+
+ /**
+ * Returns a VMMethod from the ID in the byte buffer
+ *
+ * @param klass the method's declaring class
+ * @param bb a ByteBuffer containing the method's ID
+ * @throws JdwpException for any errors creating the method
+ * @throws IOException for any errors reading from the buffer
+ */
+ public static VMMethod readId(Class klass, ByteBuffer bb)
+ throws JdwpException, IOException
+ {
+ return VMVirtualMachine.getClassMethod(klass, bb.getLong());
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof VMMethod)
+ {
+ VMMethod m = (VMMethod) obj;
+ return (getId() == m.getId());
+ }
+
+ return false;
+ }
+}
diff --git a/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMVirtualMachine.java b/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMVirtualMachine.java
new file mode 100644
index 000000000..1f85a4a18
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMVirtualMachine.java
@@ -0,0 +1,425 @@
+/* VMVirtualMachine.java -- A reference implementation of a JDWP virtual
+ machine
+
+ Copyright (C) 2005, 2006, 2007 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.classpath.jdwp;
+
+import gnu.classpath.jdwp.event.EventRequest;
+import gnu.classpath.jdwp.exception.InvalidMethodException;
+import gnu.classpath.jdwp.exception.JdwpException;
+import gnu.classpath.jdwp.util.MethodResult;
+import gnu.classpath.jdwp.util.MonitorInfo;
+import gnu.classpath.jdwp.value.Value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * A virtual machine according to JDWP.
+ *
+ * @author Keith Seitz <keiths@redhat.com>
+ */
+public class VMVirtualMachine
+{
+ // VM Capabilities
+ public static final boolean canWatchFieldModification = false;
+ public static final boolean canWatchFieldAccess = false;
+ public static final boolean canGetBytecodes = false;
+ public static final boolean canGetSyntheticAttribute = false;
+ public static final boolean canGetOwnedMonitorInfo = false;
+ public static final boolean canGetCurrentContendedMonitor = false;
+ public static final boolean canGetMonitorInfo = false;
+ public static final boolean canRedefineClasses = false;
+ public static final boolean canAddMethod = false;
+ public static final boolean canUnrestrictedlyRedefineClasses = false;
+ public static final boolean canPopFrames = false;
+ public static final boolean canUseInstanceFilters = false;
+ public static final boolean canGetSourceDebugExtension = false;
+ public static final boolean canRequestVMDeathEvent = false;
+ public static final boolean canSetDefaultStratum = false;
+
+ /**
+ * Suspend a thread
+ *
+ * @param thread the thread to suspend
+ */
+ public static native void suspendThread(Thread thread)
+ throws JdwpException;
+
+ /**
+ * Suspend all threads
+ */
+ public static void suspendAllThreads()
+ throws JdwpException
+ {
+ // Our JDWP thread group -- don't suspend any of those threads
+ Thread current = Thread.currentThread ();
+ ThreadGroup jdwpGroup = Jdwp.getDefault().getJdwpThreadGroup();
+
+ // Find the root ThreadGroup
+ ThreadGroup group = jdwpGroup;
+ ThreadGroup parent = group.getParent ();
+ while (parent != null)
+ {
+ group = parent;
+ parent = group.getParent ();
+ }
+
+ // Get all the threads in the system
+ int num = group.activeCount ();
+ Thread[] threads = new Thread[num];
+ group.enumerate (threads);
+
+ for (int i = 0; i < num; ++i)
+ {
+ Thread t = threads[i];
+ if (t != null)
+ {
+ if (t.getThreadGroup () == jdwpGroup || t == current)
+ {
+ // Don't suspend the current thread or any JDWP thread
+ continue;
+ }
+ else
+ suspendThread (t);
+ }
+ }
+
+ // Now suspend the current thread
+ if (current.getThreadGroup() != jdwpGroup)
+ suspendThread (current);
+ }
+
+ /**
+ * Resume a thread. A thread must be resumed as many times
+ * as it has been suspended.
+ *
+ * @param thread the thread to resume
+ */
+ public static native void resumeThread(Thread thread)
+ throws JdwpException;
+
+ /**
+ * Resume all threads. This simply decrements the thread's
+ * suspend count. It can not be used to force the application
+ * to run.
+ */
+ public static void resumeAllThreads()
+ throws JdwpException
+ {
+ // Our JDWP thread group -- don't resume
+ Thread current = Thread.currentThread ();
+ ThreadGroup jdwpGroup = current.getThreadGroup ();
+
+ // Find the root ThreadGroup
+ ThreadGroup group = jdwpGroup;
+ ThreadGroup parent = group.getParent ();
+ while (parent != null)
+ {
+ group = parent;
+ parent = group.getParent ();
+ }
+
+ // Get all the threads in the system
+ int num = group.activeCount ();
+ Thread[] threads = new Thread[num];
+ group.enumerate (threads);
+
+ for (int i = 0; i < num; ++i)
+ {
+ Thread t = threads[i];
+ if (t != null)
+ {
+ if (t.getThreadGroup () == jdwpGroup || t == current)
+ {
+ // Don't resume the current thread or any JDWP thread
+ continue;
+ }
+ else
+ resumeThread (t);
+ }
+ }
+ }
+
+ /**
+ * Get the suspend count for a give thread
+ *
+ * @param thread the thread whose suspend count is desired
+ * @return the number of times the thread has been suspended
+ */
+ public static native int getSuspendCount(Thread thread)
+ throws JdwpException;
+
+ /**
+ * Returns a Collection of all classes loaded in the VM
+ */
+ public static native Collection getAllLoadedClasses()
+ throws JdwpException;
+
+ /**
+ * Returns the status of the given class
+ *
+ * @param clazz the class whose status is desired
+ * @return a flag containing the class's status
+ * @see JdwpConstants.ClassStatus
+ */
+ public static native int getClassStatus(Class clazz)
+ throws JdwpException;
+
+ /**
+ * Returns all of the methods defined in the given class. This
+ * includes all methods, constructors, and class initializers.
+ *
+ * @param klass the class whose methods are desired
+ * @return an array of virtual machine methods
+ */
+ public static native VMMethod[] getAllClassMethods(Class klass)
+ { return null; }
+
+ /**
+ * A factory method for getting valid virtual machine methods
+ * which may be passed to/from the debugger.
+ *
+ * @param klass the class in which the method is defined
+ * @param id the ID of the desired method
+ * @return the desired internal representation of the method
+ * @throws InvalidMethodException if the method is not defined
+ * in the class
+ * @throws JdwpException for any other error
+ */
+ public static native VMMethod getClassMethod(Class klass, long id)
+ { return null; }
+
+ /**
+ * Returns the thread's call stack
+ *
+ * @param thread thread for which to get call stack
+ * @param start index of first frame to return
+ * @param length number of frames to return (-1 for all frames)
+ * @return a list of frames
+ */
+ public static native ArrayList getFrames(Thread thread, int start,
+ int length)
+ throws JdwpException;
+
+ /**
+ * Returns the frame for a given thread with the frame ID in
+ * the buffer
+ *
+ * I don't like this.
+ *
+ * @param thread the frame's thread
+ * @param bb buffer containing the frame's ID
+ * @return the desired frame
+ */
+ public static native VMFrame getFrame(Thread thread, long frameID)
+ throws JdwpException;
+
+ /**
+ * Returns the number of frames in the thread's stack
+ *
+ * @param thread the thread for which to get a frame count
+ * @return the number of frames in the thread's stack
+ */
+ public static native int getFrameCount(Thread thread)
+ throws JdwpException;
+
+
+ /**
+ * Returns the status of a thread
+ *
+ * @param thread the thread for which to get status
+ * @return integer status of the thread
+ * @see JdwpConstants.ThreadStatus
+ */
+ public static native int getThreadStatus(Thread thread)
+ throws JdwpException;
+
+ /**
+ * Returns a list of all classes which this class loader has been
+ * requested to load
+ *
+ * @param cl the class loader
+ * @return a list of all visible classes
+ */
+ public static native ArrayList getLoadRequests(ClassLoader cl)
+ throws JdwpException;
+
+ /**
+ * Executes a method in the virtual machine. The thread must already
+ * be suspended by a previous event. When the method invocation is
+ * complete, the thread (or all threads if INVOKE_SINGLE_THREADED is
+ * not set in options) must be suspended before this method returns.
+ *
+ * @param obj instance in which to invoke method (null for static)
+ * @param thread the thread in which to invoke the method
+ * @param clazz the class in which the method is defined
+ * @param method the method to invoke
+ * @param values arguments to pass to method
+ * @param options invocation options
+ * @return a result object containing the results of the invocation
+ */
+ public static native MethodResult executeMethod (Object obj, Thread thread,
+ Class clazz, VMMethod method,
+ Value[] values,
+ int options)
+ throws JdwpException;
+
+ /**
+ * "Returns the name of source file in which a reference type was declared"
+ *
+ * @param clazz the class for which to return a source file
+ * @return a string containing the source file name; "no path information
+ * for the file is included"
+ */
+ public static native String getSourceFile(Class clazz)
+ throws JdwpException;
+
+ /**
+ * Register a request from the debugger
+ *
+ * Virtual machines have two options. Either do nothing and allow
+ * the event manager to take care of the request (useful for broadcast-type
+ * events like class prepare/load/unload, thread start/end, etc.)
+ * or do some internal work to set up the event notification (useful for
+ * execution-related events like breakpoints, single-stepping, etc.).
+ */
+ public static native void registerEvent(EventRequest request)
+ throws JdwpException;
+
+ /**
+ * Unregisters the given request
+ *
+ * @param request the request to unregister
+ */
+ public static native void unregisterEvent(EventRequest request)
+ throws JdwpException;
+
+
+ /**
+ * Clear all events of the given kind
+ *
+ * @param kind the type of events to clear
+ */
+ public static native void clearEvents(byte kind)
+ throws JdwpException;
+
+ /**
+ * Redefines the given types. VM must support canRedefineClasses
+ * capability (may also require canAddMethod and/or
+ * canUnrestrictedlyRedefineClasses capabilities)
+ *
+ * @param types the classes to redefine
+ * @param bytecodes the new bytecode definitions for the classes
+ */
+ public static native void redefineClasses(Class[] types, byte[][] bytecodes)
+ throws JdwpException;
+
+ /**
+ * Sets the default stratum. VM must support the
+ * canSetDefaultStratum capability.
+ *
+ * @param stratum the new default stratum or empty string to
+ * use the reference default
+ */
+ public static native void setDefaultStratum(String stratum)
+ throws JdwpException;
+
+ /**
+ * Returns the source debug extension. VM must support the
+ * canGetSourceDebugExtension capability.
+ *
+ * @param klass the class for which to return information
+ * @returns the source debug extension
+ */
+ public static native String getSourceDebugExtension(Class klass)
+ throws JdwpException;
+
+ /**
+ * Returns the bytecode for the given method. VM must support the
+ * canGetBytecodes capability.
+ *
+ * @param method the method for which to get bytecodes
+ * @returns the bytecodes
+ */
+ public static native byte[] getBytecodes(VMMethod method)
+ throws JdwpException;
+
+ /**
+ * Returns monitor information about an object. VM must support
+ * the canGetMonitorInformation capability.
+ *
+ * @param obj the object
+ * @returns monitor information (owner, entry count, waiters)
+ */
+ public static native MonitorInfo getMonitorInfo(Object obj)
+ throws JdwpException;
+
+ /**
+ * Returns a list of owned monitors. VM must support the
+ * canGetOwnedMonitorInfo capability.
+ *
+ * @param thread a thread
+ * @returns the list of monitors owned by this thread
+ */
+ public static native Object[] getOwnedMonitors(Thread thread)
+ throws JdwpException;
+
+ /**
+ * Returns the current contended monitor for a thread. VM must
+ * support canGetCurrentContendedMonitor capability.
+ *
+ * @param thread the thread
+ * @returns the contended monitor
+ */
+ public static native Object getCurrentContendedMonitor(Thread thread)
+ throws JdwpException;
+
+ /**
+ * Pop all frames up to and including the given frame. VM must
+ * support canPopFrames capability. It is the responsibility
+ * of the VM to check if the thread is suspended. If it is not,
+ * the VM should throw ThreadNotSuspendedException.
+ *
+ * @param thread the thread
+ * @param frame the frame ID
+ */
+ public static native void popFrames(Thread thread, long frameId);
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/VMCPStringBuilder.java b/libjava/classpath/vm/reference/gnu/java/lang/VMCPStringBuilder.java
new file mode 100644
index 000000000..c3a3784f3
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/VMCPStringBuilder.java
@@ -0,0 +1,112 @@
+/* VMCPStringBuilder.java -- Growable strings without locking or copying
+ Copyright (C) 2008 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * This class provides VM support for CPStringBuilder
+ * by allowing the package-private constructor
+ * of java.lang.String to be invoked. The default
+ * implementation uses reflection. VMs may replace
+ * this class with a more efficient version.
+ */
+final class VMCPStringBuilder
+{
+
+ /**
+ * The package-private constructor for String objects without copying.
+ */
+ private static final Constructor cons;
+
+ static
+ {
+ try
+ {
+ cons = String.class.getDeclaredConstructor(new Class[] { char[].class,
+ Integer.TYPE,
+ Integer.TYPE,
+ Boolean.TYPE });
+ cons.setAccessible(true);
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw (Error)
+ new InternalError("Could not get no-copy String constructor").initCause(e);
+ }
+ }
+
+ /**
+ * Convert this <code>StringBuilder</code> to a <code>String</code>. The
+ * String is composed of the characters currently in this StringBuilder. Note
+ * that the result is not a copy, so the builder will allocate a new array
+ * if a further write operation is attempted.
+ *
+ * @param value the buffered characters.
+ * @param startIndex the index at which to start taking characters from the buffer.
+ * @param count the number of characters used in the buffer.
+ * @return the characters in this StringBuilder
+ */
+ public static String toString(char[] value, int startIndex, int count)
+ {
+ try
+ {
+ return (String)
+ cons.newInstance(new Object[] { value, Integer.valueOf(startIndex),
+ Integer.valueOf(count),
+ Boolean.valueOf(true) });
+ }
+ catch (InstantiationException e)
+ {
+ throw (Error)
+ new InternalError("Could not instantiate no-copy String constructor").initCause(e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw (Error)
+ new InternalError("Could not access no-copy String constructor").initCause(e);
+ }
+ catch (InvocationTargetException e)
+ {
+ throw (Error)
+ new InternalError("Error calling no-copy String constructor").initCause(e);
+ }
+ }
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/VMInstrumentationImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/VMInstrumentationImpl.java
new file mode 100644
index 000000000..5501f0f7f
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/VMInstrumentationImpl.java
@@ -0,0 +1,108 @@
+/* VMInstrumentationImpl.java -- interface for the GNU implementation
+ of InstrumentationImpl
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.lang;
+
+import java.lang.instrument.ClassDefinition;
+import java.lang.instrument.Instrumentation;
+
+/**
+ * @author Nicolas Geoffray (nicolas.geoffray@menlina.com)
+ * @since 1.5
+ */
+final class VMInstrumentationImpl
+{
+
+ /**
+ * Returns if the current JVM supports class redefinition
+ *
+ * @return true if the current JVM supports class redefinition
+ */
+ static native boolean isRedefineClassesSupported();
+
+ /**
+ * Redefines classes given as parameters. The method has to call
+ * the callTransformers from InstrumentationImpl
+ *
+ * @param inst an instrumentation object
+ * @param definitions an array of bytecode<->class correspondance
+ *
+ * @throws ClassNotFoundException if a class cannot be found
+ * @throws UnmodifiableClassException if a class cannot be modified
+ * @throws UnsupportedOperationException if the JVM does not support
+ * redefinition or the redefinition made unsupported changes
+ * @throws ClassFormatError if a class file is not valid
+ * @throws NoClassDefFoundError if a class name is not equal to the name
+ * in the class file specified
+ * @throws UnsupportedClassVersionError if the class file version numbers
+ * are unsupported
+ * @throws ClassCircularityError if circularity occured with the new
+ * classes
+ * @throws LinkageError if a linkage error occurs
+ */
+ static native void redefineClasses(Instrumentation inst,
+ ClassDefinition[] definitions);
+
+ /**
+ * Get all the classes loaded by the JVM.
+ *
+ * @return an array containing all the classes loaded by the JVM. The array
+ * is empty if no class is loaded.
+ */
+ static native Class[] getAllLoadedClasses();
+
+ /**
+ * Get all the classes loaded by a given class loader
+ *
+ * @param loader the loader
+ *
+ * @return an array containing all the classes loaded by the given loader.
+ * The array is empty if no class was loaded by the loader.
+ */
+ static native Class[] getInitiatedClasses(ClassLoader loader);
+
+ /**
+ * Get the size of an object. The object is not null
+ *
+ * @param objectToSize the object
+ * @return the size of the object
+ */
+ static native long getObjectSize(Object objectToSize);
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMClassLoadingMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMClassLoadingMXBeanImpl.java
new file mode 100644
index 000000000..ea4989741
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMClassLoadingMXBeanImpl.java
@@ -0,0 +1,89 @@
+/* VMClassLoadingMXBeanImpl.java - VM impl. of a class loading bean
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+/**
+ * Provides access to information about the class loading
+ * behaviour of the current invocation of the virtual
+ * machine. Instances of this bean are obtained by calling
+ * {@link ManagementFactory#getClassLoadingMXBean()}.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMClassLoadingMXBeanImpl
+{
+
+ /**
+ * Returns the number of classes currently loaded by
+ * the virtual machine.
+ *
+ * @return the number of loaded classes.
+ */
+ static native int getLoadedClassCount();
+
+ /**
+ * Returns the number of classes that have been unloaded
+ * by the virtual machine since it was started.
+ *
+ * @return the number of unloaded classes.
+ */
+ static native long getUnloadedClassCount();
+
+ /**
+ * Returns true if the virtual machine will emit additional
+ * information when classes are loaded and unloaded. The
+ * format of the output is left up to the virtual machine.
+ *
+ * @return true if verbose class loading output is on.
+ */
+ static native boolean isVerbose();
+
+ /**
+ * Turns on or off the emission of additional information
+ * when classes are loaded and unloaded. The format of the
+ * output is left up to the virtual machine. This method
+ * may be called by multiple threads concurrently, but there
+ * is only one global setting of verbosity that is affected.
+ *
+ * @param verbose the new setting for verbose class loading
+ * output.
+ */
+ static native void setVerbose(boolean verbose);
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMCompilationMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMCompilationMXBeanImpl.java
new file mode 100644
index 000000000..019af0ca4
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMCompilationMXBeanImpl.java
@@ -0,0 +1,66 @@
+/* VMCompilationMXBeanImpl.java - VM implementation of a compilation bean
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+/**
+ * Provides access to information about the JIT
+ * compiler of the virtual machine, if one exists.
+ * Instances of this bean are obtained by calling
+ * {@link ManagementFactory#getCompilationMXBean()},
+ * if this is the case.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMCompilationMXBeanImpl
+{
+
+ /**
+ * Returns the number of milliseconds the JIT
+ * compiler has spent compiling Java bytecode
+ * to native machine code. This is only called
+ * if a JIT compiler exists and the
+ * gnu.java.lang.management.CompilationTimeSupport
+ * property has been set.
+ *
+ * @return the number of milliseconds spent
+ * compiling.
+ */
+ static native long getTotalCompilationTime();
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMGarbageCollectorMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMGarbageCollectorMXBeanImpl.java
new file mode 100644
index 000000000..00861bc21
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMGarbageCollectorMXBeanImpl.java
@@ -0,0 +1,80 @@
+/* VMGarbageCollectorMXBeanImpl.java - VM interface for a GC bean
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+/**
+ * Provides access to information about the garbage collectors
+ * of the virtual machine. Garbage collectors are responsible
+ * for removing unreferenced objects from memory. A garbage
+ * collector is a type of memory manager, so this interface
+ * is combined with that of generic memory managers. An instance
+ * of this bean for each garbage collector is obtained by calling
+ * {@link ManagementFactory#getGarbageCollectorMXBeans()}.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMGarbageCollectorMXBeanImpl
+{
+
+ /**
+ * Returns the number of collections the garbage collector
+ * represented by this bean has made. -1 is returned if the
+ * collection count is undefined.
+ *
+ * @param name the name of the garbage collector.
+ * @return the number of collections made, or -1 if this is
+ * undefined.
+ */
+ static native long getCollectionCount(String name);
+
+ /**
+ * Returns the accumulated number of milliseconds this garbage
+ * collector has spent freeing the memory used by unreferenced
+ * objects. -1 is returned if the collection time is undefined.
+ * Note that the accumulated time may not change, even when the
+ * collection count increases, if the time taken is sufficiently
+ * short; this depends on the resolution of the timer used.
+ *
+ * @param name the name of the garbage collector.
+ * @return the accumulated number of milliseconds spent collecting,
+ * or -1 if this is undefined.
+ */
+ static native long getCollectionTime(String name);
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryMXBeanImpl.java
new file mode 100644
index 000000000..7f69bdfb7
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryMXBeanImpl.java
@@ -0,0 +1,156 @@
+/* VMMemoryMXBeanImpl.java - VM impl. of a memory bean
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryPoolMXBean;
+import java.lang.management.MemoryType;
+import java.lang.management.MemoryUsage;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Provides access to information about the memory
+ * management of the current invocation of the virtual
+ * machine. Instances of this bean are obtained by calling
+ * {@link ManagementFactory#getMemoryMXBean()}.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMMemoryMXBeanImpl
+{
+
+ /**
+ * Returns an instance of {@link java.lang.management.MemoryUsage}
+ * with appropriate initial, used, committed and maximum values
+ * for the heap. By default, this uses the methods of
+ * {@link java.lang.Runtime} to provide some of the values.
+ *
+ * @return an {@link java.lang.management.MemoryUsage} instance
+ * for the heap.
+ */
+ static MemoryUsage getHeapMemoryUsage()
+ {
+ return getUsage(MemoryType.HEAP);
+ }
+
+ /**
+ * Returns an instance of {@link java.lang.management.MemoryUsage}
+ * with appropriate initial, used, committed and maximum values
+ * for non-heap memory.
+ *
+ * @return an {@link java.lang.management.MemoryUsage} instance
+ * for non-heap memory.
+ */
+ static MemoryUsage getNonHeapMemoryUsage()
+ {
+ return getUsage(MemoryType.NON_HEAP);
+ }
+
+ /**
+ * Returns the number of objects ready to be garbage collected.
+ *
+ * @return the number of finalizable objects.
+ */
+ static native int getObjectPendingFinalizationCount();
+
+ /**
+ * Returns true if the virtual machine will emit additional
+ * information when memory is allocated and deallocated. The
+ * format of the output is left up to the virtual machine.
+ *
+ * @return true if verbose memory usage output is on.
+ */
+ static native boolean isVerbose();
+
+ /**
+ * Turns on or off the emission of additional information
+ * when memory is allocated and deallocated. The format of the
+ * output is left up to the virtual machine. This method
+ * may be called by multiple threads concurrently, but there
+ * is only one global setting of verbosity that is affected.
+ *
+ * @param verbose the new setting for verbose memory usage
+ * output.
+ */
+ static native void setVerbose(boolean verbose);
+
+ /**
+ * Totals the memory usage from all the pools that match
+ * the given type.
+ *
+ * @param type the type of memory pools to accumulate
+ * (heap or non-heap).
+ * @return the memory usage overall.
+ */
+ private static MemoryUsage getUsage(MemoryType type) {
+ long init = 0, committed = 0, used = 0, max = 0;
+ Iterator pools =
+ ManagementFactory.getMemoryPoolMXBeans().iterator();
+ while (pools.hasNext())
+ {
+ MemoryPoolMXBean pool = (MemoryPoolMXBean) pools.next();
+ if (pool.getType() == type)
+ {
+ MemoryUsage usage = pool.getUsage();
+ if (init != -1)
+ {
+ long poolInit = usage.getInit();
+ if (poolInit == -1)
+ init = -1;
+ else
+ init += poolInit;
+ }
+ committed += usage.getCommitted();
+ used += usage.getUsed();
+ if (max != -1)
+ {
+ long poolMax = usage.getMax();
+ if (poolMax == -1)
+ max = -1;
+ else
+ max += poolMax;
+ }
+ }
+ }
+ return new MemoryUsage(init, used, committed, max);
+ }
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryManagerMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryManagerMXBeanImpl.java
new file mode 100644
index 000000000..477329f0a
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryManagerMXBeanImpl.java
@@ -0,0 +1,95 @@
+/* VMMemoryManagerMXBeanImpl.java - VM interface for a memory manager bean
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryPoolMXBean;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Provides access to information about the memory managers
+ * of the virtual machine. An instance of this bean for each
+ * memory manager is obtained by calling
+ * {@link ManagementFactory#getMemoryManagerMXBeans()}.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMMemoryManagerMXBeanImpl
+{
+
+ /**
+ * Returns an array containing the names of the memory pools
+ * this memory manager manages.
+ *
+ * @param name the name of the memory manager.
+ * @return an array containing the name of each memory pool
+ * this manager is responsible for.
+ */
+ static String[] getMemoryPoolNames(String name)
+ {
+ List managedPools = new ArrayList();
+ Iterator beans = ManagementFactory.getMemoryPoolMXBeans().iterator();
+ while (beans.hasNext())
+ {
+ MemoryPoolMXBean bean = (MemoryPoolMXBean) beans.next();
+ String[] managers = bean.getMemoryManagerNames();
+ for (int a = 0; a < managers.length; ++a)
+ if (managers[a].equals(name))
+ {
+ managedPools.add(bean.getName());
+ break;
+ }
+ }
+ return (String[]) managedPools.toArray(new String[managedPools.size()]);
+ }
+
+ /**
+ * Returns true if this memory manager is still valid. A memory
+ * manager becomes invalid when it is removed by the virtual machine
+ * and no longer used.
+ *
+ * @param name the name of the memory manager.
+ * @return true if this memory manager is valid.
+ */
+ static native boolean isValid(String name);
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryPoolMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryPoolMXBeanImpl.java
new file mode 100644
index 000000000..36cd2586a
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryPoolMXBeanImpl.java
@@ -0,0 +1,195 @@
+/* MemoryPoolMXBeanImpl.java - VM interface for memory pool beans
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import java.lang.management.MemoryUsage;
+
+/**
+ * Provides access to information on the memory resources or
+ * pools used by the current invocation of the virtual machine.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMMemoryPoolMXBeanImpl
+{
+
+ /**
+ * Returns memory usage statistics for the specified pool
+ * just after a best-effort attempt to free memory. This
+ * is valid only for certain garbage collectors.
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return a {@link java.lang.management.MemoryUsage} object
+ * containing the statistics or <code>null</code>
+ * if this pool does not support such statistics.
+ */
+ static native MemoryUsage getCollectionUsage(String name);
+
+ /**
+ * Returns the collection usage threshold for the specified pool.
+ * This is only called if this functionality is supported
+ * by the virtual machine (i.e. the appropriate property,
+ * <code>gnu.java.lang.management.CollectionUsageThresholdSupport</code>,
+ * is defined). The value is initially zero.
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return the collection usage threshold.
+ */
+ static native long getCollectionUsageThreshold(String name);
+
+ /**
+ * Returns the number of times the collection usage threshold
+ * has been met or exceeded by the specified pool.
+ * This is only called if this functionality is supported
+ * by the virtual machine (i.e. the appropriate property,
+ * <code>gnu.java.lang.management.CollectionUsageThresholdSupport</code>,
+ * is defined).
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return the collection usage threshold count.
+ */
+ static native long getCollectionUsageThresholdCount(String name);
+
+ /**
+ * Returns an array of names of memory managers which manage
+ * the specified pool.
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return a list of memory managers for the pool.
+ */
+ static native String[] getMemoryManagerNames(String name);
+
+ /**
+ * Returns the peak usage level of the specified pool.
+ * This is only called if the pool is valid.
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return a {@link java.lang.management.MemoryUsage} object
+ * containing the statistics.
+ */
+ static native MemoryUsage getPeakUsage(String name);
+
+ /**
+ * Returns the type of memory used by the specified pool.
+ * The value must be either "HEAP" or "NON_HEAP".
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return the type of the given pool.
+ */
+ static native String getType(String name);
+
+ /**
+ * Returns the current usage level of the specified pool.
+ * This is only called if the pool is valid.
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return a {@link java.lang.management.MemoryUsage} object
+ * containing the statistics.
+ */
+ static native MemoryUsage getUsage(String name);
+
+ /**
+ * Returns the usage threshold for the specified pool.
+ * This is only called if this functionality is supported
+ * by the virtual machine (i.e. the appropriate property,
+ * <code>gnu.java.lang.management.UsageThresholdSupport</code>,
+ * is defined). The value is initially defined by the
+ * virtual machine.
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return the usage threshold.
+ */
+ static native long getUsageThreshold(String name);
+
+ /**
+ * Returns the number of times the usage threshold
+ * has been met or exceeded by the specified pool.
+ * This is only called if this functionality is supported
+ * by the virtual machine (i.e. the appropriate property,
+ * <code>gnu.java.lang.management.UsageThresholdSupport</code>,
+ * is defined).
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return the usage threshold count.
+ */
+ static native long getUsageThresholdCount(String name);
+
+ /**
+ * Returns true if the specified pool is still valid i.e.
+ * it is still in use by the virtual machine.
+ *
+ * @param name the name of the pool to check the validity of.
+ * @return true if the pool is valid.
+ */
+ static native boolean isValid(String name);
+
+ /**
+ * Resets the peak usage level to the current usage level for
+ * the specified pool.
+ *
+ * @param name the name of the pool to reset the peak usage of.
+ */
+ static native void resetPeakUsage(String name);
+
+ /**
+ * Sets the collection usage threshold for the specified
+ * pool to the supplied value.
+ * This is only called if this functionality is supported
+ * by the virtual machine (i.e. the appropriate property,
+ * <code>gnu.java.lang.management.CollectionUsageThresholdSupport</code>,
+ * is defined).
+ *
+ * @param name the name of the pool to set the threshold of.
+ * @param threshold the new threshold level.
+ */
+ static native void setCollectionUsageThreshold(String name, long threshold);
+
+ /**
+ * Sets the usage threshold for the specified pool to the supplied value.
+ * This is only called if this functionality is supported
+ * by the virtual machine (i.e. the appropriate property,
+ * <code>gnu.java.lang.management.UsageThresholdSupport</code>,
+ * is defined).
+ *
+ * @param name the name of the pool to set the threshold of.
+ * @param threshold the new threshold level.
+ */
+ static native void setUsageThreshold(String name, long threshold);
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMOperatingSystemMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMOperatingSystemMXBeanImpl.java
new file mode 100644
index 000000000..20b3f9ed2
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMOperatingSystemMXBeanImpl.java
@@ -0,0 +1,68 @@
+/* VMOperatingSystemMXBeanImpl.java - VM implementation of an OS bean
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import gnu.classpath.Configuration;
+
+/**
+ * Provides access to information about the operating system.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.6
+ */
+final class VMOperatingSystemMXBeanImpl
+{
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javalangmanagement");
+ }
+ }
+
+ /**
+ * Returns the system load average from the last
+ * minute.
+ *
+ * @return the system load average from the last
+ * minute.
+ */
+ static native double getSystemLoadAverage();
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMRuntimeMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMRuntimeMXBeanImpl.java
new file mode 100644
index 000000000..32a866046
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMRuntimeMXBeanImpl.java
@@ -0,0 +1,89 @@
+/* VMRuntimeMXBeanImpl.java - VM implementation of an runtime bean
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import gnu.classpath.SystemProperties;
+
+/**
+ * Provides access to information about the virtual machine.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMRuntimeMXBeanImpl
+{
+
+ /**
+ * Returns the command-line arguments supplied
+ * to the virtual machine, excluding those supplied
+ * to <code>main()</code>.
+ *
+ * @return the command-line arguments.
+ */
+ static native String[] getInputArguments();
+
+ /**
+ * Returns a developer-chosen name for the virtual
+ * machine, which may differ over different running
+ * instances of the same virtual machine binary.
+ * For example, this may include the particular
+ * process identifier used by this instance or
+ * the host name of the machine on which it is
+ * running. The intention is that this name refers
+ * to the precise entity that the other data supplied
+ * by the bean refers to, rather than the VM in general.
+ *
+ * @return the custom name of the VM.
+ */
+ static String getName()
+ {
+ return SystemProperties.getProperty("java.vm.name") + " " +
+ SystemProperties.getProperty("java.vm.version");
+ }
+
+ /**
+ * The time in milliseconds at which the virtual
+ * machine was started. This method is only executed
+ * once (for efficency), as the value is not expected
+ * to change.
+ *
+ * @return the VM start time.
+ */
+ static native long getStartTime();
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMThreadMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMThreadMXBeanImpl.java
new file mode 100644
index 000000000..33448d9d5
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMThreadMXBeanImpl.java
@@ -0,0 +1,236 @@
+/* VMThreadMXBeanImpl.java - VM impl. of a thread bean
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import java.lang.management.ThreadInfo;
+
+/**
+ * Provides access to information about the threads
+ * of the virtual machine. An instance of this bean is
+ * obtained by calling
+ * {@link ManagementFactory#getThreadMXBean()}.
+ * See {@link java.lang.management.ThreadMXBean} for
+ * full documentation.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMThreadMXBeanImpl
+{
+
+ /**
+ * Cache of how many threads were found.
+ */
+ private static int filled;
+
+ /**
+ * Returns the ids of cycles of deadlocked threads, occurring
+ * due to monitor ownership or ownable synchronizer ownership.
+ * This will only be called if ownable synchronizer monitoring
+ * is supported.
+ *
+ * @return the ids of the deadlocked threads.
+ */
+ static native long[] findDeadlockedThreads();
+
+ /**
+ * Returns the ids of cycles of deadlocked threads, occurring
+ * due to monitor ownership.
+ *
+ * @return the ids of the deadlocked threads.
+ */
+ static native long[] findMonitorDeadlockedThreads();
+
+ /* This is the same as in Thread.getAllStackTraces() */
+ static Thread[] getAllThreads()
+ {
+ ThreadGroup group = Thread.currentThread().getThreadGroup();
+ while (group.getParent() != null)
+ group = group.getParent();
+ int arraySize = group.activeCount();
+ Thread[] threadList = new Thread[arraySize];
+ filled = group.enumerate(threadList);
+ while (filled == arraySize)
+ {
+ arraySize *= 2;
+ threadList = new Thread[arraySize];
+ filled = group.enumerate(threadList);
+ }
+ return threadList;
+ }
+
+ /**
+ * Returns the id of all live threads at the time of execution.
+ *
+ * @return the live thread ids.
+ */
+ static long[] getAllThreadIds()
+ {
+ Thread[] threadList = getAllThreads();
+ long[] ids = new long[filled];
+ for (int a = 0; a < filled; ++a)
+ ids[a] = threadList[a].getId();
+ return ids;
+ }
+
+ /**
+ * Returns the number of nanoseconds of CPU time
+ * the current thread has used in total. This is
+ * only called if this feature is enabled and
+ * supported.
+ *
+ * @return the nanoseconds of CPU time used by
+ * the current thread.
+ */
+ static native long getCurrentThreadCpuTime();
+
+ /**
+ * Returns the number of nanoseconds of user time
+ * the current thread has used in total. This is
+ * only called if this feature is enabled and
+ * supported.
+ *
+ * @return the nanoseconds of user time used by
+ * the current thread.
+ */
+ static native long getCurrentThreadUserTime();
+
+ /**
+ * Returns the number of live daemon threads.
+ *
+ * @return the number of live daemon threads.
+ */
+ static int getDaemonThreadCount()
+ {
+ Thread[] threadList = getAllThreads();
+ int daemonCount = 0;
+ for (int a = 0; a < filled; ++a)
+ {
+ if (threadList[a].isDaemon())
+ ++daemonCount;
+ }
+ return daemonCount;
+ }
+
+ /**
+ * Fill out the given {@link ThreadInfo} object
+ * with ownable synchronizer usage information.
+ * This is only called if ownable synchronizer
+ * usage monitoring is supported.
+ *
+ * @param info the {@link ThreadInfo} object to modify.
+ */
+ static native void getLockInfo(ThreadInfo info);
+
+ /**
+ * Fill out the given {@link ThreadInfo} object
+ * with monitor usage information. This is only
+ * called if monitor usage monitoring is supported.
+ *
+ * @param info the {@link ThreadInfo} object to modify.
+ */
+ static native void getMonitorInfo(ThreadInfo info);
+
+ /**
+ * Returns the current peak number of live threads.
+ *
+ * @return the peak number of live threads.
+ */
+ static native int getPeakThreadCount();
+
+ /**
+ * Returns the number of live threads.
+ *
+ * @return the number of live threads.
+ */
+ static int getThreadCount()
+ {
+ getAllThreads();
+ return filled;
+ }
+
+ /**
+ * Returns the number of nanoseconds of CPU time
+ * the specified thread has used in total. This is
+ * only called if this feature is enabled and
+ * supported.
+ *
+ * @param id the thread to obtain statistics on.
+ * @return the nanoseconds of CPU time used by
+ * the thread.
+ */
+ static native long getThreadCpuTime(long id);
+
+ /**
+ * Returns the {@link java.lang.management.ThreadInfo}
+ * which corresponds to the specified id.
+ *
+ * @param id the id of the thread.
+ * @param maxDepth the depth of the stack trace.
+ * @return the corresponding <code>ThreadInfo</code>.
+ */
+ static native ThreadInfo getThreadInfoForId(long id, int maxDepth);
+
+ /**
+ * Returns the number of nanoseconds of user time
+ * the specified thread has used in total. This is
+ * only called if this feature is enabled and
+ * supported.
+ *
+ * @param id the thread to obtain statistics on.
+ * @return the nanoseconds of user time used by
+ * the thread.
+ */
+ static native long getThreadUserTime(long id);
+
+ /**
+ * Returns the total number of threads that have
+ * been started over the lifetime of the virtual
+ * machine.
+ *
+ * @return the total number of threads started.
+ */
+ static native long getTotalStartedThreadCount();
+
+ /**
+ * Resets the peak thread count to the current
+ * number of live threads.
+ */
+ static native void resetPeakThreadCount();
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/net/VMPlainDatagramSocketImpl.java b/libjava/classpath/vm/reference/gnu/java/net/VMPlainDatagramSocketImpl.java
new file mode 100644
index 000000000..da0f893cf
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/net/VMPlainDatagramSocketImpl.java
@@ -0,0 +1,260 @@
+/* PlainDatagramSocketImpl.java -- VM interface for DatagramSocket impl
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.net;
+
+import gnu.classpath.Configuration;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketAddress;
+import java.net.SocketException;
+
+/**
+ * The VM interface for {@link gnu.java.net.PlainDatagramSocketImpl}.
+ *
+ * @author Ingo Proetel (proetel@aicas.com)
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+public final class VMPlainDatagramSocketImpl
+{
+ /**
+ * Option id for the IP_TTL (time to live) value.
+ */
+ static final int IP_TTL = 0x1E61; // 7777
+
+
+ // Static initializer to load native library
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javanet");
+ }
+ }
+
+ /**
+ * Binds this socket to a particular port and interface
+ *
+ * @param socket the socket object
+ * @param port the port to bind to
+ * @param addr the address to bind to
+ *
+ * @throws SocketException If an error occurs
+ */
+ static native void bind(PlainDatagramSocketImpl socket, int port,
+ InetAddress addr)
+ throws SocketException;
+
+ /**
+ * Creates a new datagram socket.
+ *
+ * @param socket the socket object
+ *
+ * @throws SocketException If an error occurs
+ */
+ static native void create(PlainDatagramSocketImpl socket)
+ throws SocketException;
+
+ /**
+ * Connects to the remote address and port specified as arguments.
+ *
+ * @param socket the socket object
+ * @param addr the remote address to connect to
+ * @param port the remote port to connect to
+ *
+ * @throws SocketException If an error occurs
+ */
+ static native void connect(PlainDatagramSocketImpl socket, InetAddress addr,
+ int port)
+ throws SocketException;
+
+ /**
+ * Sends a packet of data to a remote host.
+ *
+ * @param socket the socket object
+ * @param packet the packet to send
+ *
+ * @throws IOException If an error occurs
+ */
+ static void send(PlainDatagramSocketImpl socket, DatagramPacket packet)
+ throws IOException
+ {
+ nativeSendTo(socket, packet.getAddress(), packet.getPort(),
+ packet.getData(), packet.getOffset(), packet.getLength());
+ }
+
+
+ /**
+ * Sends a packet of data to a remote host.
+ *
+ * @param socket the socket object
+ * @param addr the address to send to
+ * @param port the port to send to
+ * @param buf the buffer to send
+ * @param offset the offset of the data in the buffer to send
+ * @param len the length of the data to send
+ *
+ * @throws IOException If an error occurs
+ */
+ private static native void nativeSendTo(PlainDatagramSocketImpl socket,
+ InetAddress addr, int port,
+ byte[] buf, int offset, int len)
+ throws IOException;
+
+ /**
+ * Receives a UDP packet from the network
+ *
+ * @param socket the socket object
+ * @param packet the packet to fill in with the data received
+ *
+ * @throws IOException IOException If an error occurs
+ */
+ static void receive(PlainDatagramSocketImpl socket, DatagramPacket packet)
+ throws IOException
+ {
+ byte[] receiveFromAddress = new byte[4];
+ int[] receiveFromPort = new int[1];
+ int[] receivedLength = new int[1];
+
+ nativeReceive(socket, packet.getData(), packet.getOffset(),
+ packet.getLength(),
+ receiveFromAddress, receiveFromPort, receivedLength);
+
+ packet.setAddress(InetAddress.getByAddress(receiveFromAddress));
+ packet.setPort(receiveFromPort[0]);
+ packet.setLength(receivedLength[0]);
+ }
+
+ private static native void nativeReceive(PlainDatagramSocketImpl socket,
+ byte[] buf, int offset, int len,
+ byte[] receiveFromAddress,
+ int[] receiveFromPort,
+ int[] receivedLength)
+ throws IOException;
+
+ /**
+ * Sets the value of an option on the socket
+ *
+ * @param socket the socket object
+ * @param optionId the identifier of the option to set
+ * @param value the value of the option to set
+ *
+ * @exception SocketException If an error occurs
+ */
+ static native void setOption(PlainDatagramSocketImpl socket, int optionId,
+ Object value)
+ throws SocketException;
+
+ /**
+ * Retrieves the value of an option on the socket.
+ *
+ * @param socket the socket object
+ * @param optionId the identifier of the option to retrieve
+ *
+ * @return the value of the option
+ *
+ * @throws SocketException if an error occurs
+ */
+ static native Object getOption(PlainDatagramSocketImpl socket, int optionId)
+ throws SocketException;
+
+ /**
+ * Closes the socket.
+ *
+ * @param socket the socket object
+ */
+ static native void close(PlainDatagramSocketImpl socket);
+
+ /**
+ * Joins a multicast group
+ *
+ * @param addr The group to join
+ *
+ * @exception IOException If an error occurs
+ */
+ static native void join(PlainDatagramSocketImpl socket, InetAddress addr)
+ throws IOException;
+
+ /**
+ * Leaves a multicast group
+ *
+ * @param addr The group to leave
+ *
+ * @exception IOException If an error occurs
+ */
+ static native void leave(PlainDatagramSocketImpl socket, InetAddress addr)
+ throws IOException;
+
+ /**
+ * Joins a multicast group.
+ *
+ * @param socket the socket object
+ * @param address the socket address
+ * @param netIf the network interface
+ *
+ * @throws IOException if I/O errors occur
+ */
+ static void joinGroup(PlainDatagramSocketImpl socket, SocketAddress address,
+ NetworkInterface netIf)
+ throws IOException
+ {
+ throw new InternalError
+ ("PlainDatagramSocketImpl::joinGroup is not implemented");
+ }
+
+ /**
+ * Leaves a multicast group.
+ *
+ * @param socket the socket object
+ * @param address the socket address
+ * @param netIf the network interface
+ *
+ * @throws IOException if I/O errors occur
+ */
+ static void leaveGroup(PlainDatagramSocketImpl socket, SocketAddress address,
+ NetworkInterface netIf)
+ throws IOException
+ {
+ throw new InternalError
+ ("PlainDatagramSocketImpl::leaveGroup is not implemented");
+ }
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/net/VMPlainSocketImpl.java b/libjava/classpath/vm/reference/gnu/java/net/VMPlainSocketImpl.java
new file mode 100644
index 000000000..c72e6a5eb
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/net/VMPlainSocketImpl.java
@@ -0,0 +1,511 @@
+/* VMPlainSocketImpl.java -- VM interface for default socket implementation
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.net;
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.SocketOptions;
+
+import gnu.classpath.Configuration;
+import gnu.java.nio.VMChannel;
+
+/**
+ * The VM interface for {@link gnu.java.net.PlainSocketImpl}.
+ *
+ * @author Ingo Proetel (proetel@aicas.com)
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+public final class VMPlainSocketImpl
+{
+ /** Option id for time to live
+ */
+ private static final int CP_IP_TTL = 0x1E61;
+
+ private final State nfd;
+
+ /**
+ * Static initializer to load native library.
+ */
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javanet");
+ }
+ }
+
+ public VMPlainSocketImpl()
+ {
+ // XXX consider adding security check here.
+ nfd = new State();
+ }
+
+ public VMPlainSocketImpl(VMChannel channel) throws IOException
+ {
+ this();
+ nfd.setChannelFD(channel.getState());
+ }
+
+ public State getState()
+ {
+ return nfd;
+ }
+
+ /** This method exists to hide the CP_IP_TTL value from
+ * higher levels.
+ *
+ * Always think of JNode ... :)
+ */
+ public void setTimeToLive(int ttl)
+ throws SocketException
+ {
+ try
+ {
+ setOption(nfd.getNativeFD(), CP_IP_TTL, ttl);
+ }
+ catch (IOException ioe)
+ {
+ SocketException se = new SocketException();
+ se.initCause(ioe);
+ throw se;
+ }
+ }
+
+ public int getTimeToLive()
+ throws SocketException
+ {
+ try
+ {
+ return getOption(nfd.getNativeFD(), CP_IP_TTL);
+ }
+ catch (IOException ioe)
+ {
+ SocketException se = new SocketException();
+ se.initCause(ioe);
+ throw se;
+ }
+ }
+
+ public void setOption(int optionId, Object optionValue)
+ throws SocketException
+ {
+ int value;
+ if (optionValue instanceof Integer)
+ value = ((Integer) optionValue).intValue();
+ else if (optionValue instanceof Boolean)
+ // Switching off the linger behavior is done by setting
+ // the value to -1. This is how the Java API interprets
+ // it.
+ value = ((Boolean) optionValue).booleanValue()
+ ? 1
+ : (optionId == SocketOptions.SO_LINGER)
+ ? -1
+ : 0;
+ else
+ throw new IllegalArgumentException("option value type "
+ + optionValue.getClass().getName());
+
+ try
+ {
+ setOption(nfd.getNativeFD(), optionId, value);
+ }
+ catch (IOException ioe)
+ {
+ SocketException se = new SocketException();
+ se.initCause(ioe);
+ throw se;
+ }
+ }
+
+ private static native void setOption(int fd, int id, int value)
+ throws SocketException;
+
+ public void setMulticastInterface(int optionId, InetAddress addr)
+ throws SocketException
+ {
+ try
+ {
+ if (addr instanceof Inet4Address)
+ setMulticastInterface(nfd.getNativeFD(), optionId, (Inet4Address) addr);
+ else if (addr instanceof Inet6Address)
+ {
+ NetworkInterface iface = NetworkInterface.getByInetAddress(addr);
+ setMulticastInterface6(nfd.getNativeFD(), optionId, iface.getName());
+ }
+ else
+ throw new SocketException("Unknown address format: " + addr);
+ }
+ catch (SocketException se)
+ {
+ throw se;
+ }
+ catch (IOException ioe)
+ {
+ SocketException se = new SocketException();
+ se.initCause(ioe);
+ throw se;
+ }
+ }
+
+ private static native void setMulticastInterface(int fd,
+ int optionId,
+ Inet4Address addr);
+
+ private static native void setMulticastInterface6(int fd,
+ int optionId,
+ String ifName);
+
+ /**
+ * Get a socket option. This implementation is only required to support
+ * socket options that are boolean values, which include:
+ *
+ * SocketOptions.IP_MULTICAST_LOOP
+ * SocketOptions.SO_BROADCAST
+ * SocketOptions.SO_KEEPALIVE
+ * SocketOptions.SO_OOBINLINE
+ * SocketOptions.SO_REUSEADDR
+ * SocketOptions.TCP_NODELAY
+ *
+ * and socket options that are integer values, which include:
+ *
+ * SocketOptions.IP_TOS
+ * SocketOptions.SO_LINGER
+ * SocketOptions.SO_RCVBUF
+ * SocketOptions.SO_SNDBUF
+ * SocketOptions.SO_TIMEOUT
+ *
+ * @param optionId The option ID to fetch.
+ * @return A {@link Boolean} or {@link Integer} containing the socket
+ * option.
+ * @throws SocketException
+ */
+ public Object getOption(int optionId) throws SocketException
+ {
+ int value;
+ try
+ {
+ value = getOption(nfd.getNativeFD(), optionId);
+ }
+ catch (IOException ioe)
+ {
+ SocketException se = new SocketException();
+ se.initCause(ioe);
+ throw se;
+ }
+
+ switch (optionId)
+ {
+ case SocketOptions.IP_MULTICAST_LOOP:
+ case SocketOptions.SO_BROADCAST:
+ case SocketOptions.SO_KEEPALIVE:
+ case SocketOptions.SO_OOBINLINE:
+ case SocketOptions.SO_REUSEADDR:
+ case SocketOptions.TCP_NODELAY:
+ return Boolean.valueOf(value != 0);
+
+ case SocketOptions.IP_TOS:
+ case SocketOptions.SO_LINGER:
+ case SocketOptions.SO_RCVBUF:
+ case SocketOptions.SO_SNDBUF:
+ case SocketOptions.SO_TIMEOUT:
+ return new Integer(value);
+
+ default:
+ throw new SocketException("getting option " + optionId +
+ " not supported here");
+ }
+ }
+
+ private static native int getOption(int fd, int id) throws SocketException;
+
+ /**
+ * Returns an Inet4Address or Inet6Address instance belonging to the
+ * interface which is set as the multicast interface.
+ *
+ * The optionId is provided to make it possible that the native
+ * implementation may do something different depending on whether
+ * the value is SocketOptions.IP_MULTICAST_IF or
+ * SocketOptions.IP_MULTICAST_IF2.
+ */
+ public InetAddress getMulticastInterface(int optionId)
+ throws SocketException
+ {
+ try
+ {
+ return getMulticastInterface(nfd.getNativeFD(), optionId);
+ }
+ catch (IOException ioe)
+ {
+ SocketException se = new SocketException();
+ se.initCause(ioe);
+ throw se;
+ }
+ }
+
+ private static native InetAddress getMulticastInterface(int fd,
+ int optionId);
+
+ /**
+ * Binds this socket to the given local address and port.
+ *
+ * @param address The address to bind to; the InetAddress is either
+ * an IPv4 or IPv6 address.
+ * @throws IOException If binding fails; for example, if the port
+ * in the given InetSocketAddress is privileged, and the current
+ * process has insufficient privileges.
+ */
+ public void bind(InetSocketAddress address) throws IOException
+ {
+ InetAddress addr = address.getAddress();
+ if (addr instanceof Inet4Address)
+ {
+ bind (nfd.getNativeFD(), addr.getAddress(), address.getPort());
+ }
+ else if (addr instanceof Inet6Address)
+ bind6 (nfd.getNativeFD(), addr.getAddress(), address.getPort());
+ else
+ throw new SocketException ("unsupported address type");
+ }
+
+ /**
+ * Native bind function for IPv4 addresses. The addr array must be
+ * exactly four bytes long.
+ *
+ * VMs without native support need not implement this.
+ *
+ * @param fd The native file descriptor integer.
+ * @param addr The IPv4 address, in network byte order.
+ * @param port The port to bind to.
+ * @throws IOException
+ */
+ private static native void bind(int fd, byte[] addr, int port)
+ throws IOException;
+
+ /**
+ * Native bind function for IPv6 addresses. The addr array must be
+ * exactly sixteen bytes long.
+ *
+ * VMs without native support need not implement this.
+ *
+ * @param fd The native file descriptor integer.
+ * @param addr The IPv6 address, in network byte order.
+ * @param port The port to bind to.
+ * @throws IOException
+ */
+ private static native void bind6(int fd, byte[] addr, int port)
+ throws IOException;
+
+ /**
+ * Listen on this socket for incoming connections.
+ *
+ * @param backlog The backlog of connections.
+ * @throws IOException If listening fails.
+ * @see gnu.java.nio.VMChannel#accept()
+ */
+ public void listen(int backlog) throws IOException
+ {
+ listen(nfd.getNativeFD(), backlog);
+ }
+
+ /**
+ * Native listen function. VMs without native support need not implement
+ * this.
+ *
+ * @param fd The file descriptor integer.
+ * @param backlog The listen backlog size.
+ * @throws IOException
+ */
+ private static native void listen(int fd, int backlog) throws IOException;
+
+ public void join(InetAddress group) throws IOException
+ {
+ if (group instanceof Inet4Address)
+ join(nfd.getNativeFD(), group.getAddress());
+ else if (group instanceof Inet6Address)
+ join6(nfd.getNativeFD(), group.getAddress());
+ else
+ throw new IllegalArgumentException("unknown address type");
+ }
+
+ private static native void join(int fd, byte[] addr) throws IOException;
+
+ private static native void join6(int fd, byte[] addr) throws IOException;
+
+ public void leave(InetAddress group) throws IOException
+ {
+ if (group instanceof Inet4Address)
+ leave(nfd.getNativeFD(), group.getAddress());
+ else if (group instanceof Inet6Address)
+ leave6(nfd.getNativeFD(), group.getAddress());
+ else
+ throw new IllegalArgumentException("unknown address type");
+ }
+
+ private static native void leave(int fd, byte[] addr) throws IOException;
+
+ private static native void leave6(int fd, byte[] addr) throws IOException;
+
+ public void joinGroup(InetSocketAddress addr, NetworkInterface netif)
+ throws IOException
+ {
+ InetAddress address = addr.getAddress();
+
+ if (address instanceof Inet4Address)
+ joinGroup(nfd.getNativeFD(), address.getAddress(),
+ netif != null ? netif.getName() : null);
+ else if (address instanceof Inet6Address)
+ joinGroup6(nfd.getNativeFD(), address.getAddress(),
+ netif != null ? netif.getName() : null);
+ else
+ throw new IllegalArgumentException("unknown address type");
+ }
+
+ private static native void joinGroup(int fd, byte[] addr, String ifname)
+ throws IOException;
+
+ private static native void joinGroup6(int fd, byte[] addr, String ifname)
+ throws IOException;
+
+ public void leaveGroup(InetSocketAddress addr, NetworkInterface netif)
+ throws IOException
+ {
+ InetAddress address = addr.getAddress();
+ if (address instanceof Inet4Address)
+ leaveGroup(nfd.getNativeFD(), address.getAddress(),
+ netif != null ? netif.getName() : null);
+ else if (address instanceof Inet6Address)
+ leaveGroup6(nfd.getNativeFD(), address.getAddress(),
+ netif != null ? netif.getName() : null);
+ else
+ throw new IllegalArgumentException("unknown address type");
+ }
+
+ private static native void leaveGroup(int fd, byte[] addr, String ifname)
+ throws IOException;
+
+ private static native void leaveGroup6(int fd, byte[] addr, String ifname)
+ throws IOException;
+
+
+ public void shutdownInput() throws IOException
+ {
+ shutdownInput(nfd.getNativeFD());
+ }
+
+ private static native void shutdownInput(int native_fd) throws IOException;
+
+ public void shutdownOutput() throws IOException
+ {
+ shutdownOutput(nfd.getNativeFD());
+ }
+
+ private static native void shutdownOutput(int native_fd) throws IOException;
+
+ public void sendUrgentData(int data) throws IOException
+ {
+ sendUrgentData(nfd.getNativeFD(), data);
+ }
+
+ private static native void sendUrgentData(int natfive_fd, int data) throws IOException;
+
+ public void close() throws IOException
+ {
+ nfd.close();
+ }
+
+ // Inner classes.
+
+ /**
+ * Our wrapper for the native file descriptor. In this implementation,
+ * it is a simple wrapper around {@link VMChannel.State}, to simplify
+ * management of the native state.
+ */
+ public final class State
+ {
+ private VMChannel.State channelFd;
+
+ State()
+ {
+ channelFd = null;
+ }
+
+ public boolean isValid()
+ {
+ if (channelFd != null)
+ return channelFd.isValid();
+ return false;
+ }
+
+ public int getNativeFD() throws IOException
+ {
+ return channelFd.getNativeFD();
+ }
+
+ public void setChannelFD(final VMChannel.State nfd) throws IOException
+ {
+ if (this.channelFd != null && this.channelFd.isValid())
+ throw new IOException("file descriptor already initialized");
+ this.channelFd = nfd;
+ }
+
+ public void close() throws IOException
+ {
+ if (channelFd == null)
+ throw new IOException("invalid file descriptor");
+ channelFd.close();
+ }
+
+ protected void finalize() throws Throwable
+ {
+ try
+ {
+ if (isValid())
+ close();
+ }
+ finally
+ {
+ super.finalize();
+ }
+ }
+ }
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/nio/VMChannel.java b/libjava/classpath/vm/reference/gnu/java/nio/VMChannel.java
new file mode 100644
index 000000000..4494ff13c
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/nio/VMChannel.java
@@ -0,0 +1,749 @@
+/* VMChannel.java -- Native interface suppling channel operations.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.nio;
+
+import gnu.classpath.Configuration;
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+
+/**
+ * Native interface to support configuring of channel to run in a non-blocking
+ * manner and support scatter/gather io operations.
+ *
+ * @author Michael Barker <mike@middlesoft.co.uk>
+ *
+ */
+public final class VMChannel
+{
+ /**
+ * Our reference implementation uses an integer to store the native
+ * file descriptor. Implementations without such support
+ */
+ private final State nfd;
+
+ private Kind kind;
+
+ public VMChannel()
+ {
+ // XXX consider adding security check here, so only Classpath
+ // code may create instances.
+ this.nfd = new State();
+ kind = Kind.OTHER;
+ }
+
+ /**
+ * This constructor is used by the POSIX reference implementation;
+ * other virtual machines need not support it.
+ *
+ * <strong>Important:</strong> do not call this in library code that is
+ * not specific to Classpath's reference implementation.
+ *
+ * @param native_fd The native file descriptor integer.
+ * @throws IOException
+ */
+ VMChannel(final int native_fd) throws IOException
+ {
+ this();
+ this.nfd.setNativeFD(native_fd);
+ }
+
+ public State getState()
+ {
+ return nfd;
+ }
+
+ static
+ {
+ // load the shared library needed for native methods.
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary ("javanio");
+ }
+ initIDs();
+ }
+
+ public static VMChannel getStdin() throws IOException
+ {
+ return new VMChannel(stdin_fd());
+ }
+
+ public static VMChannel getStdout() throws IOException
+ {
+ return new VMChannel(stdout_fd());
+ }
+
+ public static VMChannel getStderr() throws IOException
+ {
+ return new VMChannel(stderr_fd());
+ }
+
+ private static native int stdin_fd();
+ private static native int stdout_fd();
+ private static native int stderr_fd();
+
+ /**
+ * Set the file descriptor to have the required blocking
+ * setting.
+ *
+ * @param blocking The blocking flag to set.
+ */
+ public void setBlocking(boolean blocking) throws IOException
+ {
+ setBlocking(nfd.getNativeFD(), blocking);
+ }
+
+ private static native void setBlocking(int fd, boolean blocking)
+ throws IOException;
+
+ public int available() throws IOException
+ {
+ return available(nfd.getNativeFD());
+ }
+
+ private static native int available(int native_fd) throws IOException;
+
+ /**
+ * Reads a byte buffer directly using the supplied file descriptor.
+ *
+ * @param dst Direct Byte Buffer to read to.
+ * @return Number of bytes read.
+ * @throws IOException If an error occurs or dst is not a direct buffers.
+ */
+ public int read(ByteBuffer dst)
+ throws IOException
+ {
+ return read(nfd.getNativeFD(), dst);
+ }
+
+ private static native int read(int fd, ByteBuffer dst) throws IOException;
+
+ /**
+ * Read a single byte.
+ *
+ * @return The byte read, or -1 on end of file.
+ * @throws IOException
+ */
+ public int read() throws IOException
+ {
+ return read(nfd.getNativeFD());
+ }
+
+ private static native int read(int fd) throws IOException;
+
+ /**
+ * Reads into byte buffers directly using the supplied file descriptor.
+ * Assumes that the buffer list contains DirectBuffers. Will perform a
+ * scattering read.
+ *
+ * @param dsts An array direct byte buffers.
+ * @param offset Index of the first buffer to read to.
+ * @param length The number of buffers to read to.
+ * @return Number of bytes read.
+ * @throws IOException If an error occurs or the dsts are not direct buffers.
+ */
+ public long readScattering(ByteBuffer[] dsts, int offset, int length)
+ throws IOException
+ {
+ if (offset + length > dsts.length)
+ throw new IndexOutOfBoundsException("offset + length > dsts.length");
+
+ return readScattering(nfd.getNativeFD(), dsts, offset, length);
+ }
+
+ private static native long readScattering(int fd, ByteBuffer[] dsts,
+ int offset, int length)
+ throws IOException;
+
+ /**
+ * Receive a datagram on this channel, returning the host address
+ * that sent the datagram.
+ *
+ * @param dst Where to store the datagram.
+ * @return The host address that sent the datagram.
+ * @throws IOException
+ */
+ public SocketAddress receive(ByteBuffer dst) throws IOException
+ {
+ if (kind != Kind.SOCK_DGRAM)
+ throw new SocketException("not a datagram socket");
+ ByteBuffer hostPort = ByteBuffer.allocateDirect(18);
+ int hostlen = receive(nfd.getNativeFD(), dst, hostPort);
+ if (hostlen == 0)
+ return null;
+ if (hostlen == 4) // IPv4
+ {
+ byte[] addr = new byte[4];
+ hostPort.get(addr);
+ int port = hostPort.getShort() & 0xFFFF;
+ return new InetSocketAddress(Inet4Address.getByAddress(addr), port);
+ }
+ if (hostlen == 16) // IPv6
+ {
+ byte[] addr = new byte[16];
+ hostPort.get(addr);
+ int port = hostPort.getShort() & 0xFFFF;
+ return new InetSocketAddress(Inet6Address.getByAddress(addr), port);
+ }
+
+ throw new SocketException("host address received with invalid length: "
+ + hostlen);
+ }
+
+ private static native int receive (int fd, ByteBuffer dst, ByteBuffer address)
+ throws IOException;
+
+ /**
+ * Writes from a direct byte bufer using the supplied file descriptor.
+ * Assumes the buffer is a DirectBuffer.
+ *
+ * @param src The source buffer.
+ * @return Number of bytes written.
+ * @throws IOException
+ */
+ public int write(ByteBuffer src) throws IOException
+ {
+ return write(nfd.getNativeFD(), src);
+ }
+
+ private native int write(int fd, ByteBuffer src) throws IOException;
+
+ /**
+ * Writes from byte buffers directly using the supplied file descriptor.
+ * Assumes the that buffer list constains DirectBuffers. Will perform
+ * as gathering write.
+ *
+ * @param srcs
+ * @param offset
+ * @param length
+ * @return Number of bytes written.
+ * @throws IOException
+ */
+ public long writeGathering(ByteBuffer[] srcs, int offset, int length)
+ throws IOException
+ {
+ if (offset + length > srcs.length)
+ throw new IndexOutOfBoundsException("offset + length > srcs.length");
+
+ // A gathering write is limited to 16 buffers; when writing, ensure
+ // that we have at least one buffer with something in it in the 16
+ // buffer window starting at offset.
+ while (!srcs[offset].hasRemaining() && offset < srcs.length)
+ offset++;
+
+ // There are no buffers with anything to write.
+ if (offset == srcs.length)
+ return 0;
+
+ // If we advanced `offset' so far that we don't have `length'
+ // buffers left, reset length to only the remaining buffers.
+ if (length > srcs.length - offset)
+ length = srcs.length - offset;
+
+ return writeGathering(nfd.getNativeFD(), srcs, offset, length);
+ }
+
+ private native long writeGathering(int fd, ByteBuffer[] srcs,
+ int offset, int length)
+ throws IOException;
+
+ /**
+ * Send a datagram to the given address.
+ *
+ * @param src The source buffer.
+ * @param dst The destination address.
+ * @return The number of bytes written.
+ * @throws IOException
+ */
+ public int send(ByteBuffer src, InetSocketAddress dst)
+ throws IOException
+ {
+ InetAddress addr = dst.getAddress();
+ if (addr == null)
+ throw new NullPointerException();
+ if (addr instanceof Inet4Address)
+ return send(nfd.getNativeFD(), src, addr.getAddress(), dst.getPort());
+ else if (addr instanceof Inet6Address)
+ return send6(nfd.getNativeFD(), src, addr.getAddress(), dst.getPort());
+ else
+ throw new SocketException("unrecognized inet address type");
+ }
+
+ // Send to an IPv4 address.
+ private static native int send(int fd, ByteBuffer src, byte[] addr, int port)
+ throws IOException;
+
+ // Send to an IPv6 address.
+ private static native int send6(int fd, ByteBuffer src, byte[] addr, int port)
+ throws IOException;
+
+ /**
+ * Write a single byte.
+ *
+ * @param b The byte to write.
+ * @throws IOException
+ */
+ public void write(int b) throws IOException
+ {
+ write(nfd.getNativeFD(), b);
+ }
+
+ private static native void write(int fd, int b) throws IOException;
+
+ private native static void initIDs();
+
+ // Network (socket) specific methods.
+
+ /**
+ * Create a new socket. This method will initialize the native file
+ * descriptor state of this instance.
+ *
+ * @param stream Whether or not to create a streaming socket, or a datagram
+ * socket.
+ * @throws IOException If creating a new socket fails, or if this
+ * channel already has its native descriptor initialized.
+ */
+ public void initSocket(boolean stream) throws IOException
+ {
+ if (nfd.isValid())
+ throw new IOException("native FD already initialized");
+ if (stream)
+ kind = Kind.SOCK_STREAM;
+ else
+ kind = Kind.SOCK_DGRAM;
+ nfd.setNativeFD(socket(stream));
+ }
+
+ /**
+ * Create a new socket, returning the native file descriptor.
+ *
+ * @param stream Set to true for streaming sockets; false for datagrams.
+ * @return The native file descriptor.
+ * @throws IOException If creating the socket fails.
+ */
+ private static native int socket(boolean stream) throws IOException;
+
+ /**
+ * Connect the underlying socket file descriptor to the remote host.
+ *
+ * @param saddr The address to connect to.
+ * @param timeout The connect timeout to use for blocking connects.
+ * @return True if the connection succeeded; false if the file descriptor
+ * is in non-blocking mode and the connection did not immediately
+ * succeed.
+ * @throws IOException If an error occurs while connecting.
+ */
+ public boolean connect(InetSocketAddress saddr, int timeout)
+ throws SocketException
+ {
+ int fd;
+
+ InetAddress addr = saddr.getAddress();
+
+ // Translates an IOException into a SocketException to conform
+ // to the throws clause.
+ try
+ {
+ fd = nfd.getNativeFD();
+ }
+ catch (IOException ioe)
+ {
+ throw new SocketException(ioe.getMessage());
+ }
+
+ if (addr instanceof Inet4Address)
+ return connect(fd, addr.getAddress(), saddr.getPort(),
+ timeout);
+ if (addr instanceof Inet6Address)
+ return connect6(fd, addr.getAddress(), saddr.getPort(),
+ timeout);
+ throw new SocketException("unsupported internet address");
+ }
+
+ private static native boolean connect(int fd, byte[] addr, int port, int timeout)
+ throws SocketException;
+
+ private static native boolean connect6(int fd, byte[] addr, int port, int timeout)
+ throws SocketException;
+
+ /**
+ * Disconnect this channel, if it is a datagram socket. Disconnecting
+ * a datagram channel will disassociate it from any address, so the
+ * socket will remain open, but can send and receive datagrams from
+ * any address.
+ *
+ * @throws IOException If disconnecting this channel fails, or if this
+ * channel is not a datagram channel.
+ */
+ public void disconnect() throws IOException
+ {
+ if (kind != Kind.SOCK_DGRAM)
+ throw new IOException("can only disconnect datagram channels");
+ disconnect(nfd.getNativeFD());
+ }
+
+ private static native void disconnect(int fd) throws IOException;
+
+ public InetSocketAddress getLocalAddress() throws IOException
+ {
+ if (!nfd.isValid())
+ return null;
+ ByteBuffer name = ByteBuffer.allocateDirect(18);
+ int namelen = getsockname(nfd.getNativeFD(), name);
+ if (namelen == 0) // not bound
+ return null; // XXX return some wildcard?
+ if (namelen == 4)
+ {
+ byte[] addr = new byte[4];
+ name.get(addr);
+ int port = name.getShort() & 0xFFFF;
+ return new InetSocketAddress(Inet4Address.getByAddress(addr), port);
+ }
+ if (namelen == 16)
+ {
+ byte[] addr = new byte[16];
+ name.get(addr);
+ int port = name.getShort() & 0xFFFF;
+ return new InetSocketAddress(Inet6Address.getByAddress(addr), port);
+ }
+ throw new SocketException("invalid address length");
+ }
+
+ private static native int getsockname(int fd, ByteBuffer name)
+ throws IOException;
+
+ /**
+ * Returns the socket address of the remote peer this channel is connected
+ * to, or null if this channel is not yet connected.
+ *
+ * @return The peer address.
+ * @throws IOException
+ */
+ public InetSocketAddress getPeerAddress() throws IOException
+ {
+ if (!nfd.isValid())
+ return null;
+ ByteBuffer name = ByteBuffer.allocateDirect(18);
+ int namelen = getpeername (nfd.getNativeFD(), name);
+ if (namelen == 0) // not connected yet
+ return null;
+ if (namelen == 4) // IPv4
+ {
+ byte[] addr = new byte[4];
+ name.get(addr);
+ int port = name.getShort() & 0xFFFF;
+ return new InetSocketAddress(Inet4Address.getByAddress(addr), port);
+ }
+ else if (namelen == 16) // IPv6
+ {
+ byte[] addr = new byte[16];
+ name.get(addr);
+ int port = name.getShort() & 0xFFFF;
+ return new InetSocketAddress(Inet6Address.getByAddress(addr), port);
+ }
+ throw new SocketException("invalid address length");
+ }
+
+ /*
+ * The format here is the peer address, followed by the port number.
+ * The returned value is the length of the peer address; thus, there
+ * will be LEN + 2 valid bytes put into NAME.
+ */
+ private static native int getpeername(int fd, ByteBuffer name)
+ throws IOException;
+
+ /**
+ * Accept an incoming connection, returning a new VMChannel, or null
+ * if the channel is nonblocking and no connection is pending.
+ *
+ * @return The accepted connection, or null.
+ * @throws IOException If an IO error occurs.
+ */
+ public VMChannel accept() throws IOException
+ {
+ int new_fd = accept(nfd.getNativeFD());
+ if (new_fd == -1) // non-blocking accept had no pending connection
+ return null;
+ return new VMChannel(new_fd);
+ }
+
+ private static native int accept(int native_fd) throws IOException;
+
+ // File-specific methods.
+
+ /**
+ * Open a file at PATH, initializing the native state to operate on
+ * that open file.
+ *
+ * @param path The absolute file path.
+ * @throws IOException If the file cannot be opened, or if this
+ * channel was previously initialized.
+ */
+ public void openFile(String path, int mode) throws IOException
+ {
+ if (nfd.isValid() || nfd.isClosed())
+ throw new IOException("can't reinitialize this channel");
+ int fd = open(path, mode);
+ nfd.setNativeFD(fd);
+ kind = Kind.FILE;
+ }
+
+ private static native int open(String path, int mode) throws IOException;
+
+ public long position() throws IOException
+ {
+ if (kind != Kind.FILE)
+ throw new IOException("not a file");
+ return position(nfd.getNativeFD());
+ }
+
+ private static native long position(int fd) throws IOException;
+
+ public void seek(long pos) throws IOException
+ {
+ if (kind != Kind.FILE)
+ throw new IOException("not a file");
+ seek(nfd.getNativeFD(), pos);
+ }
+
+ private static native void seek(int fd, long pos) throws IOException;
+
+ public void truncate(long length) throws IOException
+ {
+ if (kind != Kind.FILE)
+ throw new IOException("not a file");
+ truncate(nfd.getNativeFD(), length);
+ }
+
+ private static native void truncate(int fd, long len) throws IOException;
+
+ public boolean lock(long pos, long len, boolean shared, boolean wait)
+ throws IOException
+ {
+ if (kind != Kind.FILE)
+ throw new IOException("not a file");
+ return lock(nfd.getNativeFD(), pos, len, shared, wait);
+ }
+
+ private static native boolean lock(int fd, long pos, long len,
+ boolean shared, boolean wait)
+ throws IOException;
+
+ public void unlock(long pos, long len) throws IOException
+ {
+ if (kind != Kind.FILE)
+ throw new IOException("not a file");
+ unlock(nfd.getNativeFD(), pos, len);
+ }
+
+ private static native void unlock(int fd, long pos, long len) throws IOException;
+
+ public long size() throws IOException
+ {
+ if (kind != Kind.FILE)
+ throw new IOException("not a file");
+ return size(nfd.getNativeFD());
+ }
+
+ private static native long size(int fd) throws IOException;
+
+ public MappedByteBuffer map(char mode, long position, int size)
+ throws IOException
+ {
+ if (kind != Kind.FILE)
+ throw new IOException("not a file");
+ return map(nfd.getNativeFD(), mode, position, size);
+ }
+
+ private static native MappedByteBuffer map(int fd, char mode,
+ long position, int size)
+ throws IOException;
+
+ public boolean flush(boolean metadata) throws IOException
+ {
+ if (kind != Kind.FILE)
+ throw new IOException("not a file");
+ return flush(nfd.getNativeFD(), metadata);
+ }
+
+ private static native boolean flush(int fd, boolean metadata) throws IOException;
+
+ // Close.
+
+ /**
+ * Close this socket. The socket is also automatically closed when this
+ * object is finalized.
+ *
+ * @throws IOException If closing the socket fails, or if this object has
+ * no open socket.
+ */
+ public void close() throws IOException
+ {
+ nfd.close();
+ }
+
+ static native void close(int native_fd) throws IOException;
+
+ /**
+ * <p>Provides a simple mean for the JNI code to find out whether the
+ * current thread was interrupted by a call to Thread.interrupt().</p>
+ *
+ * @return
+ */
+ static boolean isThreadInterrupted()
+ {
+ return Thread.currentThread().isInterrupted();
+ }
+
+ // Inner classes.
+
+ /**
+ * A wrapper for a native file descriptor integer. This tracks the state
+ * of an open file descriptor, and ensures that
+ *
+ * This class need not be fully supported by virtual machines; if a
+ * virtual machine does not use integer file descriptors, or does and
+ * wishes to hide that, then the methods of this class may be stubbed out.
+ *
+ * System-specific classes that depend on access to native file descriptor
+ * integers SHOULD declare this fact.
+ */
+ public final class State
+ {
+ private int native_fd;
+ private boolean valid;
+ private boolean closed;
+
+ State()
+ {
+ native_fd = -1;
+ valid = false;
+ closed = false;
+ }
+
+ public boolean isValid()
+ {
+ return valid;
+ }
+
+ public boolean isClosed()
+ {
+ return closed;
+ }
+
+ public int getNativeFD() throws IOException
+ {
+ if (!valid)
+ throw new IOException("invalid file descriptor");
+ return native_fd;
+ }
+
+ void setNativeFD(final int native_fd) throws IOException
+ {
+ if (valid)
+ throw new IOException("file descriptor already initialized");
+ this.native_fd = native_fd;
+ valid = true;
+ }
+
+ public void close() throws IOException
+ {
+ if (!valid)
+ throw new IOException("invalid file descriptor");
+ try
+ {
+ VMChannel.close(native_fd);
+ }
+ finally
+ {
+ valid = false;
+ closed = true;
+ }
+ }
+
+ public String toString()
+ {
+ if (closed)
+ return "<<closed>>";
+ if (!valid)
+ return "<<invalid>>";
+ return String.valueOf(native_fd);
+ }
+
+ protected void finalize() throws Throwable
+ {
+ try
+ {
+ if (valid)
+ close();
+ }
+ finally
+ {
+ super.finalize();
+ }
+ }
+ }
+
+ /**
+ * An enumeration of possible kinds of channel.
+ */
+ static class Kind // XXX enum
+ {
+ /** A streaming (TCP) socket. */
+ static final Kind SOCK_STREAM = new Kind();
+
+ /** A datagram (UDP) socket. */
+ static final Kind SOCK_DGRAM = new Kind();
+
+ /** A file. */
+ static final Kind FILE = new Kind();
+
+ /** Something else; not a socket or file. */
+ static final Kind OTHER = new Kind();
+
+ private Kind() { }
+ }
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/nio/VMPipe.java b/libjava/classpath/vm/reference/gnu/java/nio/VMPipe.java
new file mode 100644
index 000000000..a36970452
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/nio/VMPipe.java
@@ -0,0 +1,80 @@
+/* VMPipe.java -- Reference implementation for VM hooks used by PipeImpl
+ Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.nio;
+
+import java.io.IOException;
+import gnu.classpath.Configuration;
+
+/**
+ * This class contains the native methods for gnu.java.nio.PipeImpl
+ * As such, it needs help from the VM.
+ *
+ * @author Patrik Reali
+ */
+final class VMPipe
+{
+
+ static
+ {
+ // load the shared library needed for native methods.
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary ("javanio");
+ }
+ }
+
+ /**
+ * Create a pipe, consisting of a readable VMChannel and a writable
+ * VMChannel. The readable channel is returned is the first element
+ * of the array, and the writable in the second.
+ *
+ * @return A pair of VMChannels; the first readable, the second
+ * writable.
+ * @throws IOException If the pipe cannot be created.
+ */
+ static VMChannel[] pipe() throws IOException
+ {
+ VMChannel[] pipe = new VMChannel[2];
+ int[] fds = pipe0();
+ pipe[0] = new VMChannel(fds[0]);
+ pipe[1] = new VMChannel(fds[1]);
+ return pipe;
+ }
+
+ private static native int[] pipe0() throws IOException;
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/nio/VMSelector.java b/libjava/classpath/vm/reference/gnu/java/nio/VMSelector.java
new file mode 100644
index 000000000..4d37c2c1c
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/nio/VMSelector.java
@@ -0,0 +1,59 @@
+/* VMSelector.java --
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.nio;
+
+import gnu.classpath.Configuration;
+import java.io.IOException;
+
+public final class VMSelector
+{
+ static
+ {
+ // load the shared library needed for native methods.
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary ("javanio");
+ }
+ }
+
+ // A timeout value of 0 means block forever.
+ static native int select (int[] read, int[] write,
+ int[] except, long timeout)
+ throws IOException;
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/security/jce/prng/VMSecureRandom.java b/libjava/classpath/vm/reference/gnu/java/security/jce/prng/VMSecureRandom.java
new file mode 100644
index 000000000..86faa097c
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/security/jce/prng/VMSecureRandom.java
@@ -0,0 +1,129 @@
+/* VMSecureRandom.java -- random seed generator.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.security.jce.prng;
+
+/**
+ * VM-specific methods for generating real (or almost real) random
+ * seeds. VM implementors should write a version of this class that
+ * reads random bytes from some system source.
+ *
+ * <p>The default implementation of this class runs eight threads that
+ * increment counters in a tight loop, and XORs each counter to
+ * produce one byte of seed data. This is not very efficient, and is
+ * not guaranteed to be random (the thread scheduler is probably
+ * deterministic, after all). If possible, VM implementors should
+ * reimplement this class so it obtains a random seed from a system
+ * facility, such as a system entropy gathering device or hardware
+ * random number generator.
+ */
+final class VMSecureRandom
+{
+
+ /**
+ * Generate a random seed. Implementations are free to generate
+ * fewer random bytes than are requested, and leave the remaining
+ * bytes of the destination buffer as zeros. Implementations SHOULD,
+ * however, make a best-effort attempt to satisfy the request.
+ *
+ * @param buffer The destination buffer.
+ * @param offset The offset in the buffer to start putting bytes.
+ * @param length The number of random bytes to generate.
+ */
+ static int generateSeed(byte[] buffer, int offset, int length)
+ {
+ if (length < 0)
+ throw new IllegalArgumentException("length must be nonnegative");
+ if (offset < 0 || offset + length > buffer.length)
+ throw new IndexOutOfBoundsException();
+
+ Spinner[] spinners = new Spinner[8];
+ int n = 0x1;
+ for (int i = 0; i < spinners.length; i++)
+ {
+ spinners[i] = new Spinner((byte) n);
+ Thread t = new Thread(spinners[i]);
+ t.start();
+ n <<= 1;
+ }
+
+ // Wait until at least one spinner has started.
+ while (!(spinners[0].running || spinners[1].running || spinners[2].running
+ || spinners[3].running || spinners[4].running || spinners[5].running
+ || spinners[6].running || spinners[7].running))
+ {
+ Thread.yield();
+ }
+
+ for (int i = offset; i < length; i++)
+ {
+ buffer[i] = (byte) (spinners[0].value ^ spinners[1].value ^ spinners[2].value
+ ^ spinners[3].value ^ spinners[4].value ^ spinners[5].value
+ ^ spinners[6].value ^ spinners[7].value);
+ Thread.yield();
+ }
+
+ for (int i = 0; i < spinners.length; i++)
+ spinners[i].stop();
+
+ return length;
+ }
+
+ static class Spinner implements Runnable
+ {
+ volatile byte value;
+ volatile boolean running;
+
+ Spinner(final byte initial)
+ {
+ value = initial;
+ }
+
+ public void run()
+ {
+ running = true;
+ while (running)
+ value++;
+ }
+
+ private void stop()
+ {
+ running = false;
+ }
+ }
+}
diff --git a/libjava/classpath/vm/reference/java/io/VMFile.java b/libjava/classpath/vm/reference/java/io/VMFile.java
new file mode 100644
index 000000000..2af1e95c8
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/io/VMFile.java
@@ -0,0 +1,367 @@
+/* VMFile.java -- Class for methods natively accessing files
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.io;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import gnu.classpath.Configuration;
+import gnu.java.io.PlatformHelper;
+
+
+/**
+ * @author Michael Koch (konqueror@gmx.de)
+ */
+final class VMFile
+{
+ // FIXME: We support only case sensitive filesystems currently.
+ static final boolean IS_CASE_SENSITIVE = true;
+ static final boolean IS_DOS_8_3 = false;
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javaio");
+ }
+ }
+
+ /*
+ * This native method does the actual work of getting the last file
+ * modification time. It also does the existence check to avoid the
+ * overhead of a call to exists()
+ */
+ static native long lastModified(String path);
+
+ /*
+ * This native method sets the permissions to make the file read only.
+ */
+ static native boolean setReadOnly(String path);
+
+ /**
+ * This method is used to create a temporary file
+ */
+ static native boolean create(String path) throws IOException;
+
+ /*
+ * This native function actually produces the list of files in this
+ * directory
+ */
+ static native synchronized String[] list(String dirpath);
+
+ /*
+ * This native method actually performs the rename.
+ */
+ static native boolean renameTo(String targetpath, String destpath);
+
+ /*
+ * This native method actually determines the length of the file and
+ * handles the existence check
+ */
+ static native long length(String path);
+
+ /*
+ * This native method does the actual checking of file existence.
+ */
+ static native boolean exists(String path);
+
+ /*
+ * This native method handles the actual deleting of the file
+ */
+ static native boolean delete(String path);
+
+ /*
+ * This method does the actual setting of the modification time.
+ */
+ static native boolean setLastModified(String path, long time);
+
+ /*
+ * This native method actually creates the directory
+ */
+ static native boolean mkdir(String dirpath);
+
+ /**
+ * Gets the total bytes of the filesystem named by path.
+ */
+ public static native long getTotalSpace(String path);
+
+ /**
+ * Gets the total free bytes of the filesystem named by path.
+ */
+ public static native long getFreeSpace(String path);
+
+ /**
+ * Gets the available bytes of the filesystem named by path.
+ */
+ public static native long getUsableSpace(String path);
+
+ /**
+ * Set the read permission of the file.
+ */
+ public static synchronized native boolean setReadable(String path,
+ boolean readable,
+ boolean ownerOnly);
+
+ /**
+ * Set the write permission of the file.
+ */
+ public static synchronized native boolean setWritable(String path,
+ boolean writable,
+ boolean ownerOnly);
+
+ /**
+ * Set the execute permission of the file.
+ */
+ public static synchronized native boolean setExecutable(String path,
+ boolean executable,
+ boolean ownerOnly);
+
+ /*
+ * This native method does the actual check of whether or not a file
+ * is a plain file or not. It also handles the existence check to
+ * eliminate the overhead of a call to exists()
+ */
+ static native boolean isFile(String path);
+
+ /**
+ * This native method checks file permissions for writing
+ */
+ static synchronized native boolean canWrite(String path);
+
+ /**
+ * This methods checks if a directory can be written to.
+ */
+ static native boolean canWriteDirectory(String path);
+
+ /**
+ * This native method checks file permissions for reading
+ */
+ static synchronized native boolean canRead(String path);
+
+ /**
+ * This native method checks file permissions for execution
+ */
+ static synchronized native boolean canExecute(String path);
+
+ /*
+ * This method does the actual check of whether or not a file is a
+ * directory or not. It also handle the existence check to eliminate
+ * the overhead of a call to exists()
+ */
+ static native boolean isDirectory(String dirpath);
+
+ /**
+ * This methods checks if a directory can be written to.
+ */
+ static boolean canWriteDirectory(File path)
+ {
+ return canWriteDirectory(path.getAbsolutePath());
+ }
+
+ /**
+ * This method returns an array of filesystem roots. Some operating systems
+ * have volume oriented filesystem. This method provides a mechanism for
+ * determining which volumes exist. GNU systems use a single hierarchical
+ * filesystem, so will have only one "/" filesystem root.
+ *
+ * @return An array of <code>File</code> objects for each filesystem root
+ * available.
+ *
+ * @since 1.2
+ */
+ static File[] listRoots()
+ {
+ File[] roots = new File[1];
+ roots[0] = new File("/");
+ return roots;
+ }
+
+ /**
+ * This method tests whether or not this file represents a "hidden" file.
+ * On GNU systems, a file is hidden if its name begins with a "."
+ * character. Files with these names are traditionally not shown with
+ * directory listing tools.
+ *
+ * @return <code>true</code> if the file is hidden, <code>false</code>
+ * otherwise.
+ *
+ * @since 1.2
+ */
+ static boolean isHidden(String path)
+ {
+ // FIXME: this only works on UNIX
+ return getName(path).startsWith(".");
+ }
+
+ /**
+ * This method returns the name of the file. This is everything in the
+ * complete path of the file after the last instance of the separator
+ * string.
+ *
+ * @return The file name
+ */
+ static String getName(String path)
+ {
+ int pos = PlatformHelper.lastIndexOfSeparator(path);
+ if (pos == -1)
+ return path;
+
+ if (PlatformHelper.endWithSeparator(path))
+ return "";
+
+ return path.substring(pos + File.separator.length());
+ }
+
+ /**
+ * Returns the path as an absolute path name. The value returned is the
+ * current directory plus the separatory string plus the path of the file.
+ * The current directory is determined from the <code>user.dir</code> system
+ * property.
+ *
+ * @param path the path to convert to absolute path
+ *
+ * @return the absolute path that corresponds to <code>path</code>
+ */
+ static String getAbsolutePath(String path)
+ {
+ if (File.separatorChar == '\\'
+ && path.length() > 0 && path.charAt (0) == '\\')
+ {
+ // On Windows, even if the path starts with a '\\' it is not
+ // really absolute until we prefix the drive specifier from
+ // the current working directory to it.
+ return System.getProperty ("user.dir").substring (0, 2) + path;
+ }
+ else if (File.separatorChar == '\\'
+ && path.length() > 1 && path.charAt (1) == ':'
+ && ((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
+ || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z')))
+ {
+ // On Windows, a process has a current working directory for
+ // each drive and a path like "G:foo\bar" would mean the
+ // absolute path "G:\wombat\foo\bar" if "\wombat" is the
+ // working directory on the G drive.
+ String drvDir = null;
+ try
+ {
+ drvDir = new File (path.substring (0, 2)).getCanonicalPath();
+ }
+ catch (IOException e)
+ {
+ drvDir = path.substring (0, 2) + "\\";
+ }
+
+ // Note: this would return "C:\\." for the path "C:.", if "\"
+ // is the working folder on the C drive, but this is
+ // consistent with what Sun's JRE 1.4.1.01 actually returns!
+ if (path.length() > 2)
+ return drvDir + '\\' + path.substring (2, path.length());
+ else
+ return drvDir;
+ }
+ else if (path.equals(""))
+ return System.getProperty ("user.dir");
+ else
+ return System.getProperty ("user.dir") + File.separatorChar + path;
+ }
+
+ /**
+ * This method returns true if the path represents an absolute file
+ * path and false if it does not. The definition of an absolute path varies
+ * by system. As an example, on GNU systems, a path is absolute if it starts
+ * with a "/".
+ *
+ * @param path the path to check
+ *
+ * @return <code>true</code> if path represents an absolute file name,
+ * <code>false</code> otherwise.
+ */
+ static boolean isAbsolute(String path)
+ {
+ if (File.separatorChar == '\\')
+ return path.startsWith(File.separator + File.separator)
+ || (path.length() > 2
+ && ((path.charAt(0) >= 'a' && path.charAt(0) <= 'z')
+ || (path.charAt(0) >= 'A' && path.charAt(0) <= 'Z'))
+ && path.charAt(1) == ':'
+ && path.charAt(2) == '\\');
+ else
+ return path.startsWith(File.separator);
+ }
+
+ /**
+ * Returns a <code>URL</code> with the <code>file:</code>
+ * protocol that represents this file. The exact form of this URL is
+ * system dependent.
+ *
+ * @param file the file to convert to URL
+ *
+ * @return a <code>URL</code> for this object.
+ *
+ * @throws MalformedURLException if the URL cannot be created
+ * successfully.
+ */
+ static URL toURL(File file)
+ throws MalformedURLException
+ {
+ // On Win32, Sun's JDK returns URLs of the form "file:/c:/foo/bar.txt",
+ // while on UNIX, it returns URLs of the form "file:/foo/bar.txt".
+ if (File.separatorChar == '\\')
+ return new URL ("file:/" + file.getAbsolutePath().replace ('\\', '/')
+ + (file.isDirectory() ? "/" : ""));
+ else
+ return new URL ("file:" + file.getAbsolutePath()
+ + (file.isDirectory() ? "/" : ""));
+ }
+
+ /**
+ * This method returns a canonical representation of the pathname of
+ * this file. The actual form of the canonical representation is
+ * system-dependent. On the GNU system, conversion to canonical
+ * form involves the removal of redundant separators, references to
+ * "." and "..", and symbolic links.
+ * <p>
+ * Note that this method, unlike the other methods which return path
+ * names, can throw an IOException. This is because native method
+ * might be required in order to resolve the canonical path
+ *
+ * @exception IOException If an error occurs
+ */
+ public static native String toCanonicalForm(String path) throws IOException;
+}
diff --git a/libjava/classpath/vm/reference/java/io/VMObjectInputStream.java b/libjava/classpath/vm/reference/java/io/VMObjectInputStream.java
new file mode 100644
index 000000000..10e1f34cb
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/io/VMObjectInputStream.java
@@ -0,0 +1,64 @@
+/* ObjectInputStream.java -- Class used to read serialized objects
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.io;
+
+import gnu.classpath.Configuration;
+import java.lang.reflect.Constructor;
+
+final class VMObjectInputStream
+{
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javaio");
+ }
+ }
+
+ /**
+ * Allocates a new Object of type clazz but without running the
+ * default constructor on it. It then calls the given constructor on
+ * it. The given constructor method comes from the constr_clazz
+ * which is a super class of the given clazz.
+ */
+ static native Object allocateObject(Class clazz, Class constr_clazz,
+ Constructor constructor)
+ throws InstantiationException;
+}
diff --git a/libjava/classpath/vm/reference/java/io/VMObjectStreamClass.java b/libjava/classpath/vm/reference/java/io/VMObjectStreamClass.java
new file mode 100644
index 000000000..fbaf7d6c8
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/io/VMObjectStreamClass.java
@@ -0,0 +1,168 @@
+/* VMObjectStreamClass.java -- VM helper functions for ObjectStreamClass
+ Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.io;
+
+import gnu.classpath.Configuration;
+import java.lang.reflect.Field;
+
+final class VMObjectStreamClass
+{
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javaio");
+ }
+ }
+
+ /**
+ * Returns true if CLAZZ has a static class initializer
+ * (a.k.a. <clinit>).
+ */
+ static native boolean hasClassInitializer (Class clazz);
+
+ /**
+ * Sets the value of the specified field. This method handles "double".
+ * Warning ! The types are not truely checked here and final values may be
+ * assigned.
+ *
+ * @param field Field to set the value.
+ * @param obj Instance which will have its field set.
+ * @param val Value to put in the field.
+ */
+ static native void setDoubleNative(Field field, Object obj, double val)
+ throws InternalError;
+
+ /**
+ * Sets the value of the specified field. This method handles "float".
+ * Warning ! The types are not truely checked here and final values may be
+ * assigned.
+ *
+ * @param field Field to set the value.
+ * @param obj Instance which will have its field set.
+ * @param val Value to put in the field.
+ */
+ static native void setFloatNative(Field field, Object obj, float val)
+ throws InternalError;
+
+ /**
+ * Sets the value of the specified field. This method handles "long".
+ * Warning ! The types are not truely checked here and final values may be
+ * assigned.
+ *
+ * @param field Field to set the value.
+ * @param obj Instance which will have its field set.
+ * @param val Value to put in the field.
+ */
+ static native void setLongNative(Field field, Object obj, long val)
+ throws InternalError;
+
+ /**
+ * Sets the value of the specified field. This method handles "int".
+ * Warning ! The types are not truely checked here and final values may be
+ * assigned.
+ *
+ * @param field Field to set the value.
+ * @param obj Instance which will have its field set.
+ * @param val Value to put in the field.
+ */
+ static native void setIntNative(Field field, Object obj, int val)
+ throws InternalError;
+
+ /**
+ * Sets the value of the specified field. This method handles "short".
+ * Warning ! The types are not truely checked here and final values may be
+ * assigned.
+ *
+ * @param field Field to set the value.
+ * @param obj Instance which will have its field set.
+ * @param val Value to put in the field.
+ */
+ static native void setShortNative(Field field, Object obj, short val)
+ throws InternalError;
+
+ /**
+ * Sets the value of the specified field. This method handles "char".
+ * Warning ! The types are not truely checked here and final values may be
+ * assigned.
+ *
+ * @param field Field to set the value.
+ * @param obj Instance which will have its field set.
+ * @param val Value to put in the field.
+ */
+ static native void setCharNative(Field field, Object obj, char val)
+ throws InternalError;
+
+ /**
+ * Sets the value of the specified field. This method handles "byte".
+ * Warning ! The types are not truely checked here and final values may be
+ * assigned.
+ *
+ * @param field Field to set the value.
+ * @param obj Instance which will have its field set.
+ * @param val Value to put in the field.
+ */
+ static native void setByteNative(Field field, Object obj, byte val)
+ throws InternalError;
+
+ /**
+ * Sets the value of the specified field. This method handles "boolean".
+ * Warning ! The types are not truely checked here and final values may be
+ * assigned.
+ *
+ * @param field Field to set the value.
+ * @param obj Instance which will have its field set.
+ * @param val Value to put in the field.
+ */
+ static native void setBooleanNative(Field field, Object obj, boolean val)
+ throws InternalError;
+
+ /**
+ * Sets the value of the specified field. This method handles "object".
+ * Warning ! The types are not truely checked here and final values may be
+ * assigned.
+ *
+ * @param field Field to set the value.
+ * @param obj Instance which will have its field set.
+ * @param val Value to put in the field.
+ */
+ static native void setObjectNative(Field field, Object obj, Object val)
+ throws InternalError;
+
+}
diff --git a/libjava/classpath/vm/reference/java/lang/VMClass.java b/libjava/classpath/vm/reference/java/lang/VMClass.java
new file mode 100644
index 000000000..a0091c073
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/VMClass.java
@@ -0,0 +1,469 @@
+/* VMClass.java -- VM Specific Class methods
+ Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/*
+ * This class is a reference version, mainly for compiling a class library
+ * jar. It is likely that VM implementers replace this with their own
+ * version that can communicate effectively with the VM.
+ */
+
+/**
+ *
+ * @author Etienne Gagnon (etienne.gagnon@uqam.ca)
+ * @author Archie Cobbs (archie@dellroad.org)
+ * @author C. Brian Jones (cbj@gnu.org)
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+final class VMClass
+{
+
+ // Only static methods. Cannot be instantiated.
+ private VMClass()
+ {
+ }
+
+ /**
+ * Discover whether an Object is an instance of this Class. Think of it
+ * as almost like <code>o instanceof (this class)</code>.
+ *
+ * @param klass the Class object that's calling us
+ * @param o the Object to check
+ * @return whether o is an instance of this class
+ * @since 1.1
+ */
+ static native boolean isInstance(Class klass, Object o);
+
+ /**
+ * Discover whether an instance of the Class parameter would be an
+ * instance of this Class as well. Think of doing
+ * <code>isInstance(c.newInstance())</code> or even
+ * <code>c.newInstance() instanceof (this class)</code>. While this
+ * checks widening conversions for objects, it must be exact for primitive
+ * types.
+ *
+ * @param klass the Class object that's calling us
+ * @param c the class to check
+ * @return whether an instance of c would be an instance of this class
+ * as well
+ * @throws NullPointerException if c is null
+ * @since 1.1
+ */
+ static native boolean isAssignableFrom(Class klass, Class c);
+
+ /**
+ * Check whether this class is an interface or not. Array types are not
+ * interfaces.
+ *
+ * @param klass the Class object that's calling us
+ * @return whether this class is an interface or not
+ */
+ static native boolean isInterface(Class klass);
+
+ /**
+ * Return whether this class is a primitive type. A primitive type class
+ * is a class representing a kind of "placeholder" for the various
+ * primitive types, or void. You can access the various primitive type
+ * classes through java.lang.Boolean.TYPE, java.lang.Integer.TYPE, etc.,
+ * or through boolean.class, int.class, etc.
+ *
+ * @param klass the Class object that's calling us
+ * @return whether this class is a primitive type
+ * @see Boolean#TYPE
+ * @see Byte#TYPE
+ * @see Character#TYPE
+ * @see Short#TYPE
+ * @see Integer#TYPE
+ * @see Long#TYPE
+ * @see Float#TYPE
+ * @see Double#TYPE
+ * @see Void#TYPE
+ * @since 1.1
+ */
+ static native boolean isPrimitive(Class klass);
+
+ /**
+ * Get the name of this class, separated by dots for package separators.
+ * Primitive types and arrays are encoded as:
+ * <pre>
+ * boolean Z
+ * byte B
+ * char C
+ * short S
+ * int I
+ * long J
+ * float F
+ * double D
+ * void V
+ * array type [<em>element type</em>
+ * class or interface, alone: &lt;dotted name&gt;
+ * class or interface, as element type: L&lt;dotted name&gt;;
+ *
+ * @param klass the Class object that's calling us
+ * @return the name of this class
+ */
+ static native String getName(Class klass);
+
+ /**
+ * Get the direct superclass of this class. If this is an interface,
+ * Object, a primitive type, or void, it will return null. If this is an
+ * array type, it will return Object.
+ *
+ * @param klass the Class object that's calling us
+ * @return the direct superclass of this class
+ */
+ static native Class getSuperclass(Class klass);
+
+ /**
+ * Get the interfaces this class <EM>directly</EM> implements, in the
+ * order that they were declared. This returns an empty array, not null,
+ * for Object, primitives, void, and classes or interfaces with no direct
+ * superinterface. Array types return Cloneable and Serializable.
+ *
+ * @param klass the Class object that's calling us
+ * @return the interfaces this class directly implements
+ */
+ static native Class[] getInterfaces(Class klass);
+
+ /**
+ * If this is an array, get the Class representing the type of array.
+ * Examples: "[[Ljava.lang.String;" would return "[Ljava.lang.String;", and
+ * calling getComponentType on that would give "java.lang.String". If
+ * this is not an array, returns null.
+ *
+ * @param klass the Class object that's calling us
+ * @return the array type of this class, or null
+ * @see Array
+ * @since 1.1
+ */
+ static native Class getComponentType(Class klass);
+
+ /**
+ * Get the modifiers of this class. These can be decoded using Modifier,
+ * and is limited to one of public, protected, or private, and any of
+ * final, static, abstract, or interface. An array class has the same
+ * public, protected, or private modifier as its component type, and is
+ * marked final but not an interface. Primitive types and void are marked
+ * public and final, but not an interface.
+ *
+ * @param klass the Class object that's calling us
+ * @param ignoreInnerClassesAttrib if set, return the real modifiers, not
+ * the ones specified in the InnerClasses attribute.
+ * @return the modifiers of this class
+ * @see Modifier
+ * @since 1.1
+ */
+ static native int getModifiers(Class klass, boolean ignoreInnerClassesAttrib);
+
+ /**
+ * If this is a nested or inner class, return the class that declared it.
+ * If not, return null.
+ *
+ * @param klass the Class object that's calling us
+ * @return the declaring class of this class
+ * @since 1.1
+ */
+ static native Class getDeclaringClass(Class klass);
+
+ /**
+ * Like <code>getDeclaredClasses()</code> but without the security checks.
+ *
+ * @param klass the Class object that's calling us
+ * @param publicOnly Only public classes should be returned
+ */
+ static native Class[] getDeclaredClasses(Class klass, boolean publicOnly);
+
+ /**
+ * Like <code>getDeclaredFields()</code> but without the security checks.
+ *
+ * @param klass the Class object that's calling us
+ * @param publicOnly Only public fields should be returned
+ */
+ static native Field[] getDeclaredFields(Class klass, boolean publicOnly);
+
+ /**
+ * Like <code>getDeclaredMethods()</code> but without the security checks.
+ *
+ * @param klass the Class object that's calling us
+ * @param publicOnly Only public methods should be returned
+ */
+ static native Method[] getDeclaredMethods(Class klass, boolean publicOnly);
+
+ /**
+ * Like <code>getDeclaredConstructors()</code> but without
+ * the security checks.
+ *
+ * @param klass the Class object that's calling us
+ * @param publicOnly Only public constructors should be returned
+ */
+ static native Constructor[] getDeclaredConstructors(Class klass, boolean publicOnly);
+
+ /**
+ * Return the class loader of this class.
+ *
+ * @param klass the Class object that's calling us
+ * @return the class loader
+ */
+ static native ClassLoader getClassLoader(Class klass);
+
+ /**
+ * Load the requested class and record the specified loader as the
+ * initiating class loader.
+ *
+ * @param name the name of the class to find
+ * @param initialize should the class initializer be run?
+ * @param loader the class loader to use (or null for the bootstrap loader)
+ * @return the Class object representing the class or null for noop
+ * @throws ClassNotFoundException if the class was not found by the
+ * class loader
+ * @throws LinkageError if linking the class fails
+ * @throws ExceptionInInitializerError if the class loads, but an exception
+ * occurs during initialization
+ */
+ static native Class forName(String name, boolean initialize,
+ ClassLoader loader)
+ throws ClassNotFoundException;
+
+ /**
+ * Return whether this class is an array type.
+ *
+ * @param klass the Class object that's calling us
+ * @return true if this class is an array type
+ * operation
+ */
+ static native boolean isArray(Class klass);
+
+ /**
+ * Throw a checked exception without declaring it.
+ */
+ static native void throwException(Throwable t);
+
+ /**
+ * Returns the simple name for the specified class, as used in the source
+ * code. For normal classes, this is the content returned by
+ * <code>getName()</code> which follows the last ".". Anonymous
+ * classes have no name, and so the result of calling this method is
+ * "". The simple name of an array consists of the simple name of
+ * its component type, followed by "[]". Thus, an array with the
+ * component type of an anonymous class has a simple name of simply
+ * "[]".
+ *
+ * @param klass the class whose simple name should be returned.
+ * @return the simple name for this class.
+ */
+ static String getSimpleName(Class klass)
+ {
+ if (isAnonymousClass(klass))
+ return "";
+ if (isArray(klass))
+ {
+ return getComponentType(klass).getSimpleName() + "[]";
+ }
+ String fullName = getName(klass);
+ int pos = fullName.lastIndexOf("$");
+ if (pos == -1)
+ pos = 0;
+ else
+ {
+ ++pos;
+ while (Character.isDigit(fullName.charAt(pos)))
+ ++pos;
+ }
+ int packagePos = fullName.lastIndexOf(".", pos);
+ if (packagePos == -1)
+ return fullName.substring(pos);
+ else
+ return fullName.substring(packagePos + 1);
+ }
+
+ /**
+ * Returns all annotations directly defined by the specified class. If
+ * there are no annotations associated with this class, then a zero-length
+ * array will be returned. The returned array may be modified by the client
+ * code, but this will have no effect on the annotation content of this
+ * class, and hence no effect on the return value of this method for
+ * future callers.
+ *
+ * @param klass the class whose annotations should be returned.
+ * @return the annotations directly defined by the specified class.
+ * @since 1.5
+ */
+ static native Annotation[] getDeclaredAnnotations(Class klass);
+
+ /**
+ * <p>
+ * Returns the canonical name of the specified class, as defined by section
+ * 6.7 of the Java language specification. Each package, top-level class,
+ * top-level interface and primitive type has a canonical name. A member
+ * class has a canonical name, if its parent class has one. Likewise,
+ * an array type has a canonical name, if its component type does.
+ * Local or anonymous classes do not have canonical names.
+ * </p>
+ * <p>
+ * The canonical name for top-level classes, top-level interfaces and
+ * primitive types is always the same as the fully-qualified name.
+ * For array types, the canonical name is the canonical name of its
+ * component type with `[]' appended.
+ * </p>
+ * <p>
+ * The canonical name of a member class always refers to the place where
+ * the class was defined, and is composed of the canonical name of the
+ * defining class and the simple name of the member class, joined by `.'.
+ * For example, if a <code>Person</code> class has an inner class,
+ * <code>M</code>, then both its fully-qualified name and canonical name
+ * is <code>Person.M</code>. A subclass, <code>Staff</code>, of
+ * <code>Person</code> refers to the same inner class by the fully-qualified
+ * name of <code>Staff.M</code>, but its canonical name is still
+ * <code>Person.M</code>.
+ * </p>
+ * <p>
+ * Where no canonical name is present, <code>null</code> is returned.
+ * </p>
+ *
+ * @param klass the class whose canonical name should be retrieved.
+ * @return the canonical name of the class, or <code>null</code> if the
+ * class doesn't have a canonical name.
+ * @since 1.5
+ */
+ static String getCanonicalName(Class klass)
+ {
+ if (isLocalClass(klass) || isAnonymousClass(klass))
+ return null;
+ if (isArray(klass))
+ {
+ String componentName = getComponentType(klass).getCanonicalName();
+ if (componentName != null)
+ return componentName + "[]";
+ }
+ if (isMemberClass(klass))
+ {
+ String memberName = getDeclaringClass(klass).getCanonicalName();
+ if (memberName != null)
+ return memberName + "." + getSimpleName(klass);
+ else
+ return memberName;
+ }
+ return getName(klass);
+ }
+
+ /**
+ * Returns the class which immediately encloses the specified class. If
+ * the class is a top-level class, this method returns <code>null</code>.
+ *
+ * @param klass the class whose enclosing class should be returned.
+ * @return the immediate enclosing class, or <code>null</code> if this is
+ * a top-level class.
+ * @since 1.5
+ */
+ static native Class getEnclosingClass(Class klass);
+
+ /**
+ * Returns the constructor which immediately encloses the specified class.
+ * If the class is a top-level class, or a local or anonymous class
+ * immediately enclosed by a type definition, instance initializer
+ * or static initializer, then <code>null</code> is returned.
+ *
+ * @param klass the class whose enclosing constructor should be returned.
+ * @return the immediate enclosing constructor if the specified class is
+ * declared within a constructor. Otherwise, <code>null</code>
+ * is returned.
+ * @since 1.5
+ */
+ static native Constructor getEnclosingConstructor(Class klass);
+
+ /**
+ * Returns the method which immediately encloses the specified class. If
+ * the class is a top-level class, or a local or anonymous class
+ * immediately enclosed by a type definition, instance initializer
+ * or static initializer, then <code>null</code> is returned.
+ *
+ * @param klass the class whose enclosing method should be returned.
+ * @return the immediate enclosing method if the specified class is
+ * declared within a method. Otherwise, <code>null</code>
+ * is returned.
+ * @since 1.5
+ */
+ static native Method getEnclosingMethod(Class klass);
+
+ /**
+ * Returns the class signature as specified in Class File Format
+ * chapter in the VM specification, or null if the class is not
+ * generic.
+ *
+ * @param klass the klass to test.
+ * @return a ClassSignature string.
+ * @since 1.5
+ */
+ static native String getClassSignature(Class klass);
+
+ /**
+ * Returns true if the specified class represents an anonymous class.
+ *
+ * @param klass the klass to test.
+ * @return true if the specified class represents an anonymous class.
+ * @since 1.5
+ */
+ static native boolean isAnonymousClass(Class klass);
+
+ /**
+ * Returns true if the specified class represents an local class.
+ *
+ * @param klass the klass to test.
+ * @return true if the specified class represents an local class.
+ * @since 1.5
+ */
+ static native boolean isLocalClass(Class klass);
+
+ /**
+ * Returns true if the specified class represents an member class.
+ *
+ * @param klass the klass to test.
+ * @return true if the specified class represents an member class.
+ * @since 1.5
+ */
+ static native boolean isMemberClass(Class klass);
+
+} // class VMClass
diff --git a/libjava/classpath/vm/reference/java/lang/VMClassLoader.java b/libjava/classpath/vm/reference/java/lang/VMClassLoader.java
new file mode 100644
index 000000000..c1d462588
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/VMClassLoader.java
@@ -0,0 +1,431 @@
+/* VMClassLoader.java -- Reference implementation of native interface
+ required by ClassLoader
+ Copyright (C) 1998, 2001, 2002, 2004, 2005, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang;
+
+import gnu.classpath.Configuration;
+import gnu.classpath.SystemProperties;
+import gnu.java.lang.InstrumentationImpl;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.instrument.Instrumentation;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.zip.ZipFile;
+
+/**
+ * java.lang.VMClassLoader is a package-private helper for VMs to implement
+ * on behalf of java.lang.ClassLoader.
+ *
+ * @author John Keiser
+ * @author Mark Wielaard (mark@klomp.org)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ */
+final class VMClassLoader
+{
+
+
+ /** packages loaded by the bootstrap class loader */
+ static final HashMap definedPackages = new HashMap();
+
+ /** jars from property java.boot.class.path */
+ static final HashMap bootjars = new HashMap();
+
+
+ /**
+ * Converts the array string of native package names to
+ * Packages. The packages are then put into the
+ * definedPackages hashMap
+ */
+ static
+ {
+ String[] packages = getBootPackages();
+
+ if( packages != null)
+ {
+ String specName =
+ SystemProperties.getProperty("java.specification.name");
+ String vendor =
+ SystemProperties.getProperty("java.specification.vendor");
+ String version =
+ SystemProperties.getProperty("java.specification.version");
+
+ Package p;
+
+ for(int i = 0; i < packages.length; i++)
+ {
+ p = new Package(packages[i],
+ specName,
+ vendor,
+ version,
+ "GNU Classpath",
+ "GNU",
+ Configuration.CLASSPATH_VERSION,
+ null,
+ null);
+
+ definedPackages.put(packages[i], p);
+ }
+ }
+ }
+
+
+ /**
+ * Helper to define a class using a string of bytes. This assumes that
+ * the security checks have already been performed, if necessary.
+ *
+ * Implementations of this method are advised to consider the
+ * situation where user code modifies the byte array after it has
+ * been passed to defineClass. This can be handled by making a
+ * private copy of the array, or arranging to only read any given
+ * byte a single time.
+ *
+ * @param name the name to give the class, or null if unknown
+ * @param data the data representing the classfile, in classfile format
+ * @param offset the offset into the data where the classfile starts
+ * @param len the length of the classfile data in the array
+ * @param pd the protection domain
+ * @return the class that was defined
+ * @throws ClassFormatError if data is not in proper classfile format
+ */
+ static final native Class defineClass(ClassLoader cl, String name,
+ byte[] data, int offset, int len,
+ ProtectionDomain pd)
+ throws ClassFormatError;
+
+ /**
+ * Helper to resolve all references to other classes from this class.
+ *
+ * @param c the class to resolve
+ */
+ static final native void resolveClass(Class c);
+
+ /**
+ * Helper to load a class from the bootstrap class loader.
+ *
+ * @param name the class name to load
+ * @param resolve whether to resolve it
+ * @return the class, loaded by the bootstrap classloader or null
+ * if the class wasn't found. Returning null is equivalent to throwing
+ * a ClassNotFoundException (but a possible performance optimization).
+ */
+ static final native Class loadClass(String name, boolean resolve)
+ throws ClassNotFoundException;
+
+ /**
+ * Helper to load a resource from the bootstrap class loader.
+ *
+ * @param name the resource to find
+ * @return the URL to the resource
+ */
+ static URL getResource(String name)
+ {
+ Enumeration e = getResources(name);
+ if (e.hasMoreElements())
+ return (URL)e.nextElement();
+ return null;
+ }
+ /**
+ * Helper to get a list of resources from the bootstrap class loader.
+ *
+ * @param name the resource to find
+ * @return an enumeration of resources
+ */
+ static Enumeration getResources(String name)
+ {
+ StringTokenizer st = new StringTokenizer(
+ SystemProperties.getProperty("java.boot.class.path", "."),
+ File.pathSeparator);
+ Vector v = new Vector();
+ while (st.hasMoreTokens())
+ {
+ File file = new File(st.nextToken());
+ if (file.isDirectory())
+ {
+ try
+ {
+ File f = new File(file, name);
+ if (!f.exists()) continue;
+ v.add(new URL("file://" + f.getAbsolutePath()));
+ }
+ catch (MalformedURLException e)
+ {
+ throw new Error(e);
+ }
+ }
+ else if (file.isFile())
+ {
+ ZipFile zip;
+ synchronized(bootjars)
+ {
+ zip = (ZipFile) bootjars.get(file.getName());
+ }
+ if(zip == null)
+ {
+ try
+ {
+ zip = new ZipFile(file);
+ synchronized(bootjars)
+ {
+ bootjars.put(file.getName(), zip);
+ }
+ }
+ catch (IOException e)
+ {
+ continue;
+ }
+ }
+ String zname = name.startsWith("/") ? name.substring(1) : name;
+ if (zip.getEntry(zname) == null)
+ continue;
+ try
+ {
+ v.add(new URL("jar:file://"
+ + file.getAbsolutePath() + "!/" + zname));
+ }
+ catch (MalformedURLException e)
+ {
+ throw new Error(e);
+ }
+ }
+ }
+ return v.elements();
+ }
+
+
+ /**
+ * Returns a String[] of native package names. The default
+ * implementation tries to load a list of package from
+ * the META-INF/INDEX.LIST file in the boot jar file.
+ * If not found or if any exception is raised, it returns
+ * an empty array. You may decide this needs native help.
+ */
+ private static String[] getBootPackages()
+ {
+ URL indexList = getResource("META-INF/INDEX.LIST");
+ if (indexList != null)
+ {
+ try
+ {
+ Set packageSet = new HashSet();
+ String line;
+ int lineToSkip = 3;
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(
+ indexList.openStream()));
+ while ((line = reader.readLine()) != null)
+ {
+ if (lineToSkip == 0)
+ {
+ if (line.length() == 0)
+ lineToSkip = 1;
+ else
+ packageSet.add(line.replace('/', '.'));
+ }
+ else
+ lineToSkip--;
+ }
+ reader.close();
+ return (String[]) packageSet.toArray(new String[packageSet.size()]);
+ }
+ catch (IOException e)
+ {
+ return new String[0];
+ }
+ }
+ else
+ return new String[0];
+ }
+
+
+ /**
+ * Helper to get a package from the bootstrap class loader.
+ *
+ * @param name the name to find
+ * @return the named package, if it exists
+ */
+ static Package getPackage(String name)
+ {
+ return (Package)definedPackages.get(name);
+ }
+
+
+
+ /**
+ * Helper to get all packages from the bootstrap class loader.
+ *
+ * @return all named packages, if any exist
+ */
+ static Package[] getPackages()
+ {
+ Package[] packages = new Package[definedPackages.size()];
+ definedPackages.values().toArray(packages);
+ return packages;
+ }
+
+ /**
+ * Helper for java.lang.Integer, Byte, etc to get the TYPE class
+ * at initialization time. The type code is one of the chars that
+ * represents the primitive type as in JNI.
+ *
+ * <ul>
+ * <li>'Z' - boolean</li>
+ * <li>'B' - byte</li>
+ * <li>'C' - char</li>
+ * <li>'D' - double</li>
+ * <li>'F' - float</li>
+ * <li>'I' - int</li>
+ * <li>'J' - long</li>
+ * <li>'S' - short</li>
+ * <li>'V' - void</li>
+ * </ul>
+ *
+ * @param type the primitive type
+ * @return a "bogus" class representing the primitive type
+ */
+ static final native Class getPrimitiveClass(char type);
+
+ /**
+ * The system default for assertion status. This is used for all system
+ * classes (those with a null ClassLoader), as well as the initial value for
+ * every ClassLoader's default assertion status.
+ *
+ * XXX - Not implemented yet; this requires native help.
+ *
+ * @return the system-wide default assertion status
+ */
+ static final boolean defaultAssertionStatus()
+ {
+ return true;
+ }
+
+ /**
+ * The system default for package assertion status. This is used for all
+ * ClassLoader's packageAssertionStatus defaults. It must be a map of
+ * package names to Boolean.TRUE or Boolean.FALSE, with the unnamed package
+ * represented as a null key.
+ *
+ * XXX - Not implemented yet; this requires native help.
+ *
+ * @return a (read-only) map for the default packageAssertionStatus
+ */
+ static final Map packageAssertionStatus()
+ {
+ return new HashMap();
+ }
+
+ /**
+ * The system default for class assertion status. This is used for all
+ * ClassLoader's classAssertionStatus defaults. It must be a map of
+ * class names to Boolean.TRUE or Boolean.FALSE
+ *
+ * XXX - Not implemented yet; this requires native help.
+ *
+ * @return a (read-only) map for the default classAssertionStatus
+ */
+ static final Map classAssertionStatus()
+ {
+ return new HashMap();
+ }
+
+ static ClassLoader getSystemClassLoader()
+ {
+ return ClassLoader.defaultGetSystemClassLoader();
+ }
+
+ /**
+ * Find the class if this class loader previously defined this class
+ * or if this class loader has been recorded as the initiating class loader
+ * for this class.
+ */
+ static native Class findLoadedClass(ClassLoader cl, String name);
+
+ /**
+ * The Instrumentation object created by the vm when agents are defined.
+ */
+ static final Instrumentation instrumenter = null;
+
+ /**
+ * Call the transformers of the possible Instrumentation object. This
+ * implementation assumes the instrumenter is a
+ * <code>InstrumentationImpl</code> object. VM implementors would
+ * have to redefine this method if they provide their own implementation
+ * of the <code>Instrumentation</code> interface.
+ *
+ * @param loader the initiating loader
+ * @param name the name of the class
+ * @param data the data representing the classfile, in classfile format
+ * @param offset the offset into the data where the classfile starts
+ * @param len the length of the classfile data in the array
+ * @param pd the protection domain
+ * @return the new data representing the classfile
+ */
+ static final Class defineClassWithTransformers(ClassLoader loader,
+ String name, byte[] data, int offset, int len, ProtectionDomain pd)
+ {
+
+ if (instrumenter != null)
+ {
+ byte[] modifiedData = new byte[len];
+ System.arraycopy(data, offset, modifiedData, 0, len);
+ String jvmName = name.replace('.', '/');
+ modifiedData =
+ ((InstrumentationImpl)instrumenter).callTransformers(loader, jvmName,
+ null, pd, modifiedData);
+
+ return defineClass(loader, name, modifiedData, 0, modifiedData.length,
+ pd);
+ }
+ else
+ {
+ return defineClass(loader, name, data, offset, len, pd);
+ }
+ }
+}
diff --git a/libjava/classpath/vm/reference/java/lang/VMCompiler.java b/libjava/classpath/vm/reference/java/lang/VMCompiler.java
new file mode 100644
index 000000000..fe7400756
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/VMCompiler.java
@@ -0,0 +1,112 @@
+/* VMClassLoader.java -- Reference implementation of compiler interface
+ Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+/**
+ * This class is just a per-VM reflection of java.lang.Compiler.
+ * All methods are defined identically.
+ */
+final class VMCompiler
+{
+ /**
+ * Don't allow new `Compiler's to be made.
+ */
+ private VMCompiler()
+ {
+ }
+
+ /**
+ * Compile the class named by <code>oneClass</code>.
+ *
+ * @param oneClass the class to compile
+ * @return <code>false</code> if no compiler is available or
+ * compilation failed, <code>true</code> if compilation succeeded
+ * @throws NullPointerException if oneClass is null
+ */
+ public static boolean compileClass(Class oneClass)
+ {
+ // Never succeed.
+ return false;
+ }
+
+ /**
+ * Compile the classes whose name matches <code>classNames</code>.
+ *
+ * @param classNames the name of classes to compile
+ * @return <code>false</code> if no compiler is available or
+ * compilation failed, <code>true</code> if compilation succeeded
+ * @throws NullPointerException if classNames is null
+ */
+ public static boolean compileClasses(String classNames)
+ {
+ // Note the incredibly lame interface. Always fail.
+ return false;
+ }
+
+ /**
+ * This method examines the argument and performs an operation
+ * according to the compilers documentation. No specific operation
+ * is required.
+ *
+ * @param arg a compiler-specific argument
+ * @return a compiler-specific value, including null
+ * @throws NullPointerException if the compiler doesn't like a null arg
+ */
+ public static Object command(Object arg)
+ {
+ // Our implementation defines this to a no-op.
+ return null;
+ }
+
+ /**
+ * Calling <code>Compiler.enable()</code> will cause the compiler
+ * to resume operation if it was previously disabled; provided that a
+ * compiler even exists.
+ */
+ public static void enable()
+ {
+ }
+
+ /**
+ * Calling <code>Compiler.disable()</code> will cause the compiler
+ * to be suspended; provided that a compiler even exists.
+ */
+ public static void disable()
+ {
+ }
+}
diff --git a/libjava/classpath/vm/reference/java/lang/VMDouble.java b/libjava/classpath/vm/reference/java/lang/VMDouble.java
new file mode 100644
index 000000000..8e523cd2e
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/VMDouble.java
@@ -0,0 +1,115 @@
+/* VMDouble.java -- VM Specific Double methods
+ Copyright (C) 2003, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import gnu.classpath.Configuration;
+
+/*
+ * This class is a reference version, mainly for compiling a class library
+ * jar. It is likely that VM implementers replace this with their own
+ * version that can communicate effectively with the VM.
+ */
+
+/**
+ * Code relocated from java.lang.Double by
+ * @author Dave Grove (groved@us.ibm.com)
+ */
+final class VMDouble
+{
+
+ /**
+ * Load native routines necessary for this class.
+ */
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javalang");
+ }
+
+ initIDs();
+ }
+
+ /**
+ * Convert the double to the IEEE 754 floating-point "double format" bit
+ * layout. Bit 63 (the most significant) is the sign bit, bits 62-52
+ * (masked by 0x7ff0000000000000L) represent the exponent, and bits 51-0
+ * (masked by 0x000fffffffffffffL) are the mantissa. This function
+ * leaves NaN alone, rather than collapsing to a canonical value. The
+ * result of this function can be used as the argument to
+ * <code>Double.longBitsToDouble(long)</code> to obtain the original
+ * <code>double</code> value.
+ *
+ * @param value the <code>double</code> to convert
+ * @return the bits of the <code>double</code>
+ * @see #longBitsToDouble(long)
+ */
+ public static native long doubleToRawLongBits(double value);
+
+ /**
+ * Convert the argument in IEEE 754 floating-point "double format" bit
+ * layout to the corresponding float. Bit 63 (the most significant) is the
+ * sign bit, bits 62-52 (masked by 0x7ff0000000000000L) represent the
+ * exponent, and bits 51-0 (masked by 0x000fffffffffffffL) are the mantissa.
+ * This function leaves NaN alone, so that you can recover the bit pattern
+ * with <code>Double.doubleToRawLongBits(double)</code>.
+ *
+ * @param bits the bits to convert
+ * @return the <code>double</code> represented by the bits
+ * @see #doubleToLongBits(double)
+ * @see #doubleToRawLongBits(double)
+ */
+ public static native double longBitsToDouble(long bits);
+
+ /**
+ * Helper method to convert to string.
+ *
+ * @param d the double to convert
+ * @param isFloat true if the conversion is requested by Float (results in
+ * fewer digits)
+ */
+ public static native String toString(double d, boolean isFloat);
+
+ /**
+ * Initialize JNI cache. This method is called only by the
+ * static initializer when using JNI.
+ */
+ public static native void initIDs();
+
+ public static native double parseDouble(String str);
+}
diff --git a/libjava/classpath/vm/reference/java/lang/VMFloat.java b/libjava/classpath/vm/reference/java/lang/VMFloat.java
new file mode 100644
index 000000000..ba523d697
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/VMFloat.java
@@ -0,0 +1,118 @@
+/* VMFloat.java -- VM Specific Float methods
+ Copyright (C) 2003 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import gnu.classpath.Configuration;
+
+/*
+ * This class is a reference version, mainly for compiling a class library
+ * jar. It is likely that VM implementers replace this with their own
+ * version that can communicate effectively with the VM.
+ */
+
+/**
+ * Code relocated from java.lang.Float by
+ * @author Dave Grove <groved@us.ibm.com>
+ */
+final class VMFloat
+{
+
+ /**
+ * Load native routines necessary for this class.
+ */
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javalang");
+ }
+ }
+
+ /**
+ * Convert the float to the IEEE 754 floating-point "single format" bit
+ * layout. Bit 31 (the most significant) is the sign bit, bits 30-23
+ * (masked by 0x7f800000) represent the exponent, and bits 22-0
+ * (masked by 0x007fffff) are the mantissa. This function leaves NaN alone,
+ * rather than collapsing to a canonical value. The result of this function
+ * can be used as the argument to <code>Float.intBitsToFloat(int)</code> to
+ * obtain the original <code>float</code> value.
+ *
+ * @param value the <code>float</code> to convert
+ * @return the bits of the <code>float</code>
+ * @see #intBitsToFloat(int)
+ */
+ static native int floatToRawIntBits(float value);
+
+ /**
+ * Convert the argument in IEEE 754 floating-point "single format" bit
+ * layout to the corresponding float. Bit 31 (the most significant) is the
+ * sign bit, bits 30-23 (masked by 0x7f800000) represent the exponent, and
+ * bits 22-0 (masked by 0x007fffff) are the mantissa. This function leaves
+ * NaN alone, so that you can recover the bit pattern with
+ * <code>Float.floatToRawIntBits(float)</code>.
+ *
+ * @param bits the bits to convert
+ * @return the <code>float</code> represented by the bits
+ * @see #floatToIntBits(float)
+ * @see #floatToRawIntBits(float)
+ */
+ static native float intBitsToFloat(int bits);
+
+ /**
+ * @param f the <code>float</code> to convert
+ * @return the <code>String</code> representing the <code>float</code>
+ */
+ static String toString(float f)
+ {
+ return VMDouble.toString(f, true);
+ }
+
+ /**
+ * @param str the <code>String</code> to convert
+ * @return the <code>float</code> value of <code>s</code>
+ * @throws NumberFormatException if <code>str</code> cannot be parsed as a
+ * <code>float</code>
+ * @throws NullPointerException if <code>str</code> is null
+ */
+ static float parseFloat(String str)
+ {
+ // XXX Rounding parseDouble() causes some errors greater than 1 ulp from
+ // the infinitely precise decimal.
+ return (float) Double.parseDouble(str);
+ }
+} // class VMFloat
diff --git a/libjava/classpath/vm/reference/java/lang/VMMath.java b/libjava/classpath/vm/reference/java/lang/VMMath.java
new file mode 100644
index 000000000..dc5fd4207
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/VMMath.java
@@ -0,0 +1,493 @@
+/* VMMath.java -- Common mathematical functions.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang;
+
+import gnu.classpath.Configuration;
+
+class VMMath
+{
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javalang");
+ }
+ }
+
+ /**
+ * The trigonometric function <em>sin</em>. The sine of NaN or infinity is
+ * NaN, and the sine of 0 retains its sign. This is accurate within 1 ulp,
+ * and is semi-monotonic.
+ *
+ * @param a the angle (in radians)
+ * @return sin(a)
+ */
+ public static native double sin(double a);
+
+ /**
+ * The trigonometric function <em>cos</em>. The cosine of NaN or infinity is
+ * NaN. This is accurate within 1 ulp, and is semi-monotonic.
+ *
+ * @param a the angle (in radians)
+ * @return cos(a)
+ */
+ public static native double cos(double a);
+
+ /**
+ * The trigonometric function <em>tan</em>. The tangent of NaN or infinity
+ * is NaN, and the tangent of 0 retains its sign. This is accurate within 1
+ * ulp, and is semi-monotonic.
+ *
+ * @param a the angle (in radians)
+ * @return tan(a)
+ */
+ public static native double tan(double a);
+
+ /**
+ * The trigonometric function <em>arcsin</em>. The range of angles returned
+ * is -pi/2 to pi/2 radians (-90 to 90 degrees). If the argument is NaN or
+ * its absolute value is beyond 1, the result is NaN; and the arcsine of
+ * 0 retains its sign. This is accurate within 1 ulp, and is semi-monotonic.
+ *
+ * @param a the sin to turn back into an angle
+ * @return arcsin(a)
+ */
+ public static native double asin(double a);
+
+ /**
+ * The trigonometric function <em>arccos</em>. The range of angles returned
+ * is 0 to pi radians (0 to 180 degrees). If the argument is NaN or
+ * its absolute value is beyond 1, the result is NaN. This is accurate
+ * within 1 ulp, and is semi-monotonic.
+ *
+ * @param a the cos to turn back into an angle
+ * @return arccos(a)
+ */
+ public static native double acos(double a);
+
+ /**
+ * The trigonometric function <em>arcsin</em>. The range of angles returned
+ * is -pi/2 to pi/2 radians (-90 to 90 degrees). If the argument is NaN, the
+ * result is NaN; and the arctangent of 0 retains its sign. This is accurate
+ * within 1 ulp, and is semi-monotonic.
+ *
+ * @param a the tan to turn back into an angle
+ * @return arcsin(a)
+ * @see #atan2(double, double)
+ */
+ public static native double atan(double a);
+
+ /**
+ * A special version of the trigonometric function <em>arctan</em>, for
+ * converting rectangular coordinates <em>(x, y)</em> to polar
+ * <em>(r, theta)</em>. This computes the arctangent of x/y in the range
+ * of -pi to pi radians (-180 to 180 degrees). Special cases:<ul>
+ * <li>If either argument is NaN, the result is NaN.</li>
+ * <li>If the first argument is positive zero and the second argument is
+ * positive, or the first argument is positive and finite and the second
+ * argument is positive infinity, then the result is positive zero.</li>
+ * <li>If the first argument is negative zero and the second argument is
+ * positive, or the first argument is negative and finite and the second
+ * argument is positive infinity, then the result is negative zero.</li>
+ * <li>If the first argument is positive zero and the second argument is
+ * negative, or the first argument is positive and finite and the second
+ * argument is negative infinity, then the result is the double value
+ * closest to pi.</li>
+ * <li>If the first argument is negative zero and the second argument is
+ * negative, or the first argument is negative and finite and the second
+ * argument is negative infinity, then the result is the double value
+ * closest to -pi.</li>
+ * <li>If the first argument is positive and the second argument is
+ * positive zero or negative zero, or the first argument is positive
+ * infinity and the second argument is finite, then the result is the
+ * double value closest to pi/2.</li>
+ * <li>If the first argument is negative and the second argument is
+ * positive zero or negative zero, or the first argument is negative
+ * infinity and the second argument is finite, then the result is the
+ * double value closest to -pi/2.</li>
+ * <li>If both arguments are positive infinity, then the result is the
+ * double value closest to pi/4.</li>
+ * <li>If the first argument is positive infinity and the second argument
+ * is negative infinity, then the result is the double value closest to
+ * 3*pi/4.</li>
+ * <li>If the first argument is negative infinity and the second argument
+ * is positive infinity, then the result is the double value closest to
+ * -pi/4.</li>
+ * <li>If both arguments are negative infinity, then the result is the
+ * double value closest to -3*pi/4.</li>
+ *
+ * </ul><p>This is accurate within 2 ulps, and is semi-monotonic. To get r,
+ * use sqrt(x*x+y*y).
+ *
+ * @param y the y position
+ * @param x the x position
+ * @return <em>theta</em> in the conversion of (x, y) to (r, theta)
+ * @see #atan(double)
+ */
+ public static native double atan2(double y, double x);
+
+ /**
+ * Take <em>e</em><sup>a</sup>. The opposite of <code>log()</code>. If the
+ * argument is NaN, the result is NaN; if the argument is positive infinity,
+ * the result is positive infinity; and if the argument is negative
+ * infinity, the result is positive zero. This is accurate within 1 ulp,
+ * and is semi-monotonic.
+ *
+ * @param a the number to raise to the power
+ * @return the number raised to the power of <em>e</em>
+ * @see #log(double)
+ * @see #pow(double, double)
+ */
+ public static native double exp(double a);
+
+ /**
+ * Take ln(a) (the natural log). The opposite of <code>exp()</code>. If the
+ * argument is NaN or negative, the result is NaN; if the argument is
+ * positive infinity, the result is positive infinity; and if the argument
+ * is either zero, the result is negative infinity. This is accurate within
+ * 1 ulp, and is semi-monotonic.
+ *
+ * <p>Note that the way to get log<sub>b</sub>(a) is to do this:
+ * <code>ln(a) / ln(b)</code>.
+ *
+ * @param a the number to take the natural log of
+ * @return the natural log of <code>a</code>
+ * @see #exp(double)
+ */
+ public static native double log(double a);
+
+ /**
+ * Take a square root. If the argument is NaN or negative, the result is
+ * NaN; if the argument is positive infinity, the result is positive
+ * infinity; and if the result is either zero, the result is the same.
+ * This is accurate within the limits of doubles.
+ *
+ * <p>For other roots, use pow(a, 1 / rootNumber).
+ *
+ * @param a the numeric argument
+ * @return the square root of the argument
+ * @see #pow(double, double)
+ */
+ public static native double sqrt(double a);
+
+ /**
+ * Raise a number to a power. Special cases:<ul>
+ * <li>If the second argument is positive or negative zero, then the result
+ * is 1.0.</li>
+ * <li>If the second argument is 1.0, then the result is the same as the
+ * first argument.</li>
+ * <li>If the second argument is NaN, then the result is NaN.</li>
+ * <li>If the first argument is NaN and the second argument is nonzero,
+ * then the result is NaN.</li>
+ * <li>If the absolute value of the first argument is greater than 1 and
+ * the second argument is positive infinity, or the absolute value of the
+ * first argument is less than 1 and the second argument is negative
+ * infinity, then the result is positive infinity.</li>
+ * <li>If the absolute value of the first argument is greater than 1 and
+ * the second argument is negative infinity, or the absolute value of the
+ * first argument is less than 1 and the second argument is positive
+ * infinity, then the result is positive zero.</li>
+ * <li>If the absolute value of the first argument equals 1 and the second
+ * argument is infinite, then the result is NaN.</li>
+ * <li>If the first argument is positive zero and the second argument is
+ * greater than zero, or the first argument is positive infinity and the
+ * second argument is less than zero, then the result is positive zero.</li>
+ * <li>If the first argument is positive zero and the second argument is
+ * less than zero, or the first argument is positive infinity and the
+ * second argument is greater than zero, then the result is positive
+ * infinity.</li>
+ * <li>If the first argument is negative zero and the second argument is
+ * greater than zero but not a finite odd integer, or the first argument is
+ * negative infinity and the second argument is less than zero but not a
+ * finite odd integer, then the result is positive zero.</li>
+ * <li>If the first argument is negative zero and the second argument is a
+ * positive finite odd integer, or the first argument is negative infinity
+ * and the second argument is a negative finite odd integer, then the result
+ * is negative zero.</li>
+ * <li>If the first argument is negative zero and the second argument is
+ * less than zero but not a finite odd integer, or the first argument is
+ * negative infinity and the second argument is greater than zero but not a
+ * finite odd integer, then the result is positive infinity.</li>
+ * <li>If the first argument is negative zero and the second argument is a
+ * negative finite odd integer, or the first argument is negative infinity
+ * and the second argument is a positive finite odd integer, then the result
+ * is negative infinity.</li>
+ * <li>If the first argument is less than zero and the second argument is a
+ * finite even integer, then the result is equal to the result of raising
+ * the absolute value of the first argument to the power of the second
+ * argument.</li>
+ * <li>If the first argument is less than zero and the second argument is a
+ * finite odd integer, then the result is equal to the negative of the
+ * result of raising the absolute value of the first argument to the power
+ * of the second argument.</li>
+ * <li>If the first argument is finite and less than zero and the second
+ * argument is finite and not an integer, then the result is NaN.</li>
+ * <li>If both arguments are integers, then the result is exactly equal to
+ * the mathematical result of raising the first argument to the power of
+ * the second argument if that result can in fact be represented exactly as
+ * a double value.</li>
+ *
+ * </ul><p>(In the foregoing descriptions, a floating-point value is
+ * considered to be an integer if and only if it is a fixed point of the
+ * method {@link #ceil(double)} or, equivalently, a fixed point of the
+ * method {@link #floor(double)}. A value is a fixed point of a one-argument
+ * method if and only if the result of applying the method to the value is
+ * equal to the value.) This is accurate within 1 ulp, and is semi-monotonic.
+ *
+ * @param a the number to raise
+ * @param b the power to raise it to
+ * @return a<sup>b</sup>
+ */
+ public static native double pow(double a, double b);
+
+ /**
+ * Get the IEEE 754 floating point remainder on two numbers. This is the
+ * value of <code>x - y * <em>n</em></code>, where <em>n</em> is the closest
+ * double to <code>x / y</code> (ties go to the even n); for a zero
+ * remainder, the sign is that of <code>x</code>. If either argument is NaN,
+ * the first argument is infinite, or the second argument is zero, the result
+ * is NaN; if x is finite but y is infinite, the result is x. This is
+ * accurate within the limits of doubles.
+ *
+ * @param x the dividend (the top half)
+ * @param y the divisor (the bottom half)
+ * @return the IEEE 754-defined floating point remainder of x/y
+ * @see #rint(double)
+ */
+ public static native double IEEEremainder(double x, double y);
+
+ /**
+ * Take the nearest integer that is that is greater than or equal to the
+ * argument. If the argument is NaN, infinite, or zero, the result is the
+ * same; if the argument is between -1 and 0, the result is negative zero.
+ * Note that <code>Math.ceil(x) == -Math.floor(-x)</code>.
+ *
+ * @param a the value to act upon
+ * @return the nearest integer &gt;= <code>a</code>
+ */
+ public static native double ceil(double a);
+
+ /**
+ * Take the nearest integer that is that is less than or equal to the
+ * argument. If the argument is NaN, infinite, or zero, the result is the
+ * same. Note that <code>Math.ceil(x) == -Math.floor(-x)</code>.
+ *
+ * @param a the value to act upon
+ * @return the nearest integer &lt;= <code>a</code>
+ */
+ public static native double floor(double a);
+
+ /**
+ * Take the nearest integer to the argument. If it is exactly between
+ * two integers, the even integer is taken. If the argument is NaN,
+ * infinite, or zero, the result is the same.
+ *
+ * @param a the value to act upon
+ * @return the nearest integer to <code>a</code>
+ */
+ public static native double rint(double a);
+
+ /**
+ * <p>
+ * Take a cube root. If the argument is NaN, an infinity or zero, then
+ * the original value is returned. The returned result must be within 1 ulp
+ * of the exact result. For a finite value, <code>x</code>, the cube root
+ * of <code>-x</code> is equal to the negation of the cube root
+ * of <code>x</code>.
+ * </p>
+ * <p>
+ * For a square root, use <code>sqrt</code>. For other roots, use
+ * <code>pow(a, 1 / rootNumber)</code>.
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return the cube root of the argument
+ * @see #sqrt(double)
+ * @see #pow(double, double)
+ */
+ public static native double cbrt(double a);
+
+ /**
+ * <p>
+ * Returns the hyperbolic cosine of the given value. For a value,
+ * <code>x</code>, the hyperbolic cosine is <code>(e<sup>x</sup> +
+ * e<sup>-x</sup>)/2</code>
+ * with <code>e</code> being <a href="#E">Euler's number</a>. The returned
+ * result must be within 2.5 ulps of the exact result.
+ * </p>
+ * <p>
+ * If the supplied value is <code>NaN</code>, then the original value is
+ * returned. For either infinity, positive infinity is returned.
+ * The hyperbolic cosine of zero must be 1.0.
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return the hyperbolic cosine of <code>a</code>.
+ * @since 1.5
+ */
+ public static native double cosh(double a);
+
+ /**
+ * <p>
+ * Returns <code>e<sup>a</sup> - 1. For values close to 0, the
+ * result of <code>expm1(a) + 1</code> tend to be much closer to the
+ * exact result than simply <code>exp(x)</code>. The result must be within
+ * 1 ulp of the exact result, and results must be semi-monotonic. For finite
+ * inputs, the returned value must be greater than or equal to -1.0. Once
+ * a result enters within half a ulp of this limit, the limit is returned.
+ * </p>
+ * <p>
+ * For <code>NaN</code>, positive infinity and zero, the original value
+ * is returned. Negative infinity returns a result of -1.0 (the limit).
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return <code>e<sup>a</sup> - 1</code>
+ * @since 1.5
+ */
+ public static native double expm1(double a);
+
+ /**
+ * <p>
+ * Returns the hypotenuse, <code>a<sup>2</sup> + b<sup>2</sup></code>,
+ * without intermediate overflow or underflow. The returned result must be
+ * within 1 ulp of the exact result. If one parameter is held constant,
+ * then the result in the other parameter must be semi-monotonic.
+ * </p>
+ * <p>
+ * If either of the arguments is an infinity, then the returned result
+ * is positive infinity. Otherwise, if either argument is <code>NaN</code>,
+ * then <code>NaN</code> is returned.
+ * </p>
+ *
+ * @param a the first parameter.
+ * @param b the second parameter.
+ * @return the hypotenuse matching the supplied parameters.
+ * @since 1.5
+ */
+ public static native double hypot(double a, double b);
+
+ /**
+ * <p>
+ * Returns the base 10 logarithm of the supplied value. The returned
+ * result must within 1 ulp of the exact result, and the results must be
+ * semi-monotonic.
+ * </p>
+ * <p>
+ * Arguments of either <code>NaN</code> or less than zero return
+ * <code>NaN</code>. An argument of positive infinity returns positive
+ * infinity. Negative infinity is returned if either positive or negative
+ * zero is supplied. Where the argument is the result of
+ * <code>10<sup>n</sup</code>, then <code>n</code> is returned.
+ * </p>
+ *
+ * @param a the numeric argument.
+ * @return the base 10 logarithm of <code>a</code>.
+ * @since 1.5
+ */
+ public static native double log10(double a);
+
+ /**
+ * <p>
+ * Returns the natural logarithm resulting from the sum of the argument,
+ * <code>a</code> and 1. For values close to 0, the
+ * result of <code>log1p(a)</code> tend to be much closer to the
+ * exact result than simply <code>log(1.0+a)</code>. The returned
+ * result must be within 1 ulp of the exact result, and the results must be
+ * semi-monotonic.
+ * </p>
+ * <p>
+ * Arguments of either <code>NaN</code> or less than -1 return
+ * <code>NaN</code>. An argument of positive infinity or zero
+ * returns the original argument. Negative infinity is returned from an
+ * argument of -1.
+ * </p>
+ *
+ * @param a the numeric argument.
+ * @return the natural logarithm of <code>a</code> + 1.
+ * @since 1.5
+ */
+ public static native double log1p(double a);
+
+ /**
+ * <p>
+ * Returns the hyperbolic sine of the given value. For a value,
+ * <code>x</code>, the hyperbolic sine is <code>(e<sup>x</sup> -
+ * e<sup>-x</sup>)/2</code>
+ * with <code>e</code> being <a href="#E">Euler's number</a>. The returned
+ * result must be within 2.5 ulps of the exact result.
+ * </p>
+ * <p>
+ * If the supplied value is <code>NaN</code>, an infinity or a zero, then the
+ * original value is returned.
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return the hyperbolic sine of <code>a</code>.
+ * @since 1.5
+ */
+ public static native double sinh(double a);
+
+ /**
+ * <p>
+ * Returns the hyperbolic tangent of the given value. For a value,
+ * <code>x</code>, the hyperbolic tangent is <code>(e<sup>x</sup> -
+ * e<sup>-x</sup>)/(e<sup>x</sup> + e<sup>-x</sup>)</code>
+ * (i.e. <code>sinh(a)/cosh(a)</code>)
+ * with <code>e</code> being <a href="#E">Euler's number</a>. The returned
+ * result must be within 2.5 ulps of the exact result. The absolute value
+ * of the exact result is always less than 1. Computed results are thus
+ * less than or equal to 1 for finite arguments, with results within
+ * half a ulp of either positive or negative 1 returning the appropriate
+ * limit value (i.e. as if the argument was an infinity).
+ * </p>
+ * <p>
+ * If the supplied value is <code>NaN</code> or zero, then the original
+ * value is returned. Positive infinity returns +1.0 and negative infinity
+ * returns -1.0.
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return the hyperbolic tangent of <code>a</code>.
+ * @since 1.5
+ */
+ public static native double tanh(double a);
+
+}
diff --git a/libjava/classpath/vm/reference/java/lang/VMObject.java b/libjava/classpath/vm/reference/java/lang/VMObject.java
new file mode 100644
index 000000000..279f250c0
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/VMObject.java
@@ -0,0 +1,105 @@
+/* VMObject.java -- Reference implementation for VM hooks used by Object
+ Copyright (C) 1998, 2002, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+/**
+ * Object is the ultimate superclass of every class (excepting interfaces).
+ * As such, it needs help from the VM.
+ *
+ * @author John Keiser
+ * @author Eric Blake (ebb9@email.byu.edu)
+ */
+final class VMObject
+{
+ /**
+ * Returns the runtime {@link Class} of a given Object.
+ *
+ * @param obj the object to return the class for.
+ *
+ * @return the class of the Object.
+ */
+ static native Class getClass(Object obj);
+
+ /**
+ * The VM is expected to make a field-for-field shallow copy of the
+ * argument. Thus, the copy has the same runtime type as the argument.
+ * Note, however, that the cloned object must still be finalizable, even
+ * if the original has already had finalize() invoked on it.
+ *
+ * @param c the Cloneable to clone
+ * @return the clone
+ */
+ static native Object clone(Cloneable c);
+
+ /**
+ * Wakes up one of the threads that is waiting on this Object's monitor.
+ * Only the owner of a lock on the Object may call this method. The Thread
+ * to wake up is chosen arbitrarily.
+ *
+ * @param o the object doing the notify
+ * @throw IllegalMonitorStateException if this Thread does not own the
+ * lock on the Object
+ */
+ static native void notify(Object o) throws IllegalMonitorStateException;
+
+ /**
+ * Wakes up all of the threads waiting on this Object's monitor. Only
+ * the owner of the lock on this Object may call this method.
+ *
+ * @param o the object doing the notifyAll
+ * @throws IllegalMonitorStateException if this Thread does not own the
+ * lock on the Object
+ */
+ static native void notifyAll(Object o) throws IllegalMonitorStateException;
+
+ /**
+ * Waits a specified amount of time for notify() or notifyAll() to be
+ * called on this Object. The VM does not have to pay attention to the
+ * ns argument, if it does not have that much granularity.
+ *
+ * @param o the object to suspend on
+ * @param ms milliseconds to wait (1,000 milliseconds = 1 second)
+ * @param ns nanoseconds to wait beyond ms (1,000,000 nanoseconds
+ * == 1 millisecond)
+ * @throws IllegalMonitorStateException if this Thread does not own the
+ * lock on the Object
+ * @throws InterruptedException if some other Thread interrupts this Thread
+ */
+ static native void wait(Object o, long ms, int ns)
+ throws IllegalMonitorStateException, InterruptedException;
+}
diff --git a/libjava/classpath/vm/reference/java/lang/VMProcess.java b/libjava/classpath/vm/reference/java/lang/VMProcess.java
new file mode 100644
index 000000000..c41d7cc0c
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/VMProcess.java
@@ -0,0 +1,402 @@
+/* java.lang.VMProcess -- VM implementation of java.lang.Process
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Represents one external process. Each instance of this class is in
+ * one of three states: INITIAL, RUNNING, or TERMINATED. The instance
+ * is {@link Object#notifyAll notifyAll()}'d each time the state changes.
+ * The state of all instances is managed by a single dedicated thread
+ * which does the actual fork()/exec() and wait() system calls. User
+ * threads {@link Object#wait()} on the instance when creating the
+ * process or waiting for it to terminate.
+ *
+ * <p>
+ * See
+ * <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11801">GCC bug
+ * #11801</a> for the motivation behind the design of this class.
+ *
+ * @author Archie Cobbs
+ * @see Process
+ * @see Runtime#exec(String)
+ */
+final class VMProcess extends Process
+{
+
+ // Possible states for a VMProcess
+ private static final int INITIAL = 0;
+ private static final int RUNNING = 1;
+ private static final int TERMINATED = 2;
+
+ // Dedicated thread that does all the fork()'ing and wait()'ing.
+ static Thread processThread;
+
+ // New processes waiting to be spawned by processThread.
+ static final LinkedList workList = new LinkedList();
+
+ // Return values set by nativeReap() when a child is reaped.
+ // These are only accessed by processThread so no locking required.
+ static long reapedPid;
+ static int reapedExitValue;
+
+ // Information about this process
+ int state; // current state of process
+ final String[] cmd; // copied from Runtime.exec()
+ final String[] env; // copied from Runtime.exec()
+ final File dir; // copied from Runtime.exec()
+ Throwable exception; // if process failed to start
+ long pid; // process id
+ OutputStream stdin; // process input stream
+ InputStream stdout; // process output stream
+ InputStream stderr; // process error stream
+ int exitValue; // process exit value
+ boolean redirect; // redirect stderr -> stdout
+
+ //
+ // Dedicated thread that does all the fork()'ing and wait()'ing
+ // for external processes. This is needed because some systems like
+ // Linux use a process-per-thread model, which means the same thread
+ // that did the fork()/exec() must also do the wait().
+ //
+ private static class ProcessThread extends Thread
+ {
+
+ // Max time (in ms) we'll delay before trying to reap another child.
+ private static final int MAX_REAP_DELAY = 1000;
+
+ // Processes created but not yet terminated; maps Long(pid) -> VMProcess
+ // Only used in run() and spawn() method from this Thread, so no locking.
+ private final HashMap activeMap = new HashMap();
+
+ // We have an explicit constructor, because the default
+ // constructor will be private, which means the compiler will have
+ // to generate a second package-private constructor, which is
+ // bogus.
+ ProcessThread ()
+ {
+ }
+
+ public void run()
+ {
+ final LinkedList workList = VMProcess.workList;
+ while (true)
+ {
+
+ // Get the next process to spawn (if any) and spawn it. Spawn
+ // at most one at a time before checking for reapable children.
+ VMProcess process = null;
+ synchronized (workList)
+ {
+ if (!workList.isEmpty())
+ process = (VMProcess)workList.removeFirst();
+ }
+
+ if (process != null)
+ spawn(process);
+
+
+ // Check for termination of active child processes
+ while (!activeMap.isEmpty() && VMProcess.nativeReap())
+ {
+ long pid = VMProcess.reapedPid;
+ int exitValue = VMProcess.reapedExitValue;
+ process = (VMProcess)activeMap.remove(new Long(pid));
+ if (process != null)
+ {
+ synchronized (process)
+ {
+ process.exitValue = exitValue;
+ process.state = TERMINATED;
+ process.notify();
+ }
+ }
+ else
+ System.err.println("VMProcess WARNING reaped unknown process: "
+ + pid);
+ }
+
+
+ // If there are more new processes to create, go do that now.
+ // If there is nothing left to do, exit this thread. Otherwise,
+ // sleep a little while, and then check again for reapable children.
+ // We will get woken up immediately if there are new processes to
+ // spawn, but not if there are new children to reap. So we only
+ // sleep a short time, in effect polling while processes are active.
+ synchronized (workList)
+ {
+ if (!workList.isEmpty())
+ continue;
+ if (activeMap.isEmpty())
+ {
+ processThread = null;
+ break;
+ }
+
+ try
+ {
+ workList.wait(MAX_REAP_DELAY);
+ }
+ catch (InterruptedException e)
+ {
+ /* ignore */
+ }
+ }
+ }
+ }
+
+ // Spawn a process
+ private void spawn(VMProcess process)
+ {
+
+ // Spawn the process and put it in our active map indexed by pid.
+ // If the spawn operation fails, store the exception with the process.
+ // In either case, wake up thread that created the process.
+ synchronized (process)
+ {
+ try
+ {
+ process.nativeSpawn(process.cmd, process.env, process.dir,
+ process.redirect);
+ process.state = RUNNING;
+ activeMap.put(new Long(process.pid), process);
+ }
+ catch (ThreadDeath death)
+ {
+ throw death;
+ }
+ catch (Throwable t)
+ {
+ process.state = TERMINATED;
+ process.exception = t;
+ }
+ process.notify();
+ }
+ }
+ }
+
+ // Constructor
+ private VMProcess(String[] cmd, String[] env, File dir, boolean redirect)
+ throws IOException
+ {
+
+ // Initialize this process
+ this.state = INITIAL;
+ this.cmd = cmd;
+ this.env = env;
+ this.dir = dir;
+ this.redirect = redirect;
+
+ // Add process to the new process work list and wakeup processThread
+ synchronized (workList)
+ {
+ workList.add(this);
+ if (processThread == null)
+ {
+ processThread = new ProcessThread();
+ processThread.setDaemon(true);
+ processThread.start();
+ }
+ else
+ {
+ workList.notify();
+ }
+ }
+
+ // Wait for processThread to spawn this process and update its state
+ synchronized (this)
+ {
+ while (state == INITIAL)
+ {
+ try
+ {
+ wait();
+ }
+ catch (InterruptedException e)
+ {
+ /* ignore */
+ }
+ }
+ }
+
+ // If spawning failed, rethrow the exception in this thread
+ if (exception != null)
+ {
+ exception.fillInStackTrace();
+ if (exception instanceof IOException)
+ throw (IOException)exception;
+
+ if (exception instanceof Error)
+ throw (Error)exception;
+
+ if (exception instanceof RuntimeException)
+ throw (RuntimeException)exception;
+
+ throw new RuntimeException(exception);
+ }
+ }
+
+ // Invoked by native code (from nativeSpawn()) to record process info.
+ private void setProcessInfo(OutputStream stdin,
+ InputStream stdout, InputStream stderr, long pid)
+ {
+ this.stdin = stdin;
+ this.stdout = stdout;
+ if (stderr == null)
+ this.stderr = new InputStream()
+ {
+ public int read() throws IOException
+ {
+ return -1;
+ }
+ };
+ else
+ this.stderr = stderr;
+ this.pid = pid;
+ }
+
+ /**
+ * Entry point from Runtime.exec().
+ */
+ static Process exec(String[] cmd, String[] env, File dir) throws IOException
+ {
+ return new VMProcess(cmd, env, dir, false);
+ }
+
+ static Process exec(List cmd, Map env,
+ File dir, boolean redirect) throws IOException
+ {
+ String[] acmd = (String[]) cmd.toArray(new String[cmd.size()]);
+ String[] aenv = new String[env.size()];
+
+ int i = 0;
+ Iterator iter = env.entrySet().iterator();
+ while (iter.hasNext())
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ aenv[i++] = entry.getKey() + "=" + entry.getValue();
+ }
+
+ return new VMProcess(acmd, aenv, dir, redirect);
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return stdin;
+ }
+
+ public InputStream getInputStream()
+ {
+ return stdout;
+ }
+
+ public InputStream getErrorStream()
+ {
+ return stderr;
+ }
+
+ public synchronized int waitFor() throws InterruptedException
+ {
+ while (state != TERMINATED)
+ wait();
+ return exitValue;
+ }
+
+ public synchronized int exitValue()
+ {
+ if (state != TERMINATED)
+ throw new IllegalThreadStateException();
+ return exitValue;
+ }
+
+ public synchronized void destroy()
+ {
+ if (state == TERMINATED)
+ return;
+
+ nativeKill(pid);
+
+ while (state != TERMINATED)
+ {
+ try
+ {
+ wait();
+ }
+ catch (InterruptedException e)
+ {
+ /* ignore */
+ }
+ }
+ }
+
+ /**
+ * Does the fork()/exec() thing to create the O/S process.
+ * Must invoke setProcessInfo() before returning successfully.
+ * This method is only invoked by processThread.
+ *
+ * @throws IOException if the O/S process could not be created.
+ */
+ native void nativeSpawn(String[] cmd, String[] env, File dir,
+ boolean redirect)
+ throws IOException;
+
+ /**
+ * Test for a reapable child process, and reap if so. Does not block.
+ * If a child was reaped, this method must set reapedPid and
+ * reapedExitValue appropriately before returning.
+ * This method is only invoked by processThread.
+ *
+ * @return true if a child was reaped, otherwise false
+ */
+ // This is not private as it is called from an inner class.
+ static native boolean nativeReap();
+
+ /**
+ * Kill a process. This sends it a fatal signal but does not reap it.
+ */
+ private static native void nativeKill(long pid);
+}
diff --git a/libjava/classpath/vm/reference/java/lang/VMRuntime.java b/libjava/classpath/vm/reference/java/lang/VMRuntime.java
new file mode 100644
index 000000000..0b58d5f44
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/VMRuntime.java
@@ -0,0 +1,192 @@
+/* VMRuntime.java -- VM interface to Runtime
+ Copyright (C) 2003 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * VMRuntime represents the interface to the Virtual Machine.
+ *
+ * @author Jeroen Frijters
+ */
+final class VMRuntime
+{
+ /**
+ * No instance is ever created.
+ */
+ private VMRuntime()
+ {
+ }
+
+ /**
+ * Returns the number of available processors currently available to the
+ * virtual machine. This number may change over time; so a multi-processor
+ * program want to poll this to determine maximal resource usage.
+ *
+ * @return the number of processors available, at least 1
+ */
+ static native int availableProcessors();
+
+ /**
+ * Find out how much memory is still free for allocating Objects on the heap.
+ *
+ * @return the number of bytes of free memory for more Objects
+ */
+ static native long freeMemory();
+
+ /**
+ * Find out how much memory total is available on the heap for allocating
+ * Objects.
+ *
+ * @return the total number of bytes of memory for Objects
+ */
+ static native long totalMemory();
+
+ /**
+ * Returns the maximum amount of memory the virtual machine can attempt to
+ * use. This may be <code>Long.MAX_VALUE</code> if there is no inherent
+ * limit (or if you really do have a 8 exabyte memory!).
+ *
+ * @return the maximum number of bytes the virtual machine will attempt
+ * to allocate
+ */
+ static native long maxMemory();
+
+ /**
+ * Run the garbage collector. This method is more of a suggestion than
+ * anything. All this method guarantees is that the garbage collector will
+ * have "done its best" by the time it returns. Notice that garbage
+ * collection takes place even without calling this method.
+ */
+ static native void gc();
+
+ /**
+ * Run finalization on all Objects that are waiting to be finalized. Again,
+ * a suggestion, though a stronger one than {@link #gc()}. This calls the
+ * <code>finalize</code> method of all objects waiting to be collected.
+ *
+ * @see #finalize()
+ */
+ static native void runFinalization();
+
+ /**
+ * Run finalization on all finalizable Objects (even live ones). This
+ * should only be called immediately prior to VM termination.
+ *
+ * @see #finalize()
+ */
+ static native void runFinalizationForExit();
+
+ /**
+ * Tell the VM to trace every bytecode instruction that executes (print out
+ * a trace of it). No guarantees are made as to where it will be printed,
+ * and the VM is allowed to ignore this request.
+ *
+ * @param on whether to turn instruction tracing on
+ */
+ static native void traceInstructions(boolean on);
+
+ /**
+ * Tell the VM to trace every method call that executes (print out a trace
+ * of it). No guarantees are made as to where it will be printed, and the
+ * VM is allowed to ignore this request.
+ *
+ * @param on whether to turn method tracing on
+ */
+ static native void traceMethodCalls(boolean on);
+
+ /**
+ * Native method that actually sets the finalizer setting.
+ *
+ * @param value whether to run finalizers on exit
+ */
+ static native void runFinalizersOnExit(boolean value);
+
+ /**
+ * Native method that actually shuts down the virtual machine.
+ *
+ * @param status the status to end the process with
+ */
+ static native void exit(int status);
+
+ /**
+ * Load a file. If it has already been loaded, do nothing. The name has
+ * already been mapped to a true filename.
+ *
+ * @param filename the file to load
+ * @param loader class loader, or <code>null</code> for the boot loader
+ * @return 0 on failure, nonzero on success
+ */
+ static native int nativeLoad(String filename, ClassLoader loader);
+
+ /**
+ * Map a system-independent "short name" to the full file name.
+ *
+ * @param libname the short version of the library name
+ * @return the full filename
+ */
+ static native String mapLibraryName(String libname);
+
+ /**
+ * Execute a process. The command line has already been tokenized, and
+ * the environment should contain name=value mappings. If directory is null,
+ * use the current working directory; otherwise start the process in that
+ * directory. If env is null, then the new process should inherit
+ * the environment of this process.
+ *
+ * @param cmd the non-null command tokens
+ * @param env the environment setup
+ * @param dir the directory to use, may be null
+ * @return the newly created process
+ * @throws NullPointerException if cmd or env have null elements
+ */
+ static Process exec(String[] cmd, String[] env, File dir)
+ throws IOException {
+ return VMProcess.exec(cmd, env, dir);
+ }
+
+ /**
+ * This method is called by Runtime.addShutdownHook() when it is
+ * called for the first time. It enables the VM to lazily setup
+ * an exit handler, should it so desire.
+ */
+ static void enableShutdownHooks()
+ {
+ }
+} // class VMRuntime
diff --git a/libjava/classpath/vm/reference/java/lang/VMString.java b/libjava/classpath/vm/reference/java/lang/VMString.java
new file mode 100644
index 000000000..e1fbf8390
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/VMString.java
@@ -0,0 +1,91 @@
+/* VMString.java -- VM Specific String methods
+ Copyright (C) 2003 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.lang.ref.WeakReference;
+import java.util.WeakHashMap;
+
+/*
+ * This class is a reference version, mainly for compiling a class library
+ * jar. It is likely that VM implementers replace this with their own
+ * version that can communicate effectively with the VM.
+ */
+
+/**
+ * Code relocated from java.lang.String by
+ * @author Dave Grove <groved@us.ibm.com>
+ */
+final class VMString
+{
+
+ /**
+ * Holds the references for each intern()'d String. If all references to
+ * the string disappear, and the VM properly supports weak references,
+ * the String will be GC'd.
+ */
+ private static final WeakHashMap internTable = new WeakHashMap();
+
+ /**
+ * Fetches this String from the intern hashtable. If two Strings are
+ * considered equal, by the equals() method, then intern() will return the
+ * same String instance. ie. if (s1.equals(s2)) then
+ * (s1.intern() == s2.intern()). All string literals and string-valued
+ * constant expressions are already interned.
+ *
+ * @param str the String to intern
+ * @return the interned String
+ */
+ static String intern(String str)
+ {
+ synchronized (internTable)
+ {
+ WeakReference ref = (WeakReference) internTable.get(str);
+ if (ref != null)
+ {
+ String s = (String) ref.get();
+ // If s is null, then no strong references exist to the String;
+ // the weak hash map will soon delete the key.
+ if (s != null)
+ return s;
+ }
+ internTable.put(str, new WeakReference(str));
+ }
+ return str;
+ }
+
+} // class VMString
diff --git a/libjava/classpath/vm/reference/java/lang/VMSystem.java b/libjava/classpath/vm/reference/java/lang/VMSystem.java
new file mode 100644
index 000000000..52a3c1c9f
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/VMSystem.java
@@ -0,0 +1,220 @@
+/* VMSystem.java -- helper for java.lang.system
+ Copyright (C) 1998, 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.util.List;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+
+/**
+ * VMSystem is a package-private helper class for System that the
+ * VM must implement.
+ *
+ * @author John Keiser
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+final class VMSystem
+{
+ /**
+ * Copy one array onto another from <code>src[srcStart]</code> ...
+ * <code>src[srcStart+len-1]</code> to <code>dest[destStart]</code> ...
+ * <code>dest[destStart+len-1]</code>. First, the arguments are validated:
+ * neither array may be null, they must be of compatible types, and the
+ * start and length must fit within both arrays. Then the copying starts,
+ * and proceeds through increasing slots. If src and dest are the same
+ * array, this will appear to copy the data to a temporary location first.
+ * An ArrayStoreException in the middle of copying will leave earlier
+ * elements copied, but later elements unchanged.
+ *
+ * @param src the array to copy elements from
+ * @param srcStart the starting position in src
+ * @param dest the array to copy elements to
+ * @param destStart the starting position in dest
+ * @param len the number of elements to copy
+ * @throws NullPointerException if src or dest is null
+ * @throws ArrayStoreException if src or dest is not an array, if they are
+ * not compatible array types, or if an incompatible runtime type
+ * is stored in dest
+ * @throws IndexOutOfBoundsException if len is negative, or if the start or
+ * end copy position in either array is out of bounds
+ */
+ static native void arraycopy(Object src, int srcStart,
+ Object dest, int destStart, int len);
+
+ /**
+ * Get a hash code computed by the VM for the Object. This hash code will
+ * be the same as Object's hashCode() method. It is usually some
+ * convolution of the pointer to the Object internal to the VM. It
+ * follows standard hash code rules, in that it will remain the same for a
+ * given Object for the lifetime of that Object.
+ *
+ * @param o the Object to get the hash code for
+ * @return the VM-dependent hash code for this Object
+ */
+ static native int identityHashCode(Object o);
+
+ /**
+ * Convert a library name to its platform-specific variant.
+ *
+ * @param libname the library name, as used in <code>loadLibrary</code>
+ * @return the platform-specific mangling of the name
+ * @XXX Add this method
+ static native String mapLibraryName(String libname);
+ */
+
+ /**
+ * Set {@link System#in} to a new InputStream.
+ *
+ * @param in the new InputStream
+ * @see #setIn(InputStream)
+ */
+ static native void setIn(InputStream in);
+
+ /**
+ * Set {@link System#out} to a new PrintStream.
+ *
+ * @param out the new PrintStream
+ * @see #setOut(PrintStream)
+ */
+ static native void setOut(PrintStream out);
+
+ /**
+ * Set {@link System#err} to a new PrintStream.
+ *
+ * @param err the new PrintStream
+ * @see #setErr(PrintStream)
+ */
+ static native void setErr(PrintStream err);
+
+ /**
+ * Get the current time, measured in the number of milliseconds from the
+ * beginning of Jan. 1, 1970. This is gathered from the system clock, with
+ * any attendant incorrectness (it may be timezone dependent).
+ *
+ * @return the current time
+ * @see java.util.Date
+ */
+ public static long currentTimeMillis()
+ {
+ return nanoTime() / 1000000L;
+ }
+
+ /**
+ * <p>
+ * Returns the current value of a nanosecond-precise system timer.
+ * The value of the timer is an offset relative to some arbitrary fixed
+ * time, which may be in the future (making the value negative). This
+ * method is useful for timing events where nanosecond precision is
+ * required. This is achieved by calling this method before and after the
+ * event, and taking the difference betweent the two times:
+ * </p>
+ * <p>
+ * <code>long startTime = System.nanoTime();</code><br />
+ * <code>... <emph>event code</emph> ...</code><br />
+ * <code>long endTime = System.nanoTime();</code><br />
+ * <code>long duration = endTime - startTime;</code><br />
+ * </p>
+ * <p>
+ * Note that the value is only nanosecond-precise, and not accurate; there
+ * is no guarantee that the difference between two values is really a
+ * nanosecond. Also, the value is prone to overflow if the offset
+ * exceeds 2^63.
+ * </p>
+ *
+ * @return the time of a system timer in nanoseconds.
+ * @since 1.5
+ */
+ public static native long nanoTime();
+
+ /**
+ * Returns a list of 'name=value' pairs representing the current environment
+ * variables.
+ *
+ * @return a list of 'name=value' pairs.
+ */
+ static native List environ();
+
+ /**
+ * Helper method which creates the standard input stream.
+ * VM implementors may choose to construct these streams differently.
+ * This method can also return null if the stream is created somewhere
+ * else in the VM startup sequence.
+ */
+ static InputStream makeStandardInputStream()
+ {
+ return new BufferedInputStream(new FileInputStream(FileDescriptor.in));
+ }
+
+ /**
+ * Helper method which creates the standard output stream.
+ * VM implementors may choose to construct these streams differently.
+ * This method can also return null if the stream is created somewhere
+ * else in the VM startup sequence.
+ */
+ static PrintStream makeStandardOutputStream()
+ {
+ return new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)), true);
+ }
+
+ /**
+ * Helper method which creates the standard error stream.
+ * VM implementors may choose to construct these streams differently.
+ * This method can also return null if the stream is created somewhere
+ * else in the VM startup sequence.
+ */
+ static PrintStream makeStandardErrorStream()
+ {
+ return new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.err)), true);
+ }
+
+ /**
+ * Gets the value of an environment variable.
+ * Always returning null is a valid (but not very useful) implementation.
+ *
+ * @param name The name of the environment variable (will not be null).
+ * @return The string value of the variable or null when the
+ * environment variable is not defined.
+ */
+ static native String getenv(String name);
+}
diff --git a/libjava/classpath/vm/reference/java/lang/VMThread.java b/libjava/classpath/vm/reference/java/lang/VMThread.java
new file mode 100644
index 000000000..1b461a694
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/VMThread.java
@@ -0,0 +1,461 @@
+/* VMThread -- VM interface for Thread of executable code
+ Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+/**
+ * VM interface for Thread of executable code. Holds VM dependent state.
+ * It is deliberately package local and final and should only be accessed
+ * by the Thread class.
+ * <p>
+ * This is the GNU Classpath reference implementation, it should be adapted
+ * for a specific VM.
+ * <p>
+ * The following methods must be implemented:
+ * <ul>
+ * <li>native void start(long stacksize);
+ * <li>native void interrupt();
+ * <li>native boolean isInterrupted();
+ * <li>native void suspend();
+ * <li>native void resume();
+ * <li>native void nativeSetPriority(int priority);
+ * <li>native void nativeStop(Throwable t);
+ * <li>native static Thread currentThread();
+ * <li>static native void yield();
+ * <li>static native boolean interrupted();
+ * </ul>
+ * All other methods may be implemented to make Thread handling more efficient
+ * or to implement some optional (and sometimes deprecated) behaviour. Default
+ * implementations are provided but it is highly recommended to optimize them
+ * for a specific VM.
+ *
+ * @author Jeroen Frijters (jeroen@frijters.net)
+ * @author Dalibor Topic (robilad@kaffe.org)
+ */
+final class VMThread
+{
+ /**
+ * The Thread object that this VM state belongs to.
+ * Used in currentThread() and start().
+ * Note: when this thread dies, this reference is *not* cleared
+ */
+ volatile Thread thread;
+
+ /**
+ * Flag that is set when the thread runs, used by stop() to protect against
+ * stop's getting lost.
+ */
+ private volatile boolean running;
+
+ /**
+ * VM private data.
+ */
+ private transient Object vmdata;
+
+ /**
+ * Private constructor, create VMThreads with the static create method.
+ *
+ * @param thread The Thread object that was just created.
+ */
+ private VMThread(Thread thread)
+ {
+ this.thread = thread;
+ }
+
+ /**
+ * This method is the initial Java code that gets executed when a native
+ * thread starts. It's job is to coordinate with the rest of the VMThread
+ * logic and to start executing user code and afterwards handle clean up.
+ */
+ private void run()
+ {
+ try
+ {
+ try
+ {
+ running = true;
+ synchronized(thread)
+ {
+ Throwable t = thread.stillborn;
+ if(t != null)
+ {
+ thread.stillborn = null;
+ throw t;
+ }
+ }
+ thread.run();
+ }
+ catch(Throwable t)
+ {
+ try
+ {
+ Thread.UncaughtExceptionHandler handler;
+ handler = thread.getUncaughtExceptionHandler();
+ handler.uncaughtException(thread, t);
+ }
+ catch(Throwable ignore)
+ {
+ }
+ }
+ }
+ finally
+ {
+ // Setting runnable to false is partial protection against stop
+ // being called while we're cleaning up. To be safe all code in
+ // VMThread be unstoppable.
+ running = false;
+ thread.die();
+ synchronized(this)
+ {
+ // release the threads waiting to join us
+ notifyAll();
+ }
+ }
+ }
+
+ /**
+ * Creates a native Thread. This is called from the start method of Thread.
+ * The Thread is started.
+ *
+ * @param thread The newly created Thread object
+ * @param stacksize Indicates the requested stacksize. Normally zero,
+ * non-zero values indicate requested stack size in bytes but it is up
+ * to the specific VM implementation to interpret them and may be ignored.
+ */
+ static void create(Thread thread, long stacksize)
+ {
+ VMThread vmThread = new VMThread(thread);
+ vmThread.start(stacksize);
+ thread.vmThread = vmThread;
+ }
+
+ /**
+ * Gets the name of the thread. Usually this is the name field of the
+ * associated Thread object, but some implementation might choose to
+ * return the name of the underlying platform thread.
+ */
+ String getName()
+ {
+ return thread.name;
+ }
+
+ /**
+ * Set the name of the thread. Usually this sets the name field of the
+ * associated Thread object, but some implementations might choose to
+ * set the name of the underlying platform thread.
+ * @param name The new name
+ */
+ void setName(String name)
+ {
+ thread.name = name;
+ }
+
+ /**
+ * Set the thread priority field in the associated Thread object and
+ * calls the native method to set the priority of the underlying
+ * platform thread.
+ * @param priority The new priority
+ */
+ void setPriority(int priority)
+ {
+ thread.priority = priority;
+ nativeSetPriority(priority);
+ }
+
+ /**
+ * Returns the priority. Usually this is the priority field from the
+ * associated Thread object, but some implementation might choose to
+ * return the priority of the underlying platform thread.
+ * @return this Thread's priority
+ */
+ int getPriority()
+ {
+ return thread.priority;
+ }
+
+ /**
+ * Returns true if the thread is a daemon thread. Usually this is the
+ * daemon field from the associated Thread object, but some
+ * implementation might choose to return the daemon state of the underlying
+ * platform thread.
+ * @return whether this is a daemon Thread or not
+ */
+ boolean isDaemon()
+ {
+ return thread.daemon;
+ }
+
+ /**
+ * Returns the number of stack frames in this Thread.
+ * Will only be called when when a previous call to suspend() returned true.
+ *
+ * @deprecated unsafe operation
+ */
+ native int countStackFrames();
+
+ /**
+ * Wait the specified amount of time for the Thread in question to die.
+ *
+ * <p>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do
+ * not offer that fine a grain of timing resolution. Besides, there is
+ * no guarantee that this thread can start up immediately when time expires,
+ * because some other thread may be active. So don't expect real-time
+ * performance.
+ *
+ * @param ms the number of milliseconds to wait, or 0 for forever
+ * @param ns the number of extra nanoseconds to sleep (0-999999)
+ * @throws InterruptedException if the Thread is interrupted; it's
+ * <i>interrupted status</i> will be cleared
+ */
+ synchronized void join(long ms, int ns) throws InterruptedException
+ {
+ // Round up
+ ms += (ns != 0) ? 1 : 0;
+
+ // Compute end time, but don't overflow
+ long now = System.currentTimeMillis();
+ long end = now + ms;
+ if (end < now)
+ end = Long.MAX_VALUE;
+
+ // A VM is allowed to return from wait() without notify() having been
+ // called, so we loop to handle possible spurious wakeups.
+ while(thread.vmThread != null)
+ {
+ // We use the VMThread object to wait on, because this is a private
+ // object, so client code cannot call notify on us.
+ wait(ms);
+ if(ms != 0)
+ {
+ now = System.currentTimeMillis();
+ ms = end - now;
+ if(ms <= 0)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Cause this Thread to stop abnormally and throw the specified exception.
+ * If you stop a Thread that has not yet started, the stop is ignored
+ * (contrary to what the JDK documentation says).
+ * <b>WARNING</b>This bypasses Java security, and can throw a checked
+ * exception which the call stack is unprepared to handle. Do not abuse
+ * this power.
+ *
+ * <p>This is inherently unsafe, as it can interrupt synchronized blocks and
+ * leave data in bad states.
+ *
+ * <p><b>NOTE</b> stop() should take care not to stop a thread if it is
+ * executing code in this class.
+ *
+ * @param t the Throwable to throw when the Thread dies
+ * @deprecated unsafe operation, try not to use
+ */
+ void stop(Throwable t)
+ {
+ // Note: we assume that we own the lock on thread
+ // (i.e. that Thread.stop() is synchronized)
+ if(running)
+ nativeStop(t);
+ else
+ thread.stillborn = t;
+ }
+
+ /**
+ * Create a native thread on the underlying platform and start it executing
+ * on the run method of this object.
+ * @param stacksize the requested size of the native thread stack
+ */
+ native void start(long stacksize);
+
+ /**
+ * Interrupt this thread.
+ */
+ native void interrupt();
+
+ /**
+ * Determine whether this Thread has been interrupted, but leave
+ * the <i>interrupted status</i> alone in the process.
+ *
+ * @return whether the Thread has been interrupted
+ */
+ native boolean isInterrupted();
+
+ /**
+ * Suspend this Thread. It will not come back, ever, unless it is resumed.
+ */
+ native void suspend();
+
+ /**
+ * Resume this Thread. If the thread is not suspended, this method does
+ * nothing.
+ */
+ native void resume();
+
+ /**
+ * Set the priority of the underlying platform thread.
+ *
+ * @param priority the new priority
+ */
+ native void nativeSetPriority(int priority);
+
+ /**
+ * Asynchronously throw the specified throwable in this Thread.
+ *
+ * @param t the exception to throw
+ */
+ native void nativeStop(Throwable t);
+
+ /**
+ * Return the Thread object associated with the currently executing
+ * thread.
+ *
+ * @return the currently executing Thread
+ */
+ static native Thread currentThread();
+
+ /**
+ * Yield to another thread. The Thread will not lose any locks it holds
+ * during this time. There are no guarantees which thread will be
+ * next to run, and it could even be this one, but most VMs will choose
+ * the highest priority thread that has been waiting longest.
+ */
+ static native void yield();
+
+ /**
+ * Suspend the current Thread's execution for the specified amount of
+ * time. The Thread will not lose any locks it has during this time. There
+ * are no guarantees which thread will be next to run, but most VMs will
+ * choose the highest priority thread that has been waiting longest.
+ *
+ * <p>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do
+ * not offer that fine a grain of timing resolution. Besides, there is
+ * no guarantee that this thread can start up immediately when time expires,
+ * because some other thread may be active. So don't expect real-time
+ * performance.
+ *
+ * @param ms the number of milliseconds to sleep.
+ * @param ns the number of extra nanoseconds to sleep (0-999999)
+ * @throws InterruptedException if the Thread is (or was) interrupted;
+ * it's <i>interrupted status</i> will be cleared
+ */
+ static void sleep(long ms, int ns) throws InterruptedException
+ {
+ // Note: JDK treats a zero length sleep is like Thread.yield(),
+ // without checking the interrupted status of the thread.
+ // It's unclear if this is a bug in the implementation or the spec.
+ // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203
+ if (ms == 0 && ns == 0)
+ {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ return;
+ }
+
+ // Compute end time, but don't overflow
+ long now = System.currentTimeMillis();
+ long end = now + ms;
+ if (end < now)
+ end = Long.MAX_VALUE;
+
+ // A VM is allowed to return from wait() without notify() having been
+ // called, so we loop to handle possible spurious wakeups.
+ VMThread vt = Thread.currentThread().vmThread;
+ synchronized (vt)
+ {
+ while (true)
+ {
+ vt.wait(ms, ns);
+ now = System.currentTimeMillis();
+ if (now >= end)
+ break;
+ ms = end - now;
+ ns = 0;
+ }
+ }
+ }
+
+ /**
+ * Determine whether the current Thread has been interrupted, and clear
+ * the <i>interrupted status</i> in the process.
+ *
+ * @return whether the current Thread has been interrupted
+ */
+ static native boolean interrupted();
+
+ /**
+ * Checks whether the current thread holds the monitor on a given object.
+ * This allows you to do <code>assert Thread.holdsLock(obj)</code>.
+ *
+ * @param obj the object to check
+ * @return true if the current thread is currently synchronized on obj
+ * @throws NullPointerException if obj is null
+ */
+ static boolean holdsLock(Object obj)
+ {
+ /* Use obj.notify to check if the current thread holds
+ * the monitor of the object.
+ * If it doesn't, notify will throw an exception.
+ */
+ try
+ {
+ obj.notify();
+ // okay, current thread holds lock
+ return true;
+ }
+ catch (IllegalMonitorStateException e)
+ {
+ // it doesn't hold the lock
+ return false;
+ }
+ }
+
+ /**
+ * Returns the current state of the thread.
+ * The value must be one of "BLOCKED", "NEW",
+ * "RUNNABLE", "TERMINATED", "TIMED_WAITING" or
+ * "WAITING".
+ *
+ * @return a string corresponding to one of the
+ * thread enumeration states specified above.
+ */
+ native String getState();
+
+}
diff --git a/libjava/classpath/vm/reference/java/lang/VMThrowable.java b/libjava/classpath/vm/reference/java/lang/VMThrowable.java
new file mode 100644
index 000000000..19a204e88
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/VMThrowable.java
@@ -0,0 +1,82 @@
+/* java.lang.VMThrowable -- VM support methods for Throwable.
+ Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+/**
+ * VM dependant state and support methods for Throwable.
+ * It is deliberately package local and final and should only be accessed
+ * by the Throwable class.
+ * <p>
+ * This is the GNU Classpath reference implementation, it should be adapted
+ * for a specific VM. The reference implementation does nothing.
+ *
+ * @author Mark Wielaard (mark@klomp.org)
+ */
+final class VMThrowable
+{
+ /**
+ * VM private data.
+ */
+ private transient Object vmdata;
+
+ /**
+ * Private contructor, create VMThrowables with fillInStackTrace();
+ */
+ private VMThrowable() { }
+
+ /**
+ * Fill in the stack trace with the current execution stack.
+ * Called by <code>Throwable.fillInStackTrace()</code> to get the state of
+ * the VM. Can return null when the VM does not support caputing the VM
+ * execution state.
+ *
+ * @return a new VMThrowable containing the current execution stack trace.
+ * @see Throwable#fillInStackTrace()
+ */
+ static native VMThrowable fillInStackTrace(Throwable t);
+
+ /**
+ * Returns an <code>StackTraceElement</code> array based on the execution
+ * state of the VM as captured by <code>fillInStackTrace</code>.
+ * Called by <code>Throwable.getStackTrace()</code>.
+ *
+ * @return a non-null but possible zero length array of StackTraceElement.
+ * @see Throwable#getStackTrace()
+ */
+ native StackTraceElement[] getStackTrace(Throwable t);
+}
diff --git a/libjava/classpath/vm/reference/java/lang/management/VMManagementFactory.java b/libjava/classpath/vm/reference/java/lang/management/VMManagementFactory.java
new file mode 100644
index 000000000..f10497014
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/management/VMManagementFactory.java
@@ -0,0 +1,75 @@
+/* VMManagementFactory.java - VM interface for obtaining system beans.
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang.management;
+
+/**
+ * Provides lists of resources required by the
+ * {@link java.lang.management.ManagementFactory} for
+ * creating beans.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMManagementFactory
+{
+
+ /**
+ * Return a list of the names of the currently available
+ * memory pools within the virtual machine.
+ *
+ * @return a list of memory pool names.
+ */
+ static native String[] getMemoryPoolNames();
+
+ /**
+ * Return a list of the names of the currently available
+ * memory managers within the virtual machine. This should
+ * not include the garbage collectors listed below.
+ *
+ * @return a list of memory manager names.
+ */
+ static native String[] getMemoryManagerNames();
+
+ /**
+ * Return a list of the names of the currently available
+ * garbage collectors within the virtual machine.
+ *
+ * @return a list of garbage collector names.
+ */
+ static native String[] getGarbageCollectorNames();
+}
diff --git a/libjava/classpath/vm/reference/java/lang/reflect/VMArray.java b/libjava/classpath/vm/reference/java/lang/reflect/VMArray.java
new file mode 100644
index 000000000..d6277aebd
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/reflect/VMArray.java
@@ -0,0 +1,65 @@
+/* java.lang.reflect.VMArray - VM class for array manipulation by reflection.
+ Copyright (C) 1998, 1999, 2001, 2003, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.classpath.Configuration;
+
+class VMArray
+{
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javalangreflect");
+ }
+ }
+
+ /**
+ * Dynamically create an array of objects.
+ *
+ * @param type guaranteed to be a valid object type
+ * @param dim the length of the array
+ * @return the new array
+ * @throws NegativeArraySizeException if dim is negative
+ * @throws OutOfMemoryError if memory allocation fails
+ */
+ static native Object createObjectArray(Class type, int dim);
+
+}
diff --git a/libjava/classpath/vm/reference/java/lang/reflect/VMConstructor.java b/libjava/classpath/vm/reference/java/lang/reflect/VMConstructor.java
new file mode 100644
index 000000000..c6f319026
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/reflect/VMConstructor.java
@@ -0,0 +1,169 @@
+/* java.lang.reflect.VMConstructor - VM interface for reflection of Java constructors
+ Copyright (C) 1998, 2001, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import java.lang.annotation.Annotation;
+
+import java.util.Arrays;
+
+final class VMConstructor
+{
+ Class clazz;
+ int slot;
+
+ /**
+ * This field allows us to refer back to the main constructor instance.
+ * It is set by the constructor of Constructor.
+ */
+ Constructor cons;
+
+ VMConstructor(Class clazz, int slot)
+ {
+ this.clazz = clazz;
+ this.slot = slot;
+ }
+
+ public Class getDeclaringClass()
+ {
+ return clazz;
+ }
+
+ /**
+ * Return the raw modifiers for this constructor. In particular
+ * this will include the synthetic and varargs bits.
+ * @return the constructor's modifiers
+ */
+ native int getModifiersInternal();
+
+ /**
+ * Get the parameter list for this constructor, in declaration order. If the
+ * constructor takes no parameters, returns a 0-length array (not null).
+ *
+ * @return a list of the types of the constructor's parameters
+ */
+ native Class[] getParameterTypes();
+
+ /**
+ * Get the exception types this constructor says it throws, in no particular
+ * order. If the constructor has no throws clause, returns a 0-length array
+ * (not null).
+ *
+ * @return a list of the types in the constructor's throws clause
+ */
+ native Class[] getExceptionTypes();
+
+ native Object construct(Object[] args)
+ throws InstantiationException, IllegalAccessException,
+ InvocationTargetException;
+
+ /**
+ * Return the String in the Signature attribute for this constructor. If there
+ * is no Signature attribute, return null.
+ */
+ native String getSignature();
+
+ /**
+ * <p>
+ * Return an array of arrays representing the annotations on each
+ * of the constructor's parameters. The outer array is aligned against
+ * the parameters of the constructors and is thus equal in length to
+ * the number of parameters (thus having a length zero if there are none).
+ * Each array element in the outer array contains an inner array which
+ * holds the annotations. This array has a length of zero if the parameter
+ * has no annotations.
+ * </p>
+ * <p>
+ * The returned annotations are serialized. Changing the annotations has
+ * no affect on the return value of future calls to this method.
+ * </p>
+ *
+ * @return an array of arrays which represents the annotations used on the
+ * parameters of this constructor. The order of the array elements
+ * matches the declaration order of the parameters.
+ * @since 1.5
+ */
+ native Annotation[][] getParameterAnnotations();
+
+ /**
+ * Compare two objects to see if they are semantically equivalent.
+ * Two Constructors are semantically equivalent if they have the same
+ * declaring class and the same parameter list. This ignores different
+ * exception clauses, but since you can't create a Method except through the
+ * VM, this is just the == relation.
+ *
+ * @param o the object to compare to
+ * @return <code>true</code> if they are equal; <code>false</code> if not.
+ */
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof Constructor))
+ return false;
+ Constructor that = (Constructor)o;
+ if (clazz != that.getDeclaringClass())
+ return false;
+ if (!Arrays.equals(getParameterTypes(), that.getParameterTypes()))
+ return false;
+ return true;
+ }
+
+ /**
+ * Returns the element's annotation for the specified annotation type,
+ * or <code>null</code> if no such annotation exists.
+ *
+ * @param annotationClass the type of annotation to look for.
+ * @return this element's annotation for the specified type, or
+ * <code>null</code> if no such annotation exists.
+ * @throws NullPointerException if the annotation class is <code>null</code>.
+ */
+ native Annotation getAnnotation(Class annotationClass);
+
+ /**
+ * Returns all annotations directly defined by the element. If there are
+ * no annotations directly associated with the element, then a zero-length
+ * array will be returned. The returned array may be modified by the client
+ * code, but this will have no effect on the annotation content of this
+ * class, and hence no effect on the return value of this method for
+ * future callers.
+ *
+ * @return the annotations directly defined by the element.
+ * @since 1.5
+ */
+ native Annotation[] getDeclaredAnnotations();
+
+}
diff --git a/libjava/classpath/vm/reference/java/lang/reflect/VMField.java b/libjava/classpath/vm/reference/java/lang/reflect/VMField.java
new file mode 100644
index 000000000..ee9239a8e
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/reflect/VMField.java
@@ -0,0 +1,549 @@
+/* java.lang.reflect.Field - VM interface for reflection of Java fields
+ Copyright (C) 1998, 2001, 2005, 2008 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import java.lang.annotation.Annotation;
+
+final class VMField
+{
+ Class clazz;
+ String name;
+ int slot;
+
+ /**
+ * This field allows us to refer back to the main constructor instance.
+ * It is set by the constructor of Field.
+ */
+ Field f;
+
+ VMField(Class clazz, String name, int slot)
+ {
+ this.clazz = clazz;
+ this.name = name;
+ this.slot = slot;
+ }
+
+ public Class getDeclaringClass()
+ {
+ return clazz;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Return the raw modifiers for this field.
+ * @return the field's modifiers
+ */
+ native int getModifiersInternal();
+
+ /**
+ * Gets the type of this field.
+ * @return the type of this field
+ */
+ native Class getType();
+
+ /**
+ * Get the value of this Field. If it is primitive, it will be wrapped
+ * in the appropriate wrapper type (boolean = java.lang.Boolean).<p>
+ *
+ * If the field is static, <code>o</code> will be ignored. Otherwise, if
+ * <code>o</code> is null, you get a <code>NullPointerException</code>,
+ * and if it is incompatible with the declaring class of the field, you
+ * get an <code>IllegalArgumentException</code>.<p>
+ *
+ * Next, if this Field enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not access this field in similar compiled code. If the field
+ * is static, and its class is uninitialized, you trigger class
+ * initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Finally, the field is accessed, and primitives are wrapped (but not
+ * necessarily in new objects). This method accesses the field of the
+ * declaring class, even if the instance passed in belongs to a subclass
+ * which declares another field to hide this one.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if <code>o</code> is not an instance of
+ * the class or interface declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #getBoolean(Object)
+ * @see #getByte(Object)
+ * @see #getChar(Object)
+ * @see #getShort(Object)
+ * @see #getInt(Object)
+ * @see #getLong(Object)
+ * @see #getFloat(Object)
+ * @see #getDouble(Object)
+ */
+ native Object get(Object o)
+ throws IllegalAccessException;
+
+ /**
+ * Get the value of this boolean Field. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a boolean field of
+ * <code>o</code>, or if <code>o</code> is not an instance of the
+ * declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ native boolean getBoolean(Object o)
+ throws IllegalAccessException;
+
+ /**
+ * Get the value of this byte Field. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte field of
+ * <code>o</code>, or if <code>o</code> is not an instance of the
+ * declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ native byte getByte(Object o)
+ throws IllegalAccessException;
+
+ /**
+ * Get the value of this Field as a char. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a char field of
+ * <code>o</code>, or if <code>o</code> is not an instance
+ * of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ native char getChar(Object o)
+ throws IllegalAccessException;
+
+ /**
+ * Get the value of this Field as a short. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte or short
+ * field of <code>o</code>, or if <code>o</code> is not an instance
+ * of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ native short getShort(Object o)
+ throws IllegalAccessException;
+
+ /**
+ * Get the value of this Field as an int. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, or
+ * int field of <code>o</code>, or if <code>o</code> is not an
+ * instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ native int getInt(Object o)
+ throws IllegalAccessException;
+
+ /**
+ * Get the value of this Field as a long. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * or long field of <code>o</code>, or if <code>o</code> is not an
+ * instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ native long getLong(Object o)
+ throws IllegalAccessException;
+
+ /**
+ * Get the value of this Field as a float. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * long, or float field of <code>o</code>, or if <code>o</code> is
+ * not an instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ native float getFloat(Object o)
+ throws IllegalAccessException;
+
+ /**
+ * Get the value of this Field as a double. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * long, float, or double field of <code>o</code>, or if
+ * <code>o</code> is not an instance of the declaring class of this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ native double getDouble(Object o)
+ throws IllegalAccessException;
+
+ /**
+ * Set the value of this Field. If it is a primitive field, the value
+ * will be unwrapped from the passed object (boolean = java.lang.Boolean).<p>
+ *
+ * If the field is static, <code>o</code> will be ignored. Otherwise, if
+ * <code>o</code> is null, you get a <code>NullPointerException</code>,
+ * and if it is incompatible with the declaring class of the field, you
+ * get an <code>IllegalArgumentException</code>.<p>
+ *
+ * Next, if this Field enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not access this field in similar compiled code. This also
+ * occurs whether or not there is access control if the field is final.
+ * If the field is primitive, and unwrapping your argument fails, you will
+ * get an <code>IllegalArgumentException</code>; likewise, this error
+ * happens if <code>value</code> cannot be cast to the correct object type.
+ * If the field is static, and its class is uninitialized, you trigger class
+ * initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Finally, the field is set with the widened value. This method accesses
+ * the field of the declaring class, even if the instance passed in belongs
+ * to a subclass which declares another field to hide this one.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if <code>value</code> cannot be
+ * converted by a widening conversion to the underlying type of
+ * the Field, or if <code>o</code> is not an instance of the class
+ * declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #setBoolean(Object, boolean)
+ * @see #setByte(Object, byte)
+ * @see #setChar(Object, char)
+ * @see #setShort(Object, short)
+ * @see #setInt(Object, int)
+ * @see #setLong(Object, long)
+ * @see #setFloat(Object, float)
+ * @see #setDouble(Object, double)
+ */
+ native void set(Object o, Object value)
+ throws IllegalAccessException;
+
+ /**
+ * Set this boolean Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a boolean field, or if
+ * <code>o</code> is not an instance of the class declaring this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ native void setBoolean(Object o, boolean value)
+ throws IllegalAccessException;
+
+ /**
+ * Set this byte Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, int, long,
+ * float, or double field, or if <code>o</code> is not an instance
+ * of the class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ native void setByte(Object o, byte value)
+ throws IllegalAccessException;
+
+ /**
+ * Set this char Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a char, int, long,
+ * float, or double field, or if <code>o</code> is not an instance
+ * of the class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ native void setChar(Object o, char value)
+ throws IllegalAccessException;
+
+ /**
+ * Set this short Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a short, int, long,
+ * float, or double field, or if <code>o</code> is not an instance
+ * of the class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ native void setShort(Object o, short value)
+ throws IllegalAccessException;
+
+ /**
+ * Set this int Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not an int, long, float, or
+ * double field, or if <code>o</code> is not an instance of the
+ * class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ native void setInt(Object o, int value)
+ throws IllegalAccessException;
+
+ /**
+ * Set this long Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a long, float, or double
+ * field, or if <code>o</code> is not an instance of the class
+ * declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ native void setLong(Object o, long value)
+ throws IllegalAccessException;
+
+ /**
+ * Set this float Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a float or long field, or
+ * if <code>o</code> is not an instance of the class declaring this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ native void setFloat(Object o, float value)
+ throws IllegalAccessException;
+
+ /**
+ * Set this double Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a double field, or if
+ * <code>o</code> is not an instance of the class declaring this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ native void setDouble(Object o, double value)
+ throws IllegalAccessException;
+
+ /**
+ * Return the String in the Signature attribute for this field. If there
+ * is no Signature attribute, return null.
+ *
+ */
+ native String getSignature();
+
+ /**
+ * Compare two objects to see if they are semantically equivalent.
+ * Two Fields are semantically equivalent if they have the same declaring
+ * class, name, and type. Since you can't create a Field except through
+ * the VM, this is just the == relation.
+ *
+ * @param o the object to compare to
+ * @return <code>true</code> if they are equal; <code>false</code> if not
+ */
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof Field))
+ return false;
+ Field that = (Field)o;
+ if (clazz != that.getDeclaringClass())
+ return false;
+ if (!name.equals(that.getName()))
+ return false;
+ if (getType() != that.getType())
+ return false;
+ return true;
+ }
+
+ /**
+ * Returns the element's annotation for the specified annotation type,
+ * or <code>null</code> if no such annotation exists.
+ *
+ * @param annotationClass the type of annotation to look for.
+ * @return this element's annotation for the specified type, or
+ * <code>null</code> if no such annotation exists.
+ * @throws NullPointerException if the annotation class is <code>null</code>.
+ */
+ native Annotation getAnnotation(Class annotationClass);
+
+ /**
+ * Returns all annotations directly defined by the element. If there are
+ * no annotations directly associated with the element, then a zero-length
+ * array will be returned. The returned array may be modified by the client
+ * code, but this will have no effect on the annotation content of this
+ * class, and hence no effect on the return value of this method for
+ * future callers.
+ *
+ * @return the annotations directly defined by the element.
+ * @since 1.5
+ */
+ native Annotation[] getDeclaredAnnotations();
+
+}
diff --git a/libjava/classpath/vm/reference/java/lang/reflect/VMMethod.java b/libjava/classpath/vm/reference/java/lang/reflect/VMMethod.java
new file mode 100644
index 000000000..d8bb8b4a3
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/reflect/VMMethod.java
@@ -0,0 +1,208 @@
+/* java.lang.reflect.VMMethod - VM interface for reflection of Java methods
+ Copyright (C) 1998, 2001, 2002, 2005, 2007, 2008 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import java.lang.annotation.Annotation;
+
+import java.util.Arrays;
+
+final class VMMethod
+{
+ Class clazz;
+ String name;
+ int slot;
+
+ /**
+ * This field allows us to refer back to the main constructor instance.
+ * It is set by the constructor of Field.
+ */
+ Method m;
+
+ public Class getDeclaringClass()
+ {
+ return clazz;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Return the raw modifiers for this method.
+ * @return the method's modifiers
+ */
+ native int getModifiersInternal();
+
+ /**
+ * Gets the return type of this method.
+ * @return the type of this method
+ */
+ native Class getReturnType();
+
+ /**
+ * Get the parameter list for this method, in declaration order. If the
+ * method takes no parameters, returns a 0-length array (not null).
+ *
+ * @return a list of the types of the method's parameters
+ */
+ native Class[] getParameterTypes();
+
+ /**
+ * Get the exception types this method says it throws, in no particular
+ * order. If the method has no throws clause, returns a 0-length array
+ * (not null).
+ *
+ * @return a list of the types in the method's throws clause
+ */
+ native Class[] getExceptionTypes();
+
+ native Object invoke(Object o, Object[] args)
+ throws IllegalAccessException, InvocationTargetException;
+
+ /**
+ * Return the String in the Signature attribute for this method. If there
+ * is no Signature attribute, return null.
+ */
+ native String getSignature();
+
+ /**
+ * If this method is an annotation method, returns the default
+ * value for the method. If there is no default value, or if the
+ * method is not a member of an annotation type, returns null.
+ * Primitive types are wrapped.
+ *
+ * @throws TypeNotPresentException if the method returns a Class,
+ * and the class cannot be found
+ *
+ * @since 1.5
+ */
+ native Object getDefaultValue();
+
+ /**
+ * <p>
+ * Return an array of arrays representing the annotations on each
+ * of the method's parameters. The outer array is aligned against
+ * the parameters of the method and is thus equal in length to
+ * the number of parameters (thus having a length zero if there are none).
+ * Each array element in the outer array contains an inner array which
+ * holds the annotations. This array has a length of zero if the parameter
+ * has no annotations.
+ * </p>
+ * <p>
+ * The returned annotations are serialized. Changing the annotations has
+ * no affect on the return value of future calls to this method.
+ * </p>
+ *
+ * @return an array of arrays which represents the annotations used on the
+ * parameters of this method. The order of the array elements
+ * matches the declaration order of the parameters.
+ * @since 1.5
+ */
+ native Annotation[][] getParameterAnnotations();
+
+ /**
+ * Compare two objects to see if they are semantically equivalent.
+ * Two Methods are semantically equivalent if they have the same declaring
+ * class, name, parameter list, and return type.
+ *
+ * @param o the object to compare to
+ * @return <code>true</code> if they are equal; <code>false</code> if not
+ */
+ public boolean equals(Object o)
+ {
+ // Implementation note:
+ // The following is a correct but possibly slow implementation.
+ //
+ // This class has a private field 'slot' that could be used by
+ // the VM implementation to "link" a particular method to a Class.
+ // In that case equals could be simply implemented as:
+ //
+ // if (o instanceof Method)
+ // {
+ // Method m = (Method)o;
+ // return m.declaringClass == this.declaringClass
+ // && m.slot == this.slot;
+ // }
+ // return false;
+ //
+ // If a VM uses the Method class as their native/internal representation
+ // then just using the following would be optimal:
+ //
+ // return this == o;
+ //
+ if (!(o instanceof Method))
+ return false;
+ Method that = (Method)o;
+ if (clazz != that.getDeclaringClass())
+ return false;
+ if (!name.equals(that.getName()))
+ return false;
+ if (getReturnType() != that.getReturnType())
+ return false;
+ if (!Arrays.equals(getParameterTypes(), that.getParameterTypes()))
+ return false;
+ return true;
+ }
+
+ /**
+ * Returns the element's annotation for the specified annotation type,
+ * or <code>null</code> if no such annotation exists.
+ *
+ * @param annotationClass the type of annotation to look for.
+ * @return this element's annotation for the specified type, or
+ * <code>null</code> if no such annotation exists.
+ * @throws NullPointerException if the annotation class is <code>null</code>.
+ */
+ native Annotation getAnnotation(Class annotationClass);
+
+ /**
+ * Returns all annotations directly defined by the element. If there are
+ * no annotations directly associated with the element, then a zero-length
+ * array will be returned. The returned array may be modified by the client
+ * code, but this will have no effect on the annotation content of this
+ * class, and hence no effect on the return value of this method for
+ * future callers.
+ *
+ * @return the annotations directly defined by the element.
+ * @since 1.5
+ */
+ native Annotation[] getDeclaredAnnotations();
+
+}
diff --git a/libjava/classpath/vm/reference/java/lang/reflect/VMProxy.java b/libjava/classpath/vm/reference/java/lang/reflect/VMProxy.java
new file mode 100644
index 000000000..8c7b67a72
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/lang/reflect/VMProxy.java
@@ -0,0 +1,135 @@
+/* VMProxy.java -- VM interface for proxy class
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+final class VMProxy
+{
+ /**
+ * Set to true if the VM provides a native method to implement
+ * Proxy.getProxyClass completely, including argument verification.
+ * If this is true, HAVE_NATIVE_GET_PROXY_DATA and
+ * HAVE_NATIVE_GENERATE_PROXY_CLASS should be false.
+ * @see java.lang.reflect.Proxy
+ */
+ static boolean HAVE_NATIVE_GET_PROXY_CLASS = false;
+
+ /**
+ * Set to true if the VM provides a native method to implement
+ * the first part of Proxy.getProxyClass: generation of the array
+ * of methods to convert, and verification of the arguments.
+ * If this is true, HAVE_NATIVE_GET_PROXY_CLASS should be false.
+ * @see java.lang.reflect.Proxy
+ */
+ static boolean HAVE_NATIVE_GET_PROXY_DATA = false;
+
+ /**
+ * Set to true if the VM provides a native method to implement
+ * the second part of Proxy.getProxyClass: conversion of an array of
+ * methods into an actual proxy class.
+ * If this is true, HAVE_NATIVE_GET_PROXY_CLASS should be false.
+ * @see java.lang.reflect.Proxy
+ */
+ static boolean HAVE_NATIVE_GENERATE_PROXY_CLASS = false;
+
+ /**
+ * Optional native method to replace (and speed up) the pure Java
+ * implementation of getProxyClass. Only needed if
+ * VMProxy.HAVE_NATIVE_GET_PROXY_CLASS is true, this does the
+ * work of both getProxyData and generateProxyClass with no
+ * intermediate form in Java. The native code may safely assume that
+ * this class must be created, and does not already exist.
+ *
+ * @param loader the class loader to define the proxy class in; null
+ * implies the bootstrap class loader
+ * @param interfaces the interfaces the class will extend
+ * @return the generated proxy class
+ * @throws IllegalArgumentException if the constraints for getProxyClass
+ * were violated, except for problems with null
+ * @throws NullPointerException if `interfaces' is null or contains
+ * a null entry, or if handler is null
+ * @see #HAVE_NATIVE_GET_PROXY_CLASS
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see #getProxyData(ClassLoader, Class[])
+ * @see #generateProxyClass(ClassLoader, Proxy.ProxyData)
+ */
+ static native Class getProxyClass(ClassLoader loader, Class[] interfaces);
+
+ /**
+ * Optional native method to replace (and speed up) the pure Java
+ * implementation of getProxyData. Only needed if
+ * Configuration.HAVE_NATIVE_GET_PROXY_DATA is true. The native code
+ * may safely assume that a new ProxyData object must be created which
+ * does not duplicate any existing ones.
+ *
+ * @param loader the class loader to define the proxy class in; null
+ * implies the bootstrap class loader
+ * @param interfaces the interfaces the class will extend
+ * @return all data that is required to make this proxy class
+ * @throws IllegalArgumentException if the constraints for getProxyClass
+ * were violated, except for problems with null
+ * @throws NullPointerException if `interfaces' is null or contains
+ * a null entry, or if handler is null
+ * @see #HAVE_NATIVE_GET_PROXY_DATA
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see Proxy.ProxyData#getProxyData(Proxy.ProxyType)
+ */
+ static native Proxy.ProxyData getProxyData(ClassLoader loader,
+ Class[] interfaces);
+
+ /**
+ * Optional native method to replace (and speed up) the pure Java
+ * implementation of generateProxyClass. Only needed if
+ * Configuration.HAVE_NATIVE_GENERATE_PROXY_CLASS is true. The native
+ * code may safely assume that a new Class must be created, and that
+ * the ProxyData object does not describe any existing class.
+ *
+ * @param loader the class loader to define the proxy class in; null
+ * implies the bootstrap class loader
+ * @param data the struct of information to convert to a Class. This
+ * has already been verified for all problems except exceeding
+ * VM limitations
+ * @return the newly generated class
+ * @throws IllegalArgumentException if VM limitations are exceeded
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see #getProxyClass(ClassLoader, Class[])
+ */
+ static native Class generateProxyClass(ClassLoader loader,
+ Proxy.ProxyData data);
+}
diff --git a/libjava/classpath/vm/reference/java/net/VMInetAddress.java b/libjava/classpath/vm/reference/java/net/VMInetAddress.java
new file mode 100644
index 000000000..a99c216b9
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/net/VMInetAddress.java
@@ -0,0 +1,97 @@
+/* VMInetAddress.java -- Class to model an Internet address
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.net;
+
+import gnu.classpath.Configuration;
+
+import java.io.Serializable;
+
+class VMInetAddress implements Serializable
+{
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ System.loadLibrary("javanet");
+ }
+
+ /**
+ * This method looks up the hostname of the local machine
+ * we are on. If the actual hostname cannot be determined, then the
+ * value "localhost" will be used. This native method wrappers the
+ * "gethostname" function.
+ *
+ * @return The local hostname.
+ */
+ public static native String getLocalHostname();
+
+ /**
+ * Returns the value of the special address INADDR_ANY
+ */
+ public static native byte[] lookupInaddrAny() throws UnknownHostException;
+
+ /**
+ * This method returns the hostname for a given IP address. It will
+ * throw an UnknownHostException if the hostname cannot be determined.
+ *
+ * @param ip The IP address as a byte array
+ *
+ * @return The hostname
+ *
+ * @exception UnknownHostException If the reverse lookup fails
+ */
+ public static native String getHostByAddr(byte[] ip)
+ throws UnknownHostException;
+
+ /**
+ * Returns a list of all IP addresses for a given hostname. Will throw
+ * an UnknownHostException if the hostname cannot be resolved.
+ */
+ public static native byte[][] getHostByName(String hostname)
+ throws UnknownHostException;
+
+ /**
+ * Return the IP address represented by a literal address.
+ * Will return null if the literal address is not valid.
+ *
+ * @param address the name of the host
+ *
+ * @return The IP address as a byte array
+ */
+ public static native byte[] aton(String address);
+}
diff --git a/libjava/classpath/vm/reference/java/net/VMNetworkInterface.java b/libjava/classpath/vm/reference/java/net/VMNetworkInterface.java
new file mode 100644
index 000000000..fca0c525a
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/net/VMNetworkInterface.java
@@ -0,0 +1,131 @@
+/* VMNetworkInterface.java --
+ Copyright (C) 2005, 2008 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.net;
+
+import gnu.classpath.Configuration;
+
+import java.nio.ByteBuffer;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * This class models a network interface on the host computer. A network
+ * interface contains a name (typically associated with a specific
+ * hardware adapter) and a list of addresses that are bound to it.
+ * For example, an ethernet interface may be named "eth0" and have the
+ * address 192.168.1.101 assigned to it.
+ *
+ * @author Michael Koch (konqueror@gmx.de)
+ * @since 1.4
+ */
+final class VMNetworkInterface
+{
+ String name;
+ Set addresses;
+
+ VMNetworkInterface(String name)
+ {
+ this.name = name;
+ addresses = new HashSet();
+ }
+
+ /**
+ * Creates a dummy instance which represents any network
+ * interface.
+ */
+ public VMNetworkInterface()
+ {
+ addresses = new HashSet();
+ try
+ {
+ addresses.add(InetAddress.getByName("0.0.0.0"));
+ }
+ catch (UnknownHostException _)
+ {
+ // Cannot happen.
+ }
+ }
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ System.loadLibrary("javanet");
+
+ initIds();
+ }
+
+ private static native void initIds();
+
+ /**
+ * Return a list of VM network interface objects.
+ *
+ * @return The list of network interfaces.
+ * @throws SocketException
+ */
+ public static native VMNetworkInterface[] getVMInterfaces()
+ throws SocketException;
+
+ private void addAddress(ByteBuffer addr)
+ throws SocketException, UnknownHostException
+ {
+ if (addr.remaining() == 4)
+ {
+ byte[] ipv4 = new byte[4];
+ addr.get(ipv4);
+ addresses.add(Inet4Address.getByAddress(ipv4));
+ }
+ else if (addr.remaining() == 16)
+ {
+ byte[] ipv6 = new byte[16];
+ addr.get(ipv6);
+ addresses.add(Inet6Address.getByAddress(ipv6));
+ }
+ else
+ throw new SocketException("invalid interface address");
+ }
+
+ static native boolean isUp(String name) throws SocketException;
+
+ static native boolean isLoopback(String name) throws SocketException;
+
+ static native boolean isPointToPoint(String name) throws SocketException;
+
+ static native boolean supportsMulticast(String name) throws SocketException;
+
+}
diff --git a/libjava/classpath/vm/reference/java/net/VMURLConnection.java b/libjava/classpath/vm/reference/java/net/VMURLConnection.java
new file mode 100644
index 000000000..19bf5814e
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/net/VMURLConnection.java
@@ -0,0 +1,79 @@
+/* VMURLConnection - VM code for URLConnection
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.net;
+
+import gnu.classpath.Configuration;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+final class VMURLConnection
+{
+ public static final int LENGTH = 1024;
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ System.loadLibrary("javanet");
+ init();
+ }
+
+ private static native void init();
+
+ private static native String guessContentTypeFromBuffer(byte[] b, int valid);
+
+ /**
+ * This is called from URLConnection to guess the mime type of a
+ * stream. This method may return null to indicate that it could
+ * not guess a type.
+ */
+ static String guessContentTypeFromStream(InputStream is)
+ throws IOException
+ {
+ if (! is.markSupported())
+ return null;
+ is.mark(LENGTH);
+ byte[] bytes = new byte[LENGTH];
+ int r = is.read(bytes);
+ if (r < 0)
+ return null;
+ is.reset();
+ return guessContentTypeFromBuffer(bytes, r);
+ }
+}
diff --git a/libjava/classpath/vm/reference/java/nio/VMDirectByteBuffer.java b/libjava/classpath/vm/reference/java/nio/VMDirectByteBuffer.java
new file mode 100644
index 000000000..93a83883a
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/nio/VMDirectByteBuffer.java
@@ -0,0 +1,63 @@
+/* VMDirectByteBuffer.java --
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.nio;
+
+import gnu.classpath.Configuration;
+import gnu.classpath.Pointer;
+
+final class VMDirectByteBuffer
+{
+ static
+ {
+ // load the shared library needed for native methods.
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javanio");
+ }
+ }
+
+ static native Pointer allocate (int capacity);
+ static native void free(Pointer address);
+ static native byte get(Pointer address, int index);
+ static native void get(Pointer address, int index, byte[] dst, int offset, int length);
+ static native void put(Pointer address, int index, byte value);
+ static native void put(Pointer address, int index, byte[] src, int offset, int length);
+ static native Pointer adjustAddress(Pointer address, int offset);
+ static native void shiftDown(Pointer address, int dst_offset, int src_offset, int count);
+}
diff --git a/libjava/classpath/vm/reference/java/nio/channels/VMChannels.java b/libjava/classpath/vm/reference/java/nio/channels/VMChannels.java
new file mode 100644
index 000000000..05b1441c0
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/nio/channels/VMChannels.java
@@ -0,0 +1,116 @@
+/* VMChannels.java --
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.nio.channels;
+
+import gnu.java.nio.ChannelInputStream;
+import gnu.java.nio.ChannelOutputStream;
+import gnu.java.nio.FileChannelImpl;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+final class VMChannels
+{
+ /**
+ * This class isn't intended to be instantiated.
+ */
+ private VMChannels()
+ {
+ // Do nothing here.
+ }
+
+ private static Object createStream(Class streamClass, Channel ch)
+ {
+ try
+ {
+ Class[] argTypes = new Class[1];
+ argTypes[0] = FileChannelImpl.class;
+ Constructor constructor =
+ streamClass.getDeclaredConstructor(argTypes);
+ constructor.setAccessible(true);
+ Object[] args = new Object[1];
+ args[0] = ch;
+ return constructor.newInstance(args);
+ }
+ catch (IllegalAccessException e)
+ {
+ // Ignored.
+ }
+ catch (InstantiationException e)
+ {
+ // Ignored.
+ }
+ catch (InvocationTargetException e)
+ {
+ // Ignored.
+ }
+ catch (NoSuchMethodException e)
+ {
+ // Ignored.
+ }
+
+ return null;
+ }
+
+ /**
+ * Constructs a stream that reads bytes from the given channel.
+ */
+ static InputStream newInputStream(ReadableByteChannel ch)
+ {
+ if (ch instanceof FileChannelImpl)
+ return (FileInputStream) createStream(FileInputStream.class, ch);
+
+ return new ChannelInputStream(ch);
+ }
+
+ /**
+ * Constructs a stream that writes bytes to the given channel.
+ */
+ static OutputStream newOutputStream(WritableByteChannel ch)
+ {
+ if (ch instanceof FileChannelImpl)
+ return (FileOutputStream) createStream(FileOutputStream.class, ch);
+
+ return new ChannelOutputStream(ch);
+ }
+}
diff --git a/libjava/classpath/vm/reference/java/security/VMAccessController.java b/libjava/classpath/vm/reference/java/security/VMAccessController.java
new file mode 100644
index 000000000..9299e6f84
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/security/VMAccessController.java
@@ -0,0 +1,280 @@
+/* VMAccessController.java -- VM-specific access controller methods.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.security;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+
+final class VMAccessController
+{
+
+ // Fields.
+ // -------------------------------------------------------------------------
+
+ /**
+ * This is a per-thread stack of AccessControlContext objects (which can
+ * be null) for each call to AccessController.doPrivileged in each thread's
+ * call stack. We use this to remember which context object corresponds to
+ * which call.
+ */
+ private static final ThreadLocal contexts = new ThreadLocal();
+
+ /**
+ * This is a Boolean that, if set, tells getContext that it has already
+ * been called once, allowing us to handle recursive permission checks
+ * caused by methods getContext calls.
+ */
+ private static final ThreadLocal inGetContext = new ThreadLocal();
+
+ /**
+ * And we return this all-permissive context to ensure that privileged
+ * methods called from getContext succeed.
+ */
+ private static final AccessControlContext DEFAULT_CONTEXT;
+ static
+ {
+ CodeSource source = new CodeSource(null, null);
+ Permissions permissions = new Permissions();
+ permissions.add(new AllPermission());
+ ProtectionDomain[] domain = new ProtectionDomain[] {
+ new ProtectionDomain(source, permissions)
+ };
+ DEFAULT_CONTEXT = new AccessControlContext(domain);
+ }
+
+ private static final boolean DEBUG = gnu.classpath.Configuration.DEBUG;
+ private static void debug(String msg)
+ {
+ System.err.print(">>> VMAccessController: ");
+ System.err.println(msg);
+ }
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ private VMAccessController() { }
+
+ // Class methods.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Relate a class (which should be an instance of {@link PrivilegedAction}
+ * with an access control context. This method is used by {@link
+ * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}
+ * to set up the context that will be returned by {@link #getContext()}.
+ * This method relates the class to the current thread, so contexts
+ * pushed from one thread will not be available to another.
+ *
+ * @param acc The access control context.
+ */
+ static void pushContext (AccessControlContext acc)
+ {
+ if (DEBUG)
+ debug("pushing " + acc);
+ LinkedList stack = (LinkedList) contexts.get();
+ if (stack == null)
+ {
+ if (DEBUG)
+ debug("no stack... creating ");
+ stack = new LinkedList();
+ contexts.set(stack);
+ }
+ stack.addFirst(acc);
+ }
+
+ /**
+ * Removes the relation of a class to an {@link AccessControlContext}.
+ * This method is used by {@link AccessController} when exiting from a
+ * call to {@link
+ * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}.
+ */
+ static void popContext()
+ {
+ if (DEBUG)
+ debug("popping context");
+
+ // Stack should never be null, nor should it be empty, if this method
+ // and its counterpart has been called properly.
+ LinkedList stack = (LinkedList) contexts.get();
+ if (stack != null)
+ {
+ stack.removeFirst();
+ if (stack.isEmpty())
+ contexts.set(null);
+ }
+ else if (DEBUG)
+ {
+ debug("no stack during pop?????");
+ }
+ }
+
+ /**
+ * Examine the method stack of the currently running thread, and create
+ * an {@link AccessControlContext} filled in with the appropriate {@link
+ * ProtectionDomain} objects given this stack.
+ *
+ * @return The context.
+ */
+ static AccessControlContext getContext()
+ {
+ // If we are already in getContext, but called a method that needs
+ // a permission check, return the all-permissive context so methods
+ // called from here succeed.
+ //
+ // XXX is this necessary? We should verify if there are any calls in
+ // the stack below this method that require permission checks.
+ Boolean inCall = (Boolean) inGetContext.get();
+ if (inCall != null && inCall.booleanValue())
+ {
+ if (DEBUG)
+ debug("already in getContext");
+ return DEFAULT_CONTEXT;
+ }
+
+ inGetContext.set(Boolean.TRUE);
+
+ Object[][] stack = getStack();
+ Class[] classes = (Class[]) stack[0];
+ String[] methods = (String[]) stack[1];
+
+ if (DEBUG)
+ debug("got trace of length " + classes.length);
+
+ HashSet domains = new HashSet();
+ HashSet seenDomains = new HashSet();
+ AccessControlContext context = null;
+ int privileged = 0;
+
+ // We walk down the stack, adding each ProtectionDomain for each
+ // class in the call stack. If we reach a call to doPrivileged,
+ // we don't add any more stack frames. We skip the first three stack
+ // frames, since they comprise the calls to getStack, getContext,
+ // and AccessController.getContext.
+ for (int i = 3; i < classes.length && privileged < 2; i++)
+ {
+ Class clazz = classes[i];
+ String method = methods[i];
+
+ if (DEBUG)
+ {
+ debug("checking " + clazz + "." + method);
+ // subject to getClassLoader RuntimePermission
+ debug("loader = " + clazz.getClassLoader());
+ }
+
+ // If the previous frame was a call to doPrivileged, then this is
+ // the last frame we look at.
+ if (privileged == 1)
+ privileged = 2;
+
+ if (clazz.equals (AccessController.class)
+ && method.equals ("doPrivileged"))
+ {
+ // If there was a call to doPrivileged with a supplied context,
+ // return that context. If using JAAS doAs*, it should be
+ // a context with a SubjectDomainCombiner
+ LinkedList l = (LinkedList) contexts.get();
+ if (l != null)
+ context = (AccessControlContext) l.getFirst();
+ privileged = 1;
+ }
+
+ // subject to getProtectionDomain RuntimePermission
+ ProtectionDomain domain = clazz.getProtectionDomain();
+
+ if (domain == null)
+ continue;
+ if (seenDomains.contains(domain))
+ continue;
+ seenDomains.add(domain);
+
+ // Create a static snapshot of this domain, which may change over time
+ // if the current policy changes.
+ domains.add(new ProtectionDomain(domain.getCodeSource(),
+ domain.getPermissions()));
+ }
+
+ if (DEBUG)
+ debug("created domains: " + domains);
+
+ ProtectionDomain[] result = (ProtectionDomain[])
+ domains.toArray(new ProtectionDomain[domains.size()]);
+
+ if (context != null)
+ {
+ DomainCombiner dc = context.getDomainCombiner ();
+ // If the supplied context had no explicit DomainCombiner, use
+ // our private version, which computes the intersection of the
+ // context's domains with the derived set.
+ if (dc == null)
+ context = new AccessControlContext
+ (IntersectingDomainCombiner.SINGLETON.combine
+ (result, context.getProtectionDomains ()));
+ // Use the supplied DomainCombiner. This should be secure,
+ // because only trusted code may create an
+ // AccessControlContext with a custom DomainCombiner.
+ else
+ context = new AccessControlContext (result, context, dc);
+ }
+ // No context was supplied. Return the derived one.
+ else
+ context = new AccessControlContext (result);
+
+ inGetContext.set(Boolean.FALSE);
+ return context;
+ }
+
+ /**
+ * Returns a snapshot of the current call stack as a pair of arrays:
+ * the first an array of classes in the call stack, the second an array
+ * of strings containing the method names in the call stack. The two
+ * arrays match up, meaning that method <i>i</i> is declared in class
+ * <i>i</i>. The arrays are clean; it will only contain Java methods,
+ * and no element of the list should be null.
+ *
+ * <p>The default implementation returns an empty stack, which will be
+ * interpreted as having no permissions whatsoever.
+ *
+ * @return A pair of arrays describing the current call stack. The first
+ * element is an array of Class objects, and the second is an array
+ * of Strings comprising the method names.
+ */
+ private static Object[][] getStack()
+ {
+ return new Object[][] { new Class[0], new String[0] };
+ }
+}
diff --git a/libjava/classpath/vm/reference/java/security/VMSecureRandom.java b/libjava/classpath/vm/reference/java/security/VMSecureRandom.java
new file mode 100644
index 000000000..bea154977
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/security/VMSecureRandom.java
@@ -0,0 +1,129 @@
+/* VMSecureRandom.java -- random seed generator.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.security;
+
+/**
+ * VM-specific methods for generating real (or almost real) random
+ * seeds. VM implementors should write a version of this class that
+ * reads random bytes from some system source.
+ *
+ * <p>The default implementation of this class runs eight threads that
+ * increment counters in a tight loop, and XORs each counter to
+ * produce one byte of seed data. This is not very efficient, and is
+ * not guaranteed to be random (the thread scheduler is probably
+ * deterministic, after all). If possible, VM implementors should
+ * reimplement this class so it obtains a random seed from a system
+ * facility, such as a system entropy gathering device or hardware
+ * random number generator.
+ */
+final class VMSecureRandom
+{
+
+ /**
+ * Generate a random seed. Implementations are free to generate
+ * fewer random bytes than are requested, and leave the remaining
+ * bytes of the destination buffer as zeros. Implementations SHOULD,
+ * however, make a best-effort attempt to satisfy the request.
+ *
+ * @param buffer The destination buffer.
+ * @param offset The offset in the buffer to start putting bytes.
+ * @param length The number of random bytes to generate.
+ */
+ static int generateSeed(byte[] buffer, int offset, int length)
+ {
+ if (length < 0)
+ throw new IllegalArgumentException("length must be nonnegative");
+ if (offset < 0 || offset + length > buffer.length)
+ throw new IndexOutOfBoundsException();
+
+ Spinner[] spinners = new Spinner[8];
+ int n = 0x1;
+ for (int i = 0; i < spinners.length; i++)
+ {
+ spinners[i] = new Spinner((byte) n);
+ Thread t = new Thread(spinners[i]);
+ t.start();
+ n <<= 1;
+ }
+
+ // Wait until at least one spinner has started.
+ while (!(spinners[0].running || spinners[1].running || spinners[2].running
+ || spinners[3].running || spinners[4].running || spinners[5].running
+ || spinners[6].running || spinners[7].running))
+ {
+ Thread.yield();
+ }
+
+ for (int i = offset; i < length; i++)
+ {
+ buffer[i] = (byte) (spinners[0].value ^ spinners[1].value ^ spinners[2].value
+ ^ spinners[3].value ^ spinners[4].value ^ spinners[5].value
+ ^ spinners[6].value ^ spinners[7].value);
+ Thread.yield();
+ }
+
+ for (int i = 0; i < spinners.length; i++)
+ spinners[i].stop();
+
+ return length;
+ }
+
+ static class Spinner implements Runnable
+ {
+ volatile byte value;
+ volatile boolean running;
+
+ Spinner(final byte initial)
+ {
+ value = initial;
+ }
+
+ public void run()
+ {
+ running = true;
+ while (running)
+ value++;
+ }
+
+ private void stop()
+ {
+ running = false;
+ }
+ }
+}
diff --git a/libjava/classpath/vm/reference/java/util/VMTimeZone.java b/libjava/classpath/vm/reference/java/util/VMTimeZone.java
new file mode 100644
index 000000000..11061aa32
--- /dev/null
+++ b/libjava/classpath/vm/reference/java/util/VMTimeZone.java
@@ -0,0 +1,300 @@
+/* java.util.VMTimeZone
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util;
+
+import gnu.classpath.Configuration;
+import gnu.classpath.SystemProperties;
+import gnu.java.util.ZoneInfo;
+import java.util.TimeZone;
+
+import java.io.*;
+
+/**
+ *
+ */
+final class VMTimeZone
+{
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javautil");
+ }
+ }
+
+ /**
+ * This method returns a time zone id string which is in the form
+ * (standard zone name) or (standard zone name)(GMT offset) or
+ * (standard zone name)(GMT offset)(daylight time zone name). The
+ * GMT offset can be in seconds, or where it is evenly divisible by
+ * 3600, then it can be in hours. The offset must be the time to
+ * add to the local time to get GMT. If a offset is given and the
+ * time zone observes daylight saving then the (daylight time zone
+ * name) must also be given (otherwise it is assumed the time zone
+ * does not observe any daylight savings).
+ * <p>
+ * The result of this method is given to the method
+ * TimeZone.getDefaultTimeZone(String) which tries to map the time
+ * zone id to a known TimeZone. See that method on how the returned
+ * String is mapped to a real TimeZone object.
+ * <p>
+ * The reference implementation which is made for GNU/Posix like
+ * systems calls <code>System.getenv("TZ")</code>,
+ * <code>readTimeZoneFile("/etc/timezone")</code>,
+ * <code>ZoneInfo.readTZFile((String)null, "/etc/localtime")</code>
+ * and finally <code>getSystemTimeZoneId()</code> till a supported
+ * TimeZone is found through
+ * <code>TimeZone.getDefaultTimeZone(String)</code>.
+ * If every method fails <code>null</code> is returned (which means
+ * the TimeZone code will fall back on GMT as default time zone).
+ * <p>
+ * Note that this method is called inside a
+ * <code>AccessController.doPrivileged()</code> block and runs with
+ * the priviliges of the java.util system classes. It will only be
+ * called when the default time zone is not yet set, the system
+ * property user.timezone isn't set and it is requested for the
+ * first time.
+ */
+ static TimeZone getDefaultTimeZoneId()
+ {
+ TimeZone zone = null;
+
+ // See if TZ environment variable is set and accessible.
+ String tzid = System.getenv("TZ");
+ if (tzid != null && !tzid.equals(""))
+ zone = TimeZone.getDefaultTimeZone(tzid);
+
+ // Try to parse /etc/timezone.
+ if (zone == null)
+ {
+ tzid = readTimeZoneFile("/etc/timezone");
+ if (tzid != null && !tzid.equals(""))
+ zone = TimeZone.getDefaultTimeZone(tzid);
+ }
+
+ // Try to parse /etc/localtime
+ if (zone == null)
+ {
+ zone = ZoneInfo.readTZFile((String) null, "/etc/localtime");
+ if (zone != null)
+ {
+ // Try to find a more suitable ID for the /etc/localtime
+ // timezone.
+ // Sometimes /etc/localtime is a symlink to some
+ // /usr/share/zoneinfo/ file.
+ String id = null;
+ try
+ {
+ id = new File("/etc/localtime").getCanonicalPath();
+ if (id != null)
+ {
+ String zoneinfo_dir
+ = SystemProperties.getProperty("gnu.java.util.zoneinfo.dir");
+ if (zoneinfo_dir != null)
+ zoneinfo_dir
+ = new File(zoneinfo_dir
+ + File.separatorChar).getCanonicalPath();
+ if (zoneinfo_dir != null && id.startsWith(zoneinfo_dir))
+ {
+ int pos = zoneinfo_dir.length();
+ while (pos < id.length()
+ && id.charAt(pos) == File.separatorChar)
+ pos++;
+ if (pos < id.length())
+ id = id.substring(pos);
+ else
+ id = null;
+ }
+ else
+ id = null;
+ }
+ }
+ catch (IOException ioe)
+ {
+ id = null;
+ }
+
+ if (id == null)
+ id = readSysconfigClockFile("/etc/sysconfig/clock");
+
+ if (id != null)
+ zone.setID(id);
+ }
+ }
+
+ // Try some system specific way
+ if (zone == null)
+ {
+ tzid = getSystemTimeZoneId();
+ if (tzid != null && !tzid.equals(""))
+ zone = TimeZone.getDefaultTimeZone(tzid);
+ }
+
+ return zone;
+ }
+
+ /**
+ * Tries to read the time zone name from a file. Only the first
+ * consecutive letters, digits, slashes, dashes and underscores are
+ * read from the file. If the file cannot be read or an IOException
+ * occurs null is returned.
+ * <p>
+ * The /etc/timezone file is not standard, but a lot of systems have
+ * it. If it exist the first line always contains a string
+ * describing the timezone of the host of domain. Some systems
+ * contain a /etc/TIMEZONE file which is used to set the TZ
+ * environment variable (which is checked before /etc/timezone is
+ * read).
+ */
+ private static String readTimeZoneFile(String file)
+ {
+ File f = new File(file);
+ if (!f.exists())
+ return null;
+
+ InputStreamReader isr = null;
+ try
+ {
+ FileInputStream fis = new FileInputStream(f);
+ BufferedInputStream bis = new BufferedInputStream(fis);
+ isr = new InputStreamReader(bis);
+
+ StringBuffer sb = new StringBuffer();
+ int i = isr.read();
+ while (i != -1)
+ {
+ char c = (char) i;
+ if (Character.isLetter(c) || Character.isDigit(c)
+ || c == '/' || c == '-' || c == '_')
+ {
+ sb.append(c);
+ i = isr.read();
+ }
+ else
+ break;
+ }
+ return sb.toString();
+ }
+ catch (IOException ioe)
+ {
+ // Parse error, not a proper tzfile.
+ return null;
+ }
+ finally
+ {
+ try
+ {
+ if (isr != null)
+ isr.close();
+ }
+ catch (IOException ioe)
+ {
+ // Error while close, nothing we can do.
+ }
+ }
+ }
+
+ /**
+ * Tries to read the time zone name from a file.
+ * If the file cannot be read or an IOException occurs null is returned.
+ * <p>
+ * The /etc/sysconfig/clock file is not standard, but a lot of systems
+ * have it. The file is included by shell scripts and the timezone
+ * name is defined in ZONE variable.
+ * This routine should grok it with or without quotes:
+ * ZONE=America/New_York
+ * or
+ * ZONE="Europe/London"
+ */
+ private static String readSysconfigClockFile(String file)
+ {
+ BufferedReader br = null;
+ try
+ {
+ FileInputStream fis = new FileInputStream(file);
+ BufferedInputStream bis = new BufferedInputStream(fis);
+ br = new BufferedReader(new InputStreamReader(bis));
+
+ for (String line = br.readLine(); line != null; line = br.readLine())
+ {
+ line = line.trim();
+ if (line.length() < 8 || !line.startsWith("ZONE="))
+ continue;
+ int posstart = 6;
+ int posend;
+ if (line.charAt(5) == '"')
+ posend = line.indexOf('"', 6);
+ else if (line.charAt(5) == '\'')
+ posend = line.indexOf('\'', 6);
+ else
+ {
+ posstart = 5;
+ posend = line.length();
+ }
+ if (posend < 0)
+ return null;
+ return line.substring(posstart, posend);
+ }
+ return null;
+ }
+ catch (IOException ioe)
+ {
+ // Parse error, not a proper tzfile.
+ return null;
+ }
+ finally
+ {
+ try
+ {
+ if (br != null)
+ br.close();
+ }
+ catch (IOException ioe)
+ {
+ // Error while close, nothing we can do.
+ }
+ }
+ }
+
+ /**
+ * Tries to get the system time zone id through native code.
+ */
+ private static native String getSystemTimeZoneId();
+}
diff --git a/libjava/classpath/vm/reference/sun/misc/Unsafe.java b/libjava/classpath/vm/reference/sun/misc/Unsafe.java
new file mode 100644
index 000000000..e316bdb8d
--- /dev/null
+++ b/libjava/classpath/vm/reference/sun/misc/Unsafe.java
@@ -0,0 +1,328 @@
+/* Unsafe.java - Unsafe operations needed for concurrency
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package sun.misc;
+
+import java.lang.reflect.Field;
+
+/**
+ * This class should provide access to low-level operations and its
+ * use should be limited to trusted code. Fields can be accessed using
+ * memory addresses, with undefined behaviour occurring if invalid memory
+ * addresses are given.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+public class Unsafe
+{
+ // Singleton class.
+ private static Unsafe unsafe = new Unsafe();
+
+ /**
+ * Private default constructor to prevent creation of an arbitrary
+ * number of instances.
+ */
+ private Unsafe()
+ {
+ }
+
+ /**
+ * Retrieve the singleton instance of <code>Unsafe</code>. The calling
+ * method should guard this instance from untrusted code, as it provides
+ * access to low-level operations such as direct memory access.
+ *
+ * @throws SecurityException if a security manager exists and prevents
+ * access to the system properties.
+ */
+ public static Unsafe getUnsafe()
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPropertiesAccess();
+ return unsafe;
+ }
+
+ /**
+ * Returns the memory address offset of the given static field.
+ * The offset is merely used as a means to access a particular field
+ * in the other methods of this class. The value is unique to the given
+ * field and the same value should be returned on each subsequent call.
+ *
+ * @param field the field whose offset should be returned.
+ * @return the offset of the given field.
+ */
+ public native long objectFieldOffset(Field field);
+
+ /**
+ * Compares the value of the integer field at the specified offset
+ * in the supplied object with the given expected value, and updates
+ * it if they match. The operation of this method should be atomic,
+ * thus providing an uninterruptible way of updating an integer field.
+ *
+ * @param obj the object containing the field to modify.
+ * @param offset the offset of the integer field within <code>obj</code>.
+ * @param expect the expected value of the field.
+ * @param update the new value of the field if it equals <code>expect</code>.
+ * @return true if the field was changed.
+ */
+ public native boolean compareAndSwapInt(Object obj, long offset,
+ int expect, int update);
+
+ /**
+ * Compares the value of the long field at the specified offset
+ * in the supplied object with the given expected value, and updates
+ * it if they match. The operation of this method should be atomic,
+ * thus providing an uninterruptible way of updating a long field.
+ *
+ * @param obj the object containing the field to modify.
+ * @param offset the offset of the long field within <code>obj</code>.
+ * @param expect the expected value of the field.
+ * @param update the new value of the field if it equals <code>expect</code>.
+ * @return true if the field was changed.
+ */
+ public native boolean compareAndSwapLong(Object obj, long offset,
+ long expect, long update);
+
+ /**
+ * Compares the value of the object field at the specified offset
+ * in the supplied object with the given expected value, and updates
+ * it if they match. The operation of this method should be atomic,
+ * thus providing an uninterruptible way of updating an object field.
+ *
+ * @param obj the object containing the field to modify.
+ * @param offset the offset of the object field within <code>obj</code>.
+ * @param expect the expected value of the field.
+ * @param update the new value of the field if it equals <code>expect</code>.
+ * @return true if the field was changed.
+ */
+ public native boolean compareAndSwapObject(Object obj, long offset,
+ Object expect, Object update);
+
+ /**
+ * Sets the value of the integer field at the specified offset in the
+ * supplied object to the given value. This is an ordered or lazy
+ * version of <code>putIntVolatile(Object,long,int)</code>, which
+ * doesn't guarantee the immediate visibility of the change to other
+ * threads. It is only really useful where the integer field is
+ * <code>volatile</code>, and is thus expected to change unexpectedly.
+ *
+ * @param obj the object containing the field to modify.
+ * @param offset the offset of the integer field within <code>obj</code>.
+ * @param value the new value of the field.
+ * @see #putIntVolatile(Object,long,int)
+ */
+ public native void putOrderedInt(Object obj, long offset, int value);
+
+ /**
+ * Sets the value of the long field at the specified offset in the
+ * supplied object to the given value. This is an ordered or lazy
+ * version of <code>putLongVolatile(Object,long,long)</code>, which
+ * doesn't guarantee the immediate visibility of the change to other
+ * threads. It is only really useful where the long field is
+ * <code>volatile</code>, and is thus expected to change unexpectedly.
+ *
+ * @param obj the object containing the field to modify.
+ * @param offset the offset of the long field within <code>obj</code>.
+ * @param value the new value of the field.
+ * @see #putLongVolatile(Object,long,long)
+ */
+ public native void putOrderedLong(Object obj, long offset, long value);
+
+ /**
+ * Sets the value of the object field at the specified offset in the
+ * supplied object to the given value. This is an ordered or lazy
+ * version of <code>putObjectVolatile(Object,long,Object)</code>, which
+ * doesn't guarantee the immediate visibility of the change to other
+ * threads. It is only really useful where the object field is
+ * <code>volatile</code>, and is thus expected to change unexpectedly.
+ *
+ * @param obj the object containing the field to modify.
+ * @param offset the offset of the object field within <code>obj</code>.
+ * @param value the new value of the field.
+ */
+ public native void putOrderedObject(Object obj, long offset, Object value);
+
+ /**
+ * Sets the value of the integer field at the specified offset in the
+ * supplied object to the given value, with volatile store semantics.
+ *
+ * @param obj the object containing the field to modify.
+ * @param offset the offset of the integer field within <code>obj</code>.
+ * @param value the new value of the field.
+ */
+ public native void putIntVolatile(Object obj, long offset, int value);
+
+ /**
+ * Retrieves the value of the integer field at the specified offset in the
+ * supplied object with volatile load semantics.
+ *
+ * @param obj the object containing the field to read.
+ * @param offset the offset of the integer field within <code>obj</code>.
+ */
+ public native int getIntVolatile(Object obj, long offset);
+
+ /**
+ * Sets the value of the long field at the specified offset in the
+ * supplied object to the given value, with volatile store semantics.
+ *
+ * @param obj the object containing the field to modify.
+ * @param offset the offset of the long field within <code>obj</code>.
+ * @param value the new value of the field.
+ * @see #putLong(Object,long,long)
+ */
+ public native void putLongVolatile(Object obj, long offset, long value);
+
+ /**
+ * Sets the value of the long field at the specified offset in the
+ * supplied object to the given value.
+ *
+ * @param obj the object containing the field to modify.
+ * @param offset the offset of the long field within <code>obj</code>.
+ * @param value the new value of the field.
+ * @see #putLongVolatile(Object,long,long)
+ */
+ public native void putLong(Object obj, long offset, long value);
+
+ /**
+ * Retrieves the value of the long field at the specified offset in the
+ * supplied object with volatile load semantics.
+ *
+ * @param obj the object containing the field to read.
+ * @param offset the offset of the long field within <code>obj</code>.
+ * @see #getLong(Object,long)
+ */
+ public native long getLongVolatile(Object obj, long offset);
+
+ /**
+ * Retrieves the value of the long field at the specified offset in the
+ * supplied object.
+ *
+ * @param obj the object containing the field to read.
+ * @param offset the offset of the long field within <code>obj</code>.
+ * @see #getLongVolatile(Object,long)
+ */
+ public native long getLong(Object obj, long offset);
+
+ /**
+ * Sets the value of the object field at the specified offset in the
+ * supplied object to the given value, with volatile store semantics.
+ *
+ * @param obj the object containing the field to modify.
+ * @param offset the offset of the object field within <code>obj</code>.
+ * @param value the new value of the field.
+ * @see #putObject(Object,long,Object)
+ */
+ public native void putObjectVolatile(Object obj, long offset, Object value);
+
+ /**
+ * Sets the value of the object field at the specified offset in the
+ * supplied object to the given value.
+ *
+ * @param obj the object containing the field to modify.
+ * @param offset the offset of the object field within <code>obj</code>.
+ * @param value the new value of the field.
+ * @see #putObjectVolatile(Object,long,Object)
+ */
+ public native void putObject(Object obj, long offset, Object value);
+
+ /**
+ * Retrieves the value of the object field at the specified offset in the
+ * supplied object with volatile load semantics.
+ *
+ * @param obj the object containing the field to read.
+ * @param offset the offset of the object field within <code>obj</code>.
+ */
+ public native Object getObjectVolatile(Object obj, long offset);
+
+ /**
+ * Returns the offset of the first element for a given array class.
+ * To access elements of the array class, this value may be used along
+ * with that returned by
+ * <a href="#arrayIndexScale"><code>arrayIndexScale</code></a>,
+ * if non-zero.
+ *
+ * @param arrayClass the class for which the first element's address should
+ * be obtained.
+ * @return the offset of the first element of the array class.
+ * @see arrayIndexScale(Class)
+ */
+ public native int arrayBaseOffset(Class arrayClass);
+
+ /**
+ * Returns the scale factor used for addressing elements of the supplied
+ * array class. Where a suitable scale factor can not be returned (e.g.
+ * for primitive types), zero should be returned. The returned value
+ * can be used with
+ * <a href="#arrayBaseOffset"><code>arrayBaseOffset</code></a>
+ * to access elements of the class.
+ *
+ * @param arrayClass the class whose scale factor should be returned.
+ * @return the scale factor, or zero if not supported for this array class.
+ */
+ public native int arrayIndexScale(Class arrayClass);
+
+ /**
+ * Releases the block on a thread created by
+ * <a href="#park"><code>park</code></a>. This method can also be used
+ * to terminate a blockage caused by a prior call to <code>park</code>.
+ * This operation is unsafe, as the thread must be guaranteed to be
+ * live. This is true of Java, but not native code.
+ *
+ * @param thread the thread to unblock.
+ */
+ public native void unpark(Object thread);
+
+ /**
+ * Blocks the thread until a matching
+ * <a href="#unpark"><code>unpark</code></a> occurs, the thread is
+ * interrupted or the optional timeout expires. If an <code>unpark</code>
+ * call has already occurred, this also counts. A timeout value of zero
+ * is defined as no timeout. When <code>isAbsolute</code> is
+ * <code>true</code>, the timeout is in milliseconds relative to the
+ * epoch. Otherwise, the value is the number of nanoseconds which must
+ * occur before timeout. This call may also return spuriously (i.e.
+ * for no apparent reason).
+ *
+ * @param isAbsolute true if the timeout is specified in milliseconds from
+ * the epoch.
+ * @param time either the number of nanoseconds to wait, or a time in
+ * milliseconds from the epoch to wait for.
+ */
+ public native void park(boolean isAbsolute, long time);
+
+}
diff --git a/libjava/classpath/vm/reference/sun/reflect/Reflection.java b/libjava/classpath/vm/reference/sun/reflect/Reflection.java
new file mode 100644
index 000000000..ddbb69d16
--- /dev/null
+++ b/libjava/classpath/vm/reference/sun/reflect/Reflection.java
@@ -0,0 +1,51 @@
+/* Reflection.java - JSR 166 reflection hooks
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package sun.reflect;
+
+import gnu.classpath.VMStackWalker;
+
+public class Reflection
+{
+ /**
+ * A stack-walking wrapper method used by the JSR 166 RI.
+ */
+ public static Class getCallerClass(int depth)
+ {
+ return VMStackWalker.getClassContext()[depth];
+ }
+}
diff --git a/libjava/classpath/vm/reference/sun/reflect/misc/ReflectUtil.java b/libjava/classpath/vm/reference/sun/reflect/misc/ReflectUtil.java
new file mode 100644
index 000000000..aca365d6b
--- /dev/null
+++ b/libjava/classpath/vm/reference/sun/reflect/misc/ReflectUtil.java
@@ -0,0 +1,113 @@
+/* ReflectUtil.java - JSR 166 reflection hooks
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package sun.reflect.misc;
+
+import java.lang.reflect.Modifier;
+
+public class ReflectUtil
+{
+ // We use this inaccessible inner class as an argument type
+ // in verifyMemberAccess. All current users of this method
+ // in the JSR 166 RI pass 'null' for this argument, and
+ // consequently we don't know what it means. Using a funny
+ // type like this for the argument means that if the RI changes,
+ // we will see a compilation error.
+ private static class MustBeNull
+ {
+ }
+
+ /**
+ * Check if the current thread is allowed to access the package of
+ * the declaringClass.
+ *
+ * @param declaringClass class name to check access to
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if declaringClass is null
+ */
+ public static void checkPackageAccess(Class declaringClass)
+ {
+ SecurityManager sm;
+ if ((sm = System.getSecurityManager()) != null)
+ {
+ while (declaringClass.isArray())
+ declaringClass = declaringClass.getComponentType();
+ String name = declaringClass.getName();
+ int i = name.lastIndexOf('.');
+ if (i != -1) // if declaringClass is a member of a package
+ {
+ name = name.substring(0, i);
+ sm.checkPackageAccess(name);
+ }
+ }
+ }
+
+ /**
+ * Perform access checks on a member of a class. This API is
+ * derived from the public domain code in the JSR 166 reference
+ * implementation.
+ * @param caller the class requesting access to the member
+ * @param declarer the declaring class of the member
+ * @param ignored unknown parameter; always null
+ * @param modifiers the modifiers on the member
+ * @return true if access is granted, false otherwise
+ */
+ public static void ensureMemberAccess(Class caller,
+ Class declarer,
+ MustBeNull ignored,
+ int modifiers)
+ {
+ // Same class, always ok.
+ if (caller == declarer)
+ return;
+ // Public access is ok.
+ if ((modifiers & Modifier.PUBLIC) != 0)
+ return;
+ // Protected access and request comes from
+ // a subclass of the declarer -- ok.
+ if ((modifiers & Modifier.PROTECTED) != 0
+ && declarer.isAssignableFrom(caller))
+ return;
+ // Package-private access, or protected access,
+ // and the packages are the same --ok.
+ if ((modifiers & Modifier.PRIVATE) == 0
+ && caller.getPackage() == declarer.getPackage())
+ return;
+ // Otherwise, no.
+ throw new IllegalAccessError();
+ }
+}