]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Initial revision
authorTom Tromey <tromey@gcc.gnu.org>
Sat, 16 Jul 2005 00:31:27 +0000 (00:31 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Sat, 16 Jul 2005 00:31:27 +0000 (00:31 +0000)
From-SVN: r102075

32 files changed:
libjava/classpath/vm/.cvsignore [new file with mode: 0644]
libjava/classpath/vm/Makefile.am [new file with mode: 0644]
libjava/classpath/vm/reference/.cvsignore [new file with mode: 0644]
libjava/classpath/vm/reference/Makefile.am [new file with mode: 0644]
libjava/classpath/vm/reference/gnu/classpath/VMStackWalker.java [new file with mode: 0644]
libjava/classpath/vm/reference/gnu/classpath/VMSystemProperties.java [new file with mode: 0644]
libjava/classpath/vm/reference/gnu/java/nio/VMPipe.java [new file with mode: 0644]
libjava/classpath/vm/reference/gnu/java/nio/VMSelector.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/io/VMFile.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/io/VMObjectInputStream.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/io/VMObjectStreamClass.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/lang/VMClass.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/lang/VMClassLoader.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/lang/VMCompiler.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/lang/VMDouble.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/lang/VMFloat.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/lang/VMObject.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/lang/VMProcess.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/lang/VMRuntime.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/lang/VMString.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/lang/VMSystem.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/lang/VMThread.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/lang/VMThrowable.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/lang/reflect/Constructor.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/lang/reflect/Field.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/lang/reflect/Method.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/net/VMInetAddress.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/net/VMNetworkInterface.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/nio/VMDirectByteBuffer.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/nio/channels/VMChannels.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/security/VMAccessController.java [new file with mode: 0644]
libjava/classpath/vm/reference/java/util/VMTimeZone.java [new file with mode: 0644]

diff --git a/libjava/classpath/vm/.cvsignore b/libjava/classpath/vm/.cvsignore
new file mode 100644 (file)
index 0000000..282522d
--- /dev/null
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/libjava/classpath/vm/Makefile.am b/libjava/classpath/vm/Makefile.am
new file mode 100644 (file)
index 0000000..d89e468
--- /dev/null
@@ -0,0 +1,4 @@
+# used by automake to generate Makefile.in
+
+
+SUBDIRS = reference
diff --git a/libjava/classpath/vm/reference/.cvsignore b/libjava/classpath/vm/reference/.cvsignore
new file mode 100644 (file)
index 0000000..282522d
--- /dev/null
@@ -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 (file)
index 0000000..84b0350
--- /dev/null
@@ -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 (file)
index 0000000..28e4ce3
--- /dev/null
@@ -0,0 +1,108 @@
+/* VMStackWalker.java -- Reference implementation of VM hooks for stack access
+   Copyright (C) 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 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>getClassContext()[1].getClassLoader()</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 ctx[2].getClassLoader();
+  }
+}
+
diff --git a/libjava/classpath/vm/reference/gnu/classpath/VMSystemProperties.java b/libjava/classpath/vm/reference/gnu/classpath/VMSystemProperties.java
new file mode 100644 (file)
index 0000000..e7cb91f
--- /dev/null
@@ -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 p 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/java/nio/VMPipe.java b/libjava/classpath/vm/reference/gnu/java/nio/VMPipe.java
new file mode 100644 (file)
index 0000000..11dd2aa
--- /dev/null
@@ -0,0 +1,64 @@
+/* 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 java.nio.channels.spi.SelectorProvider;
+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");
+      }
+  }
+
+  static native void init(PipeImpl self, SelectorProvider provider)
+    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 (file)
index 0000000..488132d
--- /dev/null
@@ -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/java/io/VMFile.java b/libjava/classpath/vm/reference/java/io/VMFile.java
new file mode 100644 (file)
index 0000000..2931044
--- /dev/null
@@ -0,0 +1,229 @@
+/* VMFile.java -- Class for methods natively accessing files
+   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.io;
+
+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 file in this
+   * directory
+   */
+  static native 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);
+
+  /*
+   * 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 boolean canWriteDirectory(File dir)
+  {
+    try
+      {
+        String filename = IS_DOS_8_3 ? "tst" : "test-dir-write";
+        File test = File.createTempFile(filename, null, dir);
+        return (test != null && test.delete());
+      }
+    catch (IOException ioe)
+      {
+        return false;
+      }
+  }
+
+  /**
+   * This native method checks file permissions for reading
+   */
+  static synchronized native boolean canRead(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 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());
+  }
+
+  /**
+   * This method returns a canonical representation of the pathname of
+   * the given path.  The actual form of the canonical representation is
+   * different.  On the GNU system, the canonical form differs from the
+   * absolute form in that all relative file references to "." and ".."
+   * are resolved and removed.
+   * <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 String toCanonicalForm(String path) throws IOException
+  {
+       // FIXME: this only works on UNIX
+       return PlatformHelper.toCanonicalForm(path);
+  }
+}
diff --git a/libjava/classpath/vm/reference/java/io/VMObjectInputStream.java b/libjava/classpath/vm/reference/java/io/VMObjectInputStream.java
new file mode 100644 (file)
index 0000000..7cd9719
--- /dev/null
@@ -0,0 +1,86 @@
+/* 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.VMStackWalker;
+import java.lang.reflect.Constructor;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+final class VMObjectInputStream
+{
+  private static Class oisClass = ObjectInputStream.class;
+  private static Class vmoisClass = VMObjectInputStream.class;
+
+  // PrivilegedAction needed for Class.getClassLoader()
+  private static PrivilegedAction loaderAction = new PrivilegedAction()
+    {
+      public Object run()
+      {
+       Class[] ctx = VMStackWalker.getClassContext();
+       for (int i = 0; i < ctx.length; i++)
+         {
+           ClassLoader cl = ctx[i].getClassLoader();
+           if (cl != null)
+             return cl;
+         }
+       return null;
+      }
+    };
+
+  /**
+   * Returns the first user defined class loader on the call stack, or
+   * null when no non-null class loader was found.
+   */
+  static ClassLoader currentClassLoader()
+  {
+    return (ClassLoader) AccessController.doPrivileged(loaderAction);
+  }
+
+  /**
+   * 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 (file)
index 0000000..2aee7a9
--- /dev/null
@@ -0,0 +1,160 @@
+/* VMObjectStreamClass.java -- VM helper functions for ObjectStreamClass
+   Copyright (C) 2003  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.lang.reflect.Field;
+
+final class VMObjectStreamClass
+{
+  /**
+    * 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 (file)
index 0000000..0ca0329
--- /dev/null
@@ -0,0 +1,295 @@
+/* VMClass.java -- VM Specific Class methods
+   Copyright (C) 2003, 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.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/*
+ * 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>
+ */
+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 Modifer
+   * @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 pulicOnly 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 pulicOnly 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 pulicOnly 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 pulicOnly 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);
+
+  /**
+   * VM implementors are free to make this method a noop if 
+   * the default implementation is acceptable.
+   *
+   * @param name the name of the class to find
+   * @return the Class object representing the class or null for noop
+   * @throws ClassNotFoundException if the class was not found by the
+   *         classloader
+   * @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) 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);
+
+  /**
+   * This method should trigger class initialization (if the
+   * class hasn't already been initialized)
+   * 
+   * @param klass the Class object that's calling us
+   * @throws ExceptionInInitializerError if an exception
+   *         occurs during initialization
+   */
+  static native void initialize(Class klass);
+
+  /**
+   * Load an array class.
+   *
+   * @return the Class object representing the class
+   * @throws ClassNotFoundException if the class was not found by the
+   *         classloader
+   */
+  static native Class loadArrayClass(String name, ClassLoader classloader)
+       throws ClassNotFoundException;
+
+  /**
+   * Throw a checked exception without declaring it.
+   */
+  static native void throwException(Throwable t);
+
+} // 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 (file)
index 0000000..c62f0a4
--- /dev/null
@@ -0,0 +1,285 @@
+/* VMClassLoader.java -- Reference implementation of native interface
+   required by ClassLoader
+   Copyright (C) 1998, 2001, 2002, 2004, 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.SystemProperties;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+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
+{
+  /**
+   * 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
+   * @throws IOException if one occurs
+   */
+  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
+             {
+               v.add(new URL("file://"
+                 + new File(file, name).getAbsolutePath()));
+             }
+           catch (MalformedURLException e)
+             {
+               throw new Error(e);
+             }
+         }
+       else if (file.isFile())
+         {
+           ZipFile zip;
+           try
+             {
+               zip = new ZipFile(file);
+             }
+           catch (IOException e)
+             {
+               continue;
+             }
+           String zname = name.startsWith("/") ? name.substring(1) : name;
+           try
+             {
+               if (zip.getEntry(zname) == null)
+                   continue;
+             }
+           finally
+             {
+               try
+                 {
+                   zip.close();
+                 }
+               catch (IOException e)
+                 {
+                 }
+             }
+           try
+             {
+               v.add(new URL("jar:file://"
+                 + file.getAbsolutePath() + "!/" + zname));
+             }
+           catch (MalformedURLException e)
+             {
+               throw new Error(e);
+             }
+         }
+      }
+    return v.elements();
+  }
+
+  /**
+   * Helper to get a package from the bootstrap class loader.  The default
+   * implementation of returning null may be adequate, or you may decide
+   * that this needs some native help.
+   *
+   * @param name the name to find
+   * @return the named package, if it exists
+   */
+  static Package getPackage(String name)
+  {
+    return null;
+  }
+
+  /**
+   * Helper to get all packages from the bootstrap class loader.  The default
+   * implementation of returning an empty array may be adequate, or you may
+   * decide that this needs some native help.
+   *
+   * @return all named packages, if any exist
+   */
+  static Package[] getPackages()
+  {
+    return new Package[0];
+  }
+
+  /**
+   * 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();
+  }
+}
diff --git a/libjava/classpath/vm/reference/java/lang/VMCompiler.java b/libjava/classpath/vm/reference/java/lang/VMCompiler.java
new file mode 100644 (file)
index 0000000..fe74007
--- /dev/null
@@ -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 (file)
index 0000000..8a991c9
--- /dev/null
@@ -0,0 +1,131 @@
+/* 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
+   * collapses all versions of NaN to 0x7ff8000000000000L. 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 doubleToLongBits(double value);
+
+  /**
+   * 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 (file)
index 0000000..2e7f439
--- /dev/null
@@ -0,0 +1,111 @@
+/* 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 collapses all
+   * versions of NaN to 0x7fc00000. 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 floatToIntBits(float value);
+
+  /**
+   * 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);
+
+} // class VMFloat
diff --git a/libjava/classpath/vm/reference/java/lang/VMObject.java b/libjava/classpath/vm/reference/java/lang/VMObject.java
new file mode 100644 (file)
index 0000000..1d1ec40
--- /dev/null
@@ -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 (file)
index 0000000..fa157d7
--- /dev/null
@@ -0,0 +1,368 @@
+/* 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.LinkedList;
+
+/**
+ * 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 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
+ */
+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
+
+  //
+  // 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.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) throws IOException
+  {
+    
+    // Initialize this process
+    this.state = INITIAL;
+    this.cmd = cmd;
+    this.env = env;
+    this.dir = dir;
+  
+    // 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;
+    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);
+  }
+
+  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)
+    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 (file)
index 0000000..b685b35
--- /dev/null
@@ -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 (file)
index 0000000..7e65eed
--- /dev/null
@@ -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 (file)
index 0000000..70f9dba
--- /dev/null
@@ -0,0 +1,181 @@
+/* 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.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
+ */
+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 #in} to a new InputStream.
+   *
+   * @param in the new InputStream
+   * @see #setIn(InputStream)
+   */
+  static native void setIn(InputStream in);
+
+  /**
+   * Set {@link #out} to a new PrintStream.
+   *
+   * @param out the new PrintStream
+   * @see #setOut(PrintStream)
+   */
+  static native void setOut(PrintStream out);
+
+  /**
+   * Set {@link #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 native long currentTimeMillis();
+
+  /**
+   * 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 (file)
index 0000000..6b9102b
--- /dev/null
@@ -0,0 +1,450 @@
+/* VMThread -- VM interface for Thread of executable code
+   Copyright (C) 2003, 2004, 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;
+
+/**
+ * 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.group.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
+    {
+
+      // Round up
+      ms += (ns != 0) ? 1 : 0;
+
+      // 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)
+       {
+         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);
+             now = System.currentTimeMillis();
+             if (now >= end)
+               break;
+             ms = end - now;
+           }
+       }
+    }
+
+    /**
+     * 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;
+       }
+    }
+}
diff --git a/libjava/classpath/vm/reference/java/lang/VMThrowable.java b/libjava/classpath/vm/reference/java/lang/VMThrowable.java
new file mode 100644 (file)
index 0000000..19a204e
--- /dev/null
@@ -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/reflect/Constructor.java b/libjava/classpath/vm/reference/java/lang/reflect/Constructor.java
new file mode 100644 (file)
index 0000000..cddb9ad
--- /dev/null
@@ -0,0 +1,249 @@
+/* java.lang.reflect.Constructor - reflection of Java constructors
+   Copyright (C) 1998, 2001 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.util.Arrays;
+
+/**
+ * The Constructor class represents a constructor of a class. It also allows
+ * dynamic creation of an object, via reflection. Invocation on Constructor
+ * objects knows how to do widening conversions, but throws
+ * {@link IllegalArgumentException} if a narrowing conversion would be
+ * necessary. You can query for information on this Constructor regardless
+ * of location, but construction access may be limited by Java language
+ * access controls. If you can't do it in the compiler, you can't normally
+ * do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type.  They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc.  These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class.  It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getConstructor(Object[])
+ * @see java.lang.Class#getDeclaredConstructor(Object[])
+ * @see java.lang.Class#getConstructors()
+ * @see java.lang.Class#getDeclaredConstructors()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Constructor
+extends AccessibleObject implements Member
+{
+  private Class clazz;
+  private int slot;
+  
+  /**
+   * This class is uninstantiable except from native code.
+   */
+  private Constructor(Class declaringClass,int slot)
+  {
+    this.clazz = declaringClass;
+    this.slot = slot;
+  }
+
+  private Constructor()
+  {
+  }
+
+  /**
+   * Gets the class that declared this constructor.
+   * @return the class that declared this member
+   */
+  public Class getDeclaringClass()
+  {
+    return clazz;
+  }
+
+  /**
+   * Gets the name of this constructor (the non-qualified name of the class
+   * it was declared in).
+   * @return the name of this constructor
+   */
+  public String getName()
+  {
+    return getDeclaringClass().getName();
+  }
+
+  /**
+   * Gets the modifiers this constructor uses.  Use the <code>Modifier</code>
+   * class to interpret the values. A constructor can only have a subset of the
+   * following modifiers: public, private, protected.
+   *
+   * @return an integer representing the modifiers to this Member
+   * @see Modifier
+   */
+  public native int getModifiers();
+
+  /**
+   * 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
+   */
+  public 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
+   */
+  public native Class[] getExceptionTypes();
+
+  /**
+   * 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 (this.getDeclaringClass() != that.getDeclaringClass())
+      return false;
+    if (!Arrays.equals(this.getParameterTypes(), that.getParameterTypes()))
+      return false;
+    return true;
+  }
+
+  /**
+   * Get the hash code for the Constructor. The Constructor hash code is the
+   * hash code of the declaring class's name.
+   *
+   * @return the hash code for the object
+   */
+  public int hashCode()
+  {
+    return getDeclaringClass().getName().hashCode();
+  }
+
+  /**
+   * Get a String representation of the Constructor. A Constructor's String
+   * representation is "&lt;modifier&gt; &lt;classname&gt;(&lt;paramtypes&gt;)
+   * throws &lt;exceptions&gt;", where everything after ')' is omitted if
+   * there are no exceptions.<br> Example:
+   * <code>public java.io.FileInputStream(java.lang.Runnable)
+   * throws java.io.FileNotFoundException</code>
+   *
+   * @return the String representation of the Constructor
+   */
+  public String toString()
+  {
+    // 128 is a reasonable buffer initial size for constructor
+    StringBuffer sb = new StringBuffer(128);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    sb.append(getDeclaringClass().getName()).append('(');
+    Class[] c = getParameterTypes();
+    if (c.length > 0)
+      {
+        sb.append(c[0].getName());
+        for (int i = 1; i < c.length; i++)
+          sb.append(',').append(c[i].getName());
+      }
+    sb.append(')');
+    c = getExceptionTypes();
+    if (c.length > 0)
+      {
+        sb.append(" throws ").append(c[0].getName());
+        for (int i = 1; i < c.length; i++)
+          sb.append(',').append(c[i].getName());
+      }
+    return sb.toString();
+  }
+  /**
+   * Create a new instance by invoking the constructor. Arguments are
+   * automatically unwrapped and widened, if needed.<p>
+   *
+   * If this class is abstract, you will get an
+   * <code>InstantiationException</code>. If the constructor takes 0
+   * arguments, you may use null or a 0-length array for <code>args</code>.<p>
+   *
+   * If this Constructor enforces access control, your runtime context is
+   * evaluated, and you may have an <code>IllegalAccessException</code> if
+   * you could not create this object in similar compiled code. If the class
+   * is uninitialized, you trigger class initialization, which may end in a
+   * <code>ExceptionInInitializerError</code>.<p>
+   *
+   * Then, the constructor is invoked. If it completes normally, the return
+   * value will be the new object. If it completes abruptly, the exception is
+   * wrapped in an <code>InvocationTargetException</code>.
+   *
+   * @param args the arguments to the constructor
+   * @return the newly created object
+   * @throws IllegalAccessException if the constructor could not normally be
+   *         called by the Java code (i.e. it is not public)
+   * @throws IllegalArgumentException if the number of arguments is incorrect;
+   *         or if the arguments types are wrong even with a widening
+   *         conversion
+   * @throws InstantiationException if the class is abstract
+   * @throws InvocationTargetException if the constructor throws an exception
+   * @throws ExceptionInInitializerError if construction triggered class
+   *         initialization, which then failed
+   */
+  public Object newInstance(Object args[])
+    throws InstantiationException, IllegalAccessException,
+           InvocationTargetException
+  {
+    return constructNative(args, clazz, slot);
+  }
+
+  private native Object constructNative(Object[] args, Class declaringClass,
+                                        int slot)
+    throws InstantiationException, IllegalAccessException,
+           InvocationTargetException;
+}
diff --git a/libjava/classpath/vm/reference/java/lang/reflect/Field.java b/libjava/classpath/vm/reference/java/lang/reflect/Field.java
new file mode 100644 (file)
index 0000000..85e76d6
--- /dev/null
@@ -0,0 +1,589 @@
+/* java.lang.reflect.Field - reflection of Java fields
+   Copyright (C) 1998, 2001 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;
+
+/**
+ * The Field class represents a member variable of a class. It also allows
+ * dynamic access to a member, via reflection. This works for both
+ * static and instance fields. Operations on Field objects know how to
+ * do widening conversions, but throw {@link IllegalArgumentException} if
+ * a narrowing conversion would be necessary. You can query for information
+ * on this Field regardless of location, but get and set access may be limited
+ * by Java language access controls. If you can't do it in the compiler, you
+ * can't normally do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type.  They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc.  These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class.  It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @see Member
+ * @see Class
+ * @see Class#getField(String)
+ * @see Class#getDeclaredField(String)
+ * @see Class#getFields()
+ * @see Class#getDeclaredFields()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Field
+extends AccessibleObject implements Member
+{
+  private Class declaringClass;
+  private String name;
+  private int slot;
+
+  /**
+   * This class is uninstantiable except natively.
+   */
+  private Field(Class declaringClass, String name, int slot)
+  {
+    this.declaringClass = declaringClass;
+    this.name = name;
+    this.slot = slot;
+  }
+
+  /**
+   * Gets the class that declared this field, or the class where this field
+   * is a non-inherited member.
+   * @return the class that declared this member
+   */
+  public Class getDeclaringClass()
+  {
+    return declaringClass;
+  }
+
+  /**
+   * Gets the name of this field.
+   * @return the name of this field
+   */
+  public String getName()
+  {
+    return name;
+  }
+
+  /**
+   * Gets the modifiers this field uses.  Use the <code>Modifier</code>
+   * class to interpret the values.  A field can only have a subset of the
+   * following modifiers: public, private, protected, static, final,
+   * transient, and volatile.
+   *
+   * @return an integer representing the modifiers to this Member
+   * @see Modifier
+   */
+  public native int getModifiers();
+
+  /**
+   * Gets the type of this field.
+   * @return the type of this field
+   */
+  public native Class getType();
+
+  /**
+   * 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 creat 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 (this.getDeclaringClass() != that.getDeclaringClass())
+      return false;
+    if (!this.getName().equals(that.getName()))
+      return false;
+    if (this.getType() != that.getType())
+      return false;
+    return true;
+  }
+
+  /**
+   * Get the hash code for the Field. The Field hash code is the hash code
+   * of its name XOR'd with the hash code of its class name.
+   *
+   * @return the hash code for the object.
+   */
+  public int hashCode()
+  {
+    return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
+  }
+
+  /**
+   * Get a String representation of the Field. A Field's String
+   * representation is "&lt;modifiers&gt; &lt;type&gt;
+   * &lt;class&gt;.&lt;fieldname&gt;".<br> Example:
+   * <code>public transient boolean gnu.parse.Parser.parseComplete</code>
+   *
+   * @return the String representation of the Field
+   */
+  public String toString()
+  {
+    // 64 is a reasonable buffer initial size for field
+    StringBuffer sb = new StringBuffer(64);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    sb.append(getType().getName()).append(' ');
+    sb.append(getDeclaringClass().getName()).append('.');
+    sb.append(getName());
+    return sb.toString();
+  }
+  /**
+   * 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)
+   */
+  public 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)
+   */
+  public 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)
+   */
+  public 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.
+   *
+   * @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)
+   */
+  public 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)
+   */
+  public 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)
+   */
+  public 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)
+   */
+  public 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)
+   */
+  public 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)
+   */
+  public 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)
+   */
+  public 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)
+   */
+  public 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)
+   */
+  public 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)
+   */
+  public 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)
+   */
+  public 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)
+   */
+  public 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)
+   */
+  public 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)
+   */
+  public 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)
+   */
+  public native void setDouble(Object o, double value)
+    throws IllegalAccessException;
+}
diff --git a/libjava/classpath/vm/reference/java/lang/reflect/Method.java b/libjava/classpath/vm/reference/java/lang/reflect/Method.java
new file mode 100644 (file)
index 0000000..f289e77
--- /dev/null
@@ -0,0 +1,339 @@
+/* java.lang.reflect.Method - reflection of Java methods
+   Copyright (C) 1998, 2001, 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.reflect;
+
+import java.util.Arrays;
+
+/**
+ * The Method class represents a member method of a class. It also allows
+ * dynamic invocation, via reflection. This works for both static and
+ * instance methods. Invocation on Method objects knows how to do
+ * widening conversions, but throws {@link IllegalArgumentException} if
+ * a narrowing conversion would be necessary. You can query for information
+ * on this Method regardless of location, but invocation access may be limited
+ * by Java language access controls. If you can't do it in the compiler, you
+ * can't normally do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type.  They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc.  These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class.  It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getMethod(String,Object[])
+ * @see java.lang.Class#getDeclaredMethod(String,Object[])
+ * @see java.lang.Class#getMethods()
+ * @see java.lang.Class#getDeclaredMethods()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Method
+extends AccessibleObject implements Member
+{
+  Class declaringClass;
+  String name;
+  int slot;
+
+  /**
+   * This class is uninstantiable.
+   */
+  private Method(Class declaringClass, String name, int slot)
+  {
+    this.declaringClass = declaringClass;
+    this.name = name;
+    this.slot = slot;
+  }
+
+  /**
+   * Gets the class that declared this method, or the class where this method
+   * is a non-inherited member.
+   * @return the class that declared this member
+   */
+  public Class getDeclaringClass()
+  {
+    return declaringClass;
+  }
+
+  /**
+   * Gets the name of this method.
+   * @return the name of this method
+   */
+  public String getName()
+  {
+    return name;
+  }
+
+  /**
+   * Gets the modifiers this method uses.  Use the <code>Modifier</code>
+   * class to interpret the values.  A method can only have a subset of the
+   * following modifiers: public, private, protected, abstract, static,
+   * final, synchronized, native, and strictfp.
+   *
+   * @return an integer representing the modifiers to this Member
+   * @see Modifier
+   */
+  public native int getModifiers();
+
+  /**
+   * Gets the return type of this method.
+   * @return the type of this method
+   */
+  public 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
+   */
+  public 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
+   */
+  public native Class[] getExceptionTypes();
+
+  /**
+   * 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 (this.getDeclaringClass() != that.getDeclaringClass())
+      return false;
+    if (!this.getName().equals(that.getName()))
+      return false;
+    if (this.getReturnType() != that.getReturnType())
+      return false;
+    if (!Arrays.equals(this.getParameterTypes(), that.getParameterTypes()))
+      return false;
+    return true;
+  }
+
+  /**
+   * Get the hash code for the Method. The Method hash code is the hash code
+   * of its name XOR'd with the hash code of its class name.
+   *
+   * @return the hash code for the object
+   */
+  public int hashCode()
+  {
+    return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
+  }
+
+  /**
+   * Get a String representation of the Method. A Method's String
+   * representation is "&lt;modifiers&gt; &lt;returntype&gt;
+   * &lt;methodname&gt;(&lt;paramtypes&gt;) throws &lt;exceptions&gt;", where
+   * everything after ')' is omitted if there are no exceptions.<br> Example:
+   * <code>public static int run(java.lang.Runnable,int)</code>
+   *
+   * @return the String representation of the Method
+   */
+  public String toString()
+  {
+    // 128 is a reasonable buffer initial size for constructor
+    StringBuffer sb = new StringBuffer(128);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    sb.append(getUserTypeName(getReturnType().getName())).append(' ');
+    sb.append(getDeclaringClass().getName()).append('.');
+    sb.append(getName()).append('(');
+    Class[] c = getParameterTypes();
+    if (c.length > 0)
+      {
+        sb.append(getUserTypeName(c[0].getName()));
+        for (int i = 1; i < c.length; i++)
+          sb.append(',').append(getUserTypeName(c[i].getName()));
+      }
+    sb.append(')');
+    c = getExceptionTypes();
+    if (c.length > 0)
+      {
+        sb.append(" throws ").append(c[0].getName());
+        for (int i = 1; i < c.length; i++)
+          sb.append(',').append(c[i].getName());
+      }
+    return sb.toString();
+  }
+
+  private static String getUserTypeName(String typeSpec)
+  {
+    int pos = 0;
+    String typeName = "";
+    String arrayPart = "";
+
+    while (typeSpec.charAt(pos) == '[')
+      {
+       arrayPart += "[]";
+       ++pos;
+      }
+
+    switch (typeSpec.charAt(pos))
+      {
+      case 'Z':
+       typeName = "boolean";
+       break;
+      case 'B':
+       typeName = "byte";
+       break;
+      case 'C':
+       typeName = "char";
+       break;
+      case 'D':
+       typeName = "double";
+       break;
+      case 'F':
+       typeName = "float";
+       break;
+      case 'I':
+       typeName = "int";
+       break;
+      case 'J':
+       typeName = "long";
+       break;
+      case 'S':
+       typeName = "short";
+       break;
+      case 'L':
+       typeName = typeSpec.substring(pos + 1, typeSpec.length() - 1);
+       break;
+      default:
+       typeName = typeSpec;
+       break;
+      }
+
+    return typeName + arrayPart;
+  }
+
+  /**
+   * Invoke the method. Arguments are automatically unwrapped and widened,
+   * and the result is automatically wrapped, if needed.<p>
+   *
+   * If the method is static, <code>o</code> will be ignored. Otherwise,
+   * the method uses dynamic lookup as described in JLS 15.12.4.4. You cannot
+   * mimic the behavior of nonvirtual lookup (as in super.foo()). This means
+   * you will get a <code>NullPointerException</code> if <code>o</code> is
+   * null, and an <code>IllegalArgumentException</code> if it is incompatible
+   * with the declaring class of the method. If the method takes 0 arguments,
+   * you may use null or a 0-length array for <code>args</code>.<p>
+   *
+   * Next, if this Method enforces access control, your runtime context is
+   * evaluated, and you may have an <code>IllegalAccessException</code> if
+   * you could not acces this method in similar compiled code. If the method
+   * is static, and its class is uninitialized, you trigger class
+   * initialization, which may end in a
+   * <code>ExceptionInInitializerError</code>.<p>
+   *
+   * Finally, the method is invoked. If it completes normally, the return value
+   * will be null for a void method, a wrapped object for a primitive return
+   * method, or the actual return of an Object method. If it completes
+   * abruptly, the exception is wrapped in an
+   * <code>InvocationTargetException</code>.
+   *
+   * @param o the object to invoke the method on
+   * @param args the arguments to the method
+   * @return the return value of the method, wrapped in the appropriate
+   *         wrapper if it is primitive
+   * @throws IllegalAccessException if the method could not normally be called
+   *         by the Java code (i.e. it is not public)
+   * @throws IllegalArgumentException if the number of arguments is incorrect;
+   *         if the arguments types are wrong even with a widening conversion;
+   *         or if <code>o</code> is not an instance of the class or interface
+   *         declaring this method
+   * @throws InvocationTargetException if the method throws an exception
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static method triggered
+   *         class initialization, which then failed
+   */
+  public Object invoke(Object o, Object[] args)
+    throws IllegalAccessException, InvocationTargetException
+  {
+    return invokeNative(o, args, declaringClass, slot);
+  }
+
+  /*
+   * NATIVE HELPERS
+   */
+
+  private native Object invokeNative(Object o, Object[] args,
+                                     Class declaringClass, int slot)
+    throws IllegalAccessException, InvocationTargetException;
+}
diff --git a/libjava/classpath/vm/reference/java/net/VMInetAddress.java b/libjava/classpath/vm/reference/java/net/VMInetAddress.java
new file mode 100644 (file)
index 0000000..1253ded
--- /dev/null
@@ -0,0 +1,93 @@
+/* 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.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.StringTokenizer;
+
+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;
+}
diff --git a/libjava/classpath/vm/reference/java/net/VMNetworkInterface.java b/libjava/classpath/vm/reference/java/net/VMNetworkInterface.java
new file mode 100644 (file)
index 0000000..af71ce2
--- /dev/null
@@ -0,0 +1,66 @@
+/* VMNetworkInterface.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.net;
+
+import gnu.classpath.Configuration;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * 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
+{
+  static
+    {
+      if (Configuration.INIT_LOAD_LIBRARY)
+       System.loadLibrary("javanet");
+    }
+
+  public static native Vector getInterfaces()
+    throws SocketException;
+}
diff --git a/libjava/classpath/vm/reference/java/nio/VMDirectByteBuffer.java b/libjava/classpath/vm/reference/java/nio/VMDirectByteBuffer.java
new file mode 100644 (file)
index 0000000..e42f503
--- /dev/null
@@ -0,0 +1,66 @@
+/* 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.RawData;
+
+final class VMDirectByteBuffer
+{
+  static
+  {
+    // load the shared library needed for native methods.
+    if (Configuration.INIT_LOAD_LIBRARY)
+      {
+        System.loadLibrary("javanio");
+      }
+
+    init();
+  }
+
+  private static native void init();
+  
+  static native RawData allocate (int capacity);
+  static native void free(RawData address);
+  static native byte get(RawData address, int index);
+  static native void get(RawData address, int index, byte[] dst, int offset, int length);
+  static native void put(RawData address, int index, byte value);
+  static native RawData adjustAddress(RawData address, int offset);
+  static native void shiftDown(RawData 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 (file)
index 0000000..e58d7fb
--- /dev/null
@@ -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.channels.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 (file)
index 0000000..7058a5e
--- /dev/null
@@ -0,0 +1,260 @@
+/* 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 = false;
+  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)
+      {
+        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);
+      }
+  }
+
+  /**
+   * 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);
+            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.
+            LinkedList l = (LinkedList) contexts.get();
+            if (l != null)
+              context = (AccessControlContext) l.getFirst();
+            privileged = 1;
+          }
+
+        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()]);
+
+    // Intersect the derived protection domain with the context supplied
+    // to doPrivileged.
+    if (context != null)
+      context = new AccessControlContext(result, context,
+                                         IntersectingDomainCombiner.SINGLETON);
+    // 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/util/VMTimeZone.java b/libjava/classpath/vm/reference/java/util/VMTimeZone.java
new file mode 100644 (file)
index 0000000..86b6258
--- /dev/null
@@ -0,0 +1,345 @@
+/* java.util.VMTimeZone
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 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.util;
+
+import gnu.classpath.Configuration;
+
+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>readtzFile("/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)
+      {
+       tzid = readtzFile("/etc/localtime");
+       if (tzid != null && !tzid.equals(""))
+         zone = TimeZone.getDefaultTimeZone(tzid);
+      }
+
+    // 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 a file as a "standard" tzfile and return a time
+   * zone id string as expected by <code>getDefaultTimeZone(String)</code>.
+   * If the file doesn't exist, an IOException occurs or it isn't a tzfile
+   * that can be parsed null is returned.
+   * <p>
+   * The tzfile structure (as also used by glibc) is described in the Olson
+   * tz database archive as can be found at
+   * <code>ftp://elsie.nci.nih.gov/pub/</code>.
+   * <p>
+   * At least the following platforms support the tzdata file format
+   * and /etc/localtime (GNU/Linux, Darwin, Solaris and FreeBSD at
+   * least). Some systems (like Darwin) don't start the file with the
+   * required magic bytes 'TZif', this implementation can handle
+   * that).
+   */
+  private static String readtzFile(String file)
+  {
+    File f = new File(file);
+    if (!f.exists())
+      return null;
+    
+    DataInputStream dis = null;
+    try
+      {
+        FileInputStream fis = new FileInputStream(f);
+        BufferedInputStream bis = new BufferedInputStream(fis);
+        dis = new DataInputStream(bis);
+       
+        // Make sure we are reading a tzfile.
+        byte[] tzif = new byte[4];
+        dis.readFully(tzif);
+        if (tzif[0] == 'T' && tzif[1] == 'Z'
+            && tzif[2] == 'i' && tzif[3] == 'f')
+         // Reserved bytes, ttisgmtcnt, ttisstdcnt and leapcnt
+         skipFully(dis, 16 + 3 * 4);
+       else
+         // Darwin has tzdata files that don't start with the TZif marker
+         skipFully(dis, 16 + 3 * 4 - 4);
+       
+       int timecnt = dis.readInt();
+       int typecnt = dis.readInt();
+       if (typecnt > 0)
+         {
+           int charcnt = dis.readInt();
+           // Transition times plus indexed transition times.
+           skipFully(dis, timecnt * (4 + 1));
+           
+           // Get last gmt_offset and dst/non-dst time zone names.
+           int abbrind = -1;
+           int dst_abbrind = -1;
+           int gmt_offset = 0;
+           while (typecnt-- > 0)
+             {
+               // gmtoff
+               int offset = dis.readInt();
+               int dst = dis.readByte();
+               if (dst == 0)
+                 {
+                   abbrind = dis.readByte();
+                   gmt_offset = offset;
+                 }
+               else
+                 dst_abbrind = dis.readByte();
+             }
+           
+           // gmt_offset is the offset you must add to UTC/GMT to
+           // get the local time, we need the offset to add to
+           // the local time to get UTC/GMT.
+           gmt_offset *= -1;
+           
+           // Turn into hours if possible.
+           if (gmt_offset % 3600 == 0)
+             gmt_offset /= 3600;
+           
+           if (abbrind >= 0)
+             {
+               byte[] names = new byte[charcnt];
+               dis.readFully(names);
+               int j = abbrind;
+               while (j < charcnt && names[j] != 0)
+                 j++;
+               
+               String zonename = new String(names, abbrind, j - abbrind,
+                                            "ASCII");
+               
+               String dst_zonename;
+               if (dst_abbrind >= 0)
+                 {
+                   j = dst_abbrind;
+                   while (j < charcnt && names[j] != 0)
+                     j++;
+                   dst_zonename = new String(names, dst_abbrind,
+                                             j - dst_abbrind, "ASCII");
+                 }
+               else
+                 dst_zonename = "";
+               
+               // Only use gmt offset when necessary.
+               // Also special case GMT+/- timezones.
+               String offset_string;
+               if ("".equals(dst_zonename)
+                   && (gmt_offset == 0
+                       || zonename.startsWith("GMT+")
+                       || zonename.startsWith("GMT-")))
+                 offset_string = "";
+               else
+                 offset_string = Integer.toString(gmt_offset);
+               
+               String id = zonename + offset_string + dst_zonename;
+               
+               return id;
+             }
+         }
+       
+       // Something didn't match while reading the file.
+       return null;
+      }
+    catch (IOException ioe)
+      {
+       // Parse error, not a proper tzfile.
+       return null;
+      }
+    finally
+      {
+       try
+         {
+           if (dis != null)
+             dis.close();
+         }
+       catch(IOException ioe)
+         {
+           // Error while close, nothing we can do.
+         }
+      }
+  }
+  
+  /**
+   * Skips the requested number of bytes in the given InputStream.
+   * Throws EOFException if not enough bytes could be skipped.
+   * Negative numbers of bytes to skip are ignored.
+   */
+  private static void skipFully(InputStream is, long l) throws IOException
+  {
+    while (l > 0)
+      {
+        long k = is.skip(l);
+        if (k <= 0)
+          throw new EOFException();
+        l -= k;
+      }
+  }
+
+  /**
+   * Tries to get the system time zone id through native code.
+   */
+  private static native String getSystemTimeZoneId();
+}