[llvm-commits] [llvm-gcc-4.2] r43913 [71/80] - in /llvm-gcc-4.2/trunk: boehm-gc/ boehm-gc/Mac_files/ boehm-gc/cord/ boehm-gc/doc/ boehm-gc/include/ boehm-gc/include/private/ boehm-gc/tests/ libffi/ libffi/include/ libffi/src/ libffi/src/alpha/ libffi/src/arm/ libffi/src/cris/ libffi/src/frv/ libffi/src/ia64/ libffi/src/m32r/ libffi/src/m68k/ libffi/src/mips/ libffi/src/pa/ libffi/src/powerpc/ libffi/src/s390/ libffi/src/sh/ libffi/src/sh64/ libffi/src/sparc/ libffi/src/x86/ libffi/testsuite/ libffi/testsuite/config/ li...

Bill Wendling isanbard at gmail.com
Thu Nov 8 14:57:11 PST 2007


Added: llvm-gcc-4.2/trunk/libjava/java/lang/SecurityManager.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/SecurityManager.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/SecurityManager.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/SecurityManager.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1057 @@
+/* SecurityManager.java -- security checks for privileged actions
+   Copyright (C) 1998, 1999, 2001, 2002, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang;
+
+import java.awt.AWTPermission;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FilePermission;
+import java.lang.reflect.Member;
+import java.net.InetAddress;
+import java.net.SocketPermission;
+import java.security.AccessController;
+import java.security.AccessControlContext;
+import java.security.AllPermission;
+import java.security.Permission;
+import java.security.PrivilegedAction;
+import java.security.Security;
+import java.security.SecurityPermission;
+import java.util.PropertyPermission;
+import java.util.StringTokenizer;
+
+/**
+ * SecurityManager is a class you can extend to create your own Java
+ * security policy.  By default, there is no SecurityManager installed in
+ * 1.1, which means that all things are permitted to all people. The security
+ * manager, if set, is consulted before doing anything with potentially
+ * dangerous results, and throws a <code>SecurityException</code> if the
+ * action is forbidden.
+ *
+ * <p>A typical check is as follows, just before the dangerous operation:<br>
+ * <pre>
+ * SecurityManager sm = System.getSecurityManager();
+ * if (sm != null)
+ *   sm.checkABC(<em>argument</em>, ...);
+ * </pre>
+ * Note that this is thread-safe, by caching the security manager in a local
+ * variable rather than risking a NullPointerException if the mangager is
+ * changed between the check for null and before the permission check.
+ *
+ * <p>The special method <code>checkPermission</code> is a catchall, and
+ * the default implementation calls
+ * <code>AccessController.checkPermission</code>. In fact, all the other
+ * methods default to calling checkPermission.
+ *
+ * <p>Sometimes, the security check needs to happen from a different context,
+ * such as when called from a worker thread. In such cases, use
+ * <code>getSecurityContext</code> to take a snapshot that can be passed
+ * to the worker thread:<br>
+ * <pre>
+ * Object context = null;
+ * SecurityManager sm = System.getSecurityManager();
+ * if (sm != null)
+ *   context = sm.getSecurityContext(); // defaults to an AccessControlContext
+ * // now, in worker thread
+ * if (sm != null)
+ *   sm.checkPermission(permission, context);
+ * </pre>
+ *
+ * <p>Permissions fall into these categories: File, Socket, Net, Security,
+ * Runtime, Property, AWT, Reflect, and Serializable. Each of these
+ * permissions have a property naming convention, that follows a hierarchical
+ * naming convention, to make it easy to grant or deny several permissions
+ * at once. Some permissions also take a list of permitted actions, such
+ * as "read" or "write", to fine-tune control even more. The permission
+ * <code>java.security.AllPermission</code> grants all permissions.
+ *
+ * <p>The default methods in this class deny all things to all people. You
+ * must explicitly grant permission for anything you want to be legal when
+ * subclassing this class.
+ *
+ * @author John Keiser
+ * @author Eric Blake (ebb9 at email.byu.edu)
+ * @see ClassLoader
+ * @see SecurityException
+ * @see #checkTopLevelWindow(Object)
+ * @see System#getSecurityManager()
+ * @see System#setSecurityManager(SecurityManager)
+ * @see AccessController
+ * @see AccessControlContext
+ * @see AccessControlException
+ * @see Permission
+ * @see BasicPermission
+ * @see java.io.FilePermission
+ * @see java.net.SocketPermission
+ * @see java.util.PropertyPermission
+ * @see RuntimePermission
+ * @see java.awt.AWTPermission
+ * @see Policy
+ * @see SecurityPermission
+ * @see ProtectionDomain
+ * @since 1.0
+ * @status still missing 1.4 functionality
+ */
+public class SecurityManager
+{
+  /**
+   * The current security manager. This is located here instead of in
+   * System, to avoid security problems, as well as bootstrap issues.
+   * Make sure to access it in a thread-safe manner; it is package visible
+   * to avoid overhead in java.lang.
+   */
+  static volatile SecurityManager current;
+
+  /**
+   * Tells whether or not the SecurityManager is currently performing a
+   * security check.
+   * @deprecated Use {@link #checkPermission(Permission)} instead.
+   */
+  protected boolean inCheck;
+
+  /**
+   * Construct a new security manager. There may be a security check, of
+   * <code>RuntimePermission("createSecurityManager")</code>.
+   *
+   * @throws SecurityException if permission is denied
+   */
+  public SecurityManager()
+  {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      sm.checkPermission(new RuntimePermission("createSecurityManager"));
+  }
+
+  /**
+   * Tells whether or not the SecurityManager is currently performing a
+   * security check.
+   *
+   * @return true if the SecurityManager is in a security check
+   * @see #inCheck
+   * @deprecated use {@link #checkPermission(Permission)} instead
+   */
+  public boolean getInCheck()
+  {
+    return inCheck;
+  }
+
+  /**
+   * Get a list of all the classes currently executing methods on the Java
+   * stack.  getClassContext()[0] is the currently executing method (ie. the
+   * class that CALLED getClassContext, not SecurityManager).
+   *
+   * @return an array of classes on the Java execution stack
+   */
+  protected Class[] getClassContext()
+  {
+    return VMSecurityManager.getClassContext(SecurityManager.class);
+  }
+
+  /**
+   * Find the ClassLoader of the first non-system class on the execution
+   * stack. A non-system class is one whose ClassLoader is not equal to
+   * {@link ClassLoader#getSystemClassLoader()} or its ancestors. This
+   * will return null in three cases:
+   *
+   * <ul>
+   * <li>All methods on the stack are from system classes</li>
+   * <li>All methods on the stack up to the first "privileged" caller, as
+   *  created by {@link AccessController#doPrivileged(PrivilegedAction)},
+   *  are from system classes</li>
+   * <li>A check of <code>java.security.AllPermission</code> succeeds.</li>
+   * </ul>
+   * 
+   * @return the most recent non-system ClassLoader on the execution stack
+   * @deprecated use {@link #checkPermission(Permission)} instead
+   */
+  protected ClassLoader currentClassLoader()
+  {
+    return VMSecurityManager.currentClassLoader(SecurityManager.class);
+  }
+
+  /**
+   * Find the first non-system class on the execution stack. A non-system
+   * class is one whose ClassLoader is not equal to
+   * {@link ClassLoader#getSystemClassLoader()} or its ancestors. This
+   * will return null in three cases:
+   *
+   * <ul>
+   * <li>All methods on the stack are from system classes</li>
+   * <li>All methods on the stack up to the first "privileged" caller, as
+   *  created by {@link AccessController#doPrivileged(PrivilegedAction)},
+   *  are from system classes</li>
+   * <li>A check of <code>java.security.AllPermission</code> succeeds.</li>
+   * </ul>
+   * 
+   * @return the most recent non-system Class on the execution stack
+   * @deprecated use {@link #checkPermission(Permission)} instead
+   */
+  protected Class currentLoadedClass()
+  {
+    int i = classLoaderDepth();
+    return i >= 0 ? getClassContext()[i] : null;
+  }
+
+  /**
+   * Get the depth of a particular class on the execution stack.
+   *
+   * @param className the fully-qualified name to search for
+   * @return the index of the class on the stack, or -1
+   * @deprecated use {@link #checkPermission(Permission)} instead
+   */
+  protected int classDepth(String className)
+  {
+    Class[] c = getClassContext();
+    for (int i = 0; i < c.length; i++)
+      if (className.equals(c[i].getName()))
+        return i;
+    return -1;
+  }
+
+  /**
+   * Get the depth on the execution stack of the most recent non-system class.
+   * A non-system class is one whose ClassLoader is not equal to
+   * {@link ClassLoader#getSystemClassLoader()} or its ancestors. This
+   * will return -1 in three cases:
+   *
+   * <ul>
+   * <li>All methods on the stack are from system classes</li>
+   * <li>All methods on the stack up to the first "privileged" caller, as
+   *  created by {@link AccessController#doPrivileged(PrivilegedAction)},
+   *  are from system classes</li>
+   * <li>A check of <code>java.security.AllPermission</code> succeeds.</li>
+   * </ul>
+   * 
+   * @return the index of the most recent non-system Class on the stack
+   * @deprecated use {@link #checkPermission(Permission)} instead
+   */
+  protected int classLoaderDepth()
+  {
+    try
+      {
+        checkPermission(new AllPermission());
+      }
+    catch (SecurityException e)
+      {
+        Class[] c = getClassContext();
+        for (int i = 0; i < c.length; i++)
+          if (c[i].getClassLoader() != null)
+            // XXX Check if c[i] is AccessController, or a system class.
+            return i;
+      }
+    return -1;
+  }
+
+  /**
+   * Tell whether the specified class is on the execution stack.
+   *
+   * @param className the fully-qualified name of the class to find
+   * @return whether the specified class is on the execution stack
+   * @deprecated use {@link #checkPermission(Permission)} instead
+   */
+  protected boolean inClass(String className)
+  {
+    return classDepth(className) != -1;
+  }
+
+  /**
+   * Tell whether there is a class loaded with an explicit ClassLoader on
+   * the stack.
+   *
+   * @return whether a class with an explicit ClassLoader is on the stack
+   * @deprecated use {@link #checkPermission(Permission)} instead
+   */
+  protected boolean inClassLoader()
+  {
+    return classLoaderDepth() != -1;
+  }
+
+  /**
+   * Get an implementation-dependent Object that contains enough information
+   * about the current environment to be able to perform standard security
+   * checks later.  This is used by trusted methods that need to verify that
+   * their callers have sufficient access to perform certain operations.
+   *
+   * <p>Currently the only methods that use this are checkRead() and
+   * checkConnect(). The default implementation returns an
+   * <code>AccessControlContext</code>.
+   *
+   * @return a security context
+   * @see #checkConnect(String, int, Object)
+   * @see #checkRead(String, Object)
+   * @see AccessControlContext
+   * @see AccessController#getContext()
+   */
+  public Object getSecurityContext()
+  {
+    return AccessController.getContext();
+  }
+
+  /**
+   * Check if the current thread is allowed to perform an operation that
+   * requires the specified <code>Permission</code>. This defaults to
+   * <code>AccessController.checkPermission</code>.
+   *
+   * @param perm the <code>Permission</code> required
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if perm is null
+   * @since 1.2
+   */
+  public void checkPermission(Permission perm)
+  {
+    AccessController.checkPermission(perm);
+  }
+
+  /**
+   * Check if the current thread is allowed to perform an operation that
+   * requires the specified <code>Permission</code>. This is done in a
+   * context previously returned by <code>getSecurityContext()</code>. The
+   * default implementation expects context to be an AccessControlContext,
+   * and it calls <code>AccessControlContext.checkPermission(perm)</code>.
+   *
+   * @param perm the <code>Permission</code> required
+   * @param context a security context
+   * @throws SecurityException if permission is denied, or if context is
+   *         not an AccessControlContext
+   * @throws NullPointerException if perm is null
+   * @see #getSecurityContext()
+   * @see AccessControlContext#checkPermission(Permission)
+   * @since 1.2
+   */
+  public void checkPermission(Permission perm, Object context)
+  {
+    if (! (context instanceof AccessControlContext))
+      throw new SecurityException("Missing context");
+    ((AccessControlContext) context).checkPermission(perm);
+  }
+
+  /**
+   * Check if the current thread is allowed to create a ClassLoader. This
+   * method is called from ClassLoader.ClassLoader(), and checks
+   * <code>RuntimePermission("createClassLoader")</code>. If you override
+   * this, you should call <code>super.checkCreateClassLoader()</code> rather
+   * than throwing an exception.
+   *
+   * @throws SecurityException if permission is denied
+   * @see ClassLoader#ClassLoader()
+   */
+  public void checkCreateClassLoader()
+  {
+    checkPermission(new RuntimePermission("createClassLoader"));
+  }
+
+  /**
+   * Check if the current thread is allowed to modify another Thread. This is
+   * called by Thread.stop(), suspend(), resume(), interrupt(), destroy(),
+   * setPriority(), setName(), and setDaemon(). The default implementation
+   * checks <code>RuntimePermission("modifyThread")</code> on system threads
+   * (ie. threads in ThreadGroup with a null parent), and returns silently on
+   * other threads.
+   *
+   * <p>If you override this, you must do two things. First, call
+   * <code>super.checkAccess(t)</code>, to make sure you are not relaxing
+   * requirements. Second, if the calling thread has
+   * <code>RuntimePermission("modifyThread")</code>, return silently, so that
+   * core classes (the Classpath library!) can modify any thread.
+   *
+   * @param thread the other Thread to check
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if thread is null
+   * @see Thread#stop()
+   * @see Thread#suspend()
+   * @see Thread#resume()
+   * @see Thread#setPriority(int)
+   * @see Thread#setName(String)
+   * @see Thread#setDaemon(boolean)
+   */
+  public void checkAccess(Thread thread)
+  {
+    if (thread.getThreadGroup() != null 
+	&& thread.getThreadGroup().getParent() == null)
+      checkPermission(new RuntimePermission("modifyThread"));
+  }
+
+  /**
+   * Check if the current thread is allowed to modify a ThreadGroup. This is
+   * called by Thread.Thread() (to add a thread to the ThreadGroup),
+   * ThreadGroup.ThreadGroup() (to add this ThreadGroup to a parent),
+   * ThreadGroup.stop(), suspend(), resume(), interrupt(), destroy(),
+   * setDaemon(), and setMaxPriority(). The default implementation
+   * checks <code>RuntimePermission("modifyThread")</code> on the system group
+   * (ie. the one with a null parent), and returns silently on other groups.
+   *
+   * <p>If you override this, you must do two things. First, call
+   * <code>super.checkAccess(t)</code>, to make sure you are not relaxing
+   * requirements. Second, if the calling thread has
+   * <code>RuntimePermission("modifyThreadGroup")</code>, return silently,
+   * so that core classes (the Classpath library!) can modify any thread.
+   *
+   * @param g the ThreadGroup to check
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if g is null
+   * @see Thread#Thread()
+   * @see ThreadGroup#ThreadGroup(String)
+   * @see ThreadGroup#stop()
+   * @see ThreadGroup#suspend()
+   * @see ThreadGroup#resume()
+   * @see ThreadGroup#interrupt()
+   * @see ThreadGroup#setDaemon(boolean)
+   * @see ThreadGroup#setMaxPriority(int)
+   */
+  public void checkAccess(ThreadGroup g)
+  {
+    if (g.getParent() == null)
+      checkPermission(new RuntimePermission("modifyThreadGroup"));
+  }
+
+  /**
+   * Check if the current thread is allowed to exit the JVM with the given
+   * status. This method is called from Runtime.exit() and Runtime.halt().
+   * The default implementation checks
+   * <code>RuntimePermission("exitVM")</code>. If you override this, call
+   * <code>super.checkExit</code> rather than throwing an exception.
+   *
+   * @param status the status to exit with
+   * @throws SecurityException if permission is denied
+   * @see Runtime#exit(int)
+   * @see Runtime#halt(int)
+   */
+  public void checkExit(int status)
+  {
+    checkPermission(new RuntimePermission("exitVM"));
+  }
+
+  /**
+   * Check if the current thread is allowed to execute the given program. This
+   * method is called from Runtime.exec(). If the name is an absolute path,
+   * the default implementation checks
+   * <code>FilePermission(program, "execute")</code>, otherwise it checks
+   * <code>FilePermission("<<ALL FILES>>", "execute")</code>. If
+   * you override this, call <code>super.checkExec</code> rather than
+   * throwing an exception.
+   *
+   * @param program the name of the program to exec
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if program is null
+   * @see Runtime#exec(String[], String[], File)
+   */
+  public void checkExec(String program)
+  {
+    if (! program.equals(new File(program).getAbsolutePath()))
+      program = "<<ALL FILES>>";
+    checkPermission(new FilePermission(program, "execute"));
+  }
+
+  /**
+   * Check if the current thread is allowed to link in the given native
+   * library. This method is called from Runtime.load() (and hence, by
+   * loadLibrary() as well). The default implementation checks
+   * <code>RuntimePermission("loadLibrary." + filename)</code>. If you
+   * override this, call <code>super.checkLink</code> rather than throwing
+   * an exception.
+   *
+   * @param filename the full name of the library to load
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if filename is null
+   * @see Runtime#load(String)
+   */
+  public void checkLink(String filename)
+  {
+    // Use the toString() hack to do the null check.
+    checkPermission(new RuntimePermission("loadLibrary."
+                                          + filename.toString()));
+  }
+
+  /**
+   * Check if the current thread is allowed to read the given file using the
+   * FileDescriptor. This method is called from
+   * FileInputStream.FileInputStream(). The default implementation checks
+   * <code>RuntimePermission("readFileDescriptor")</code>. If you override
+   * this, call <code>super.checkRead</code> rather than throwing an
+   * exception.
+   *
+   * @param desc the FileDescriptor representing the file to access
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if desc is null
+   * @see FileInputStream#FileInputStream(FileDescriptor)
+   */
+  public void checkRead(FileDescriptor desc)
+  {
+    if (desc == null)
+      throw new NullPointerException();
+    checkPermission(new RuntimePermission("readFileDescriptor"));
+  }
+
+  /**
+   * Check if the current thread is allowed to read the given file. This
+   * method is called from FileInputStream.FileInputStream(),
+   * RandomAccessFile.RandomAccessFile(), File.exists(), canRead(), isFile(),
+   * isDirectory(), lastModified(), length() and list(). The default
+   * implementation checks <code>FilePermission(filename, "read")</code>. If
+   * you override this, call <code>super.checkRead</code> rather than
+   * throwing an exception.
+   *
+   * @param filename the full name of the file to access
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if filename is null
+   * @see File
+   * @see FileInputStream#FileInputStream(String)
+   * @see RandomAccessFile#RandomAccessFile(String, String)
+   */
+  public void checkRead(String filename)
+  {
+    checkPermission(new FilePermission(filename, "read"));
+  }
+
+  /**
+   * Check if the current thread is allowed to read the given file. using the
+   * given security context. The context must be a result of a previous call
+   * to <code>getSecurityContext()</code>. The default implementation checks
+   * <code>AccessControlContext.checkPermission(new FilePermission(filename,
+   * "read"))</code>. If you override this, call <code>super.checkRead</code>
+   * rather than throwing an exception.
+   *
+   * @param filename the full name of the file to access
+   * @param context the context to determine access for
+   * @throws SecurityException if permission is denied, or if context is
+   *         not an AccessControlContext
+   * @throws NullPointerException if filename is null
+   * @see #getSecurityContext()
+   * @see AccessControlContext#checkPermission(Permission)
+   */
+  public void checkRead(String filename, Object context)
+  {
+    if (! (context instanceof AccessControlContext))
+      throw new SecurityException("Missing context");
+    AccessControlContext ac = (AccessControlContext) context;
+    ac.checkPermission(new FilePermission(filename, "read"));
+  }
+
+  /**
+   * Check if the current thread is allowed to write the given file using the
+   * FileDescriptor. This method is called from
+   * FileOutputStream.FileOutputStream(). The default implementation checks
+   * <code>RuntimePermission("writeFileDescriptor")</code>. If you override
+   * this, call <code>super.checkWrite</code> rather than throwing an
+   * exception.
+   *
+   * @param desc the FileDescriptor representing the file to access
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if desc is null
+   * @see FileOutputStream#FileOutputStream(FileDescriptor)
+   */
+  public void checkWrite(FileDescriptor desc)
+  {
+    if (desc == null)
+      throw new NullPointerException();
+    checkPermission(new RuntimePermission("writeFileDescriptor"));
+  }
+
+  /**
+   * Check if the current thread is allowed to write the given file. This
+   * method is called from FileOutputStream.FileOutputStream(),
+   * RandomAccessFile.RandomAccessFile(), File.canWrite(), mkdir(), and
+   * renameTo(). The default implementation checks
+   * <code>FilePermission(filename, "write")</code>. If you override this,
+   * call <code>super.checkWrite</code> rather than throwing an exception.
+   *
+   * @param filename the full name of the file to access
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if filename is null
+   * @see File
+   * @see File#canWrite()
+   * @see File#mkdir()
+   * @see File#renameTo(File)
+   * @see FileOutputStream#FileOutputStream(String)
+   * @see RandomAccessFile#RandomAccessFile(String, String)
+   */
+  public void checkWrite(String filename)
+  {
+    checkPermission(new FilePermission(filename, "write"));
+  }
+
+  /**
+   * Check if the current thread is allowed to delete the given file. This
+   * method is called from File.delete(). The default implementation checks
+   * <code>FilePermission(filename, "delete")</code>. If you override this,
+   * call <code>super.checkDelete</code> rather than throwing an exception.
+   *
+   * @param filename the full name of the file to delete
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if filename is null
+   * @see File#delete()
+   */
+  public void checkDelete(String filename)
+  {
+    checkPermission(new FilePermission(filename, "delete"));
+  }
+
+  /**
+   * Check if the current thread is allowed to connect to a given host on a
+   * given port. This method is called from Socket.Socket(). A port number
+   * of -1 indicates the caller is attempting to determine an IP address, so
+   * the default implementation checks
+   * <code>SocketPermission(host, "resolve")</code>. Otherwise, the default
+   * implementation checks
+   * <code>SocketPermission(host + ":" + port, "connect")</code>. If you
+   * override this, call <code>super.checkConnect</code> rather than throwing
+   * an exception.
+   *
+   * @param host the host to connect to
+   * @param port the port to connect on
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if host is null
+   * @see Socket#Socket()
+   */
+  public void checkConnect(String host, int port)
+  {
+    if (port == -1)
+      checkPermission(new SocketPermission(host, "resolve"));
+    else
+      // Use the toString() hack to do the null check.
+      checkPermission(new SocketPermission(host.toString() + ":" + port,
+                                           "connect"));
+  }
+
+  /**
+   * Check if the current thread is allowed to connect to a given host on a
+   * given port, using the given security context. The context must be a
+   * result of a previous call to <code>getSecurityContext</code>. A port
+   * number of -1 indicates the caller is attempting to determine an IP
+   * address, so the default implementation checks
+   * <code>AccessControlContext.checkPermission(new SocketPermission(host,
+   * "resolve"))</code>. Otherwise, the default implementation checks
+   * <code>AccessControlContext.checkPermission(new SocketPermission(host
+   * + ":" + port, "connect"))</code>. If you override this, call
+   * <code>super.checkConnect</code> rather than throwing an exception.
+   *
+   * @param host the host to connect to
+   * @param port the port to connect on
+   * @param context the context to determine access for
+   *
+   * @throws SecurityException if permission is denied, or if context is
+   *         not an AccessControlContext
+   * @throws NullPointerException if host is null
+   *
+   * @see #getSecurityContext()
+   * @see AccessControlContext#checkPermission(Permission)
+   */
+  public void checkConnect(String host, int port, Object context)
+  {
+    if (! (context instanceof AccessControlContext))
+      throw new SecurityException("Missing context");
+    AccessControlContext ac = (AccessControlContext) context;
+    if (port == -1)
+      ac.checkPermission(new SocketPermission(host, "resolve"));
+    else
+      // Use the toString() hack to do the null check.
+      ac.checkPermission(new SocketPermission(host.toString() + ":" + port,
+                                              "connect"));
+  }
+
+  /**
+   * Check if the current thread is allowed to listen to a specific port for
+   * data. This method is called by ServerSocket.ServerSocket(). The default
+   * implementation checks
+   * <code>SocketPermission("localhost:" + (port == 0 ? "1024-" : "" + port),
+   * "listen")</code>. If you override this, call
+   * <code>super.checkListen</code> rather than throwing an exception.
+   *
+   * @param port the port to listen on
+   * @throws SecurityException if permission is denied
+   * @see ServerSocket#ServerSocket(int)
+   */
+  public void checkListen(int port)
+  {
+    checkPermission(new SocketPermission("localhost:"
+                                         + (port == 0 ? "1024-" : "" +port),
+                                         "listen"));
+  }
+
+  /**
+   * Check if the current thread is allowed to accept a connection from a
+   * particular host on a particular port. This method is called by
+   * ServerSocket.implAccept(). The default implementation checks
+   * <code>SocketPermission(host + ":" + port, "accept")</code>. If you
+   * override this, call <code>super.checkAccept</code> rather than throwing
+   * an exception.
+   *
+   * @param host the host which wishes to connect
+   * @param port the port the connection will be on
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if host is null
+   * @see ServerSocket#accept()
+   */
+  public void checkAccept(String host, int port)
+  {
+    // Use the toString() hack to do the null check.
+    checkPermission(new SocketPermission(host.toString() + ":" + port,
+                                         "accept"));
+  }
+
+  /**
+   * Check if the current thread is allowed to read and write multicast to
+   * a particular address. The default implementation checks
+   * <code>SocketPermission(addr.getHostAddress(), "accept,connect")</code>.
+   * If you override this, call <code>super.checkMulticast</code> rather than
+   * throwing an exception.
+   *
+   * @param addr the address to multicast to
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if host is null
+   * @since 1.1
+   */
+  public void checkMulticast(InetAddress addr)
+  {
+    checkPermission(new SocketPermission(addr.getHostAddress(),
+                                         "accept,connect"));
+  }
+
+  /**
+   *Check if the current thread is allowed to read and write multicast to
+   * a particular address with a particular ttl (time-to-live) value. The
+   * default implementation ignores ttl, and checks
+   * <code>SocketPermission(addr.getHostAddress(), "accept,connect")</code>.
+   * If you override this, call <code>super.checkMulticast</code> rather than
+   * throwing an exception.
+   *
+   * @param addr the address to multicast to
+   * @param ttl value in use for multicast send
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if host is null
+   * @since 1.1
+   * @deprecated use {@link #checkPermission(Permission)} instead
+   */
+  public void checkMulticast(InetAddress addr, byte ttl)
+  {
+    checkPermission(new SocketPermission(addr.getHostAddress(),
+                                         "accept,connect"));
+  }
+
+  /**
+   * Check if the current thread is allowed to read or write all the system
+   * properties at once. This method is called by System.getProperties()
+   * and setProperties(). The default implementation checks
+   * <code>PropertyPermission("*", "read,write")</code>. If you override
+   * this, call <code>super.checkPropertiesAccess</code> rather than
+   * throwing an exception.
+   *
+   * @throws SecurityException if permission is denied
+   * @see System#getProperties()
+   * @see System#setProperties(Properties)
+   */
+  public void checkPropertiesAccess()
+  {
+    checkPermission(new PropertyPermission("*", "read,write"));
+  }
+
+  /**
+   * Check if the current thread is allowed to read a particular system
+   * property (writes are checked directly via checkPermission). This method
+   * is called by System.getProperty() and setProperty(). The default
+   * implementation checks <code>PropertyPermission(key, "read")</code>. If
+   * you override this, call <code>super.checkPropertyAccess</code> rather
+   * than throwing an exception.
+   *
+   * @param key the key of the property to check
+   *
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if key is null
+   * @throws IllegalArgumentException if key is ""
+   *
+   * @see System#getProperty(String)
+   */
+  public void checkPropertyAccess(String key)
+  {
+    checkPermission(new PropertyPermission(key, "read"));
+  }
+
+  /**
+   * Check if the current thread is allowed to create a top-level window. If
+   * it is not, the operation should still go through, but some sort of
+   * nonremovable warning should be placed on the window to show that it
+   * is untrusted. This method is called by Window.Window(). The default
+   * implementation checks
+   * <code>AWTPermission("showWindowWithoutWarningBanner")</code>, and returns
+   * true if no exception was thrown. If you override this, use
+   * <code>return super.checkTopLevelWindow</code> rather than returning
+   * false.
+   *
+   * @param window the window to create
+   * @return true if there is permission to show the window without warning
+   * @throws NullPointerException if window is null
+   * @see java.awt.Window#Window(java.awt.Frame)
+   */
+  public boolean checkTopLevelWindow(Object window)
+  {
+    if (window == null)
+      throw new NullPointerException();
+    try
+      {
+        checkPermission(new AWTPermission("showWindowWithoutWarningBanner"));
+        return true;
+      }
+    catch (SecurityException e)
+      {
+        return false;
+      }
+  }
+
+  /**
+   * Check if the current thread is allowed to create a print job. This
+   * method is called by Toolkit.getPrintJob(). The default implementation
+   * checks <code>RuntimePermission("queuePrintJob")</code>. If you override
+   * this, call <code>super.checkPrintJobAccess</code> rather than throwing
+   * an exception.
+   *
+   * @throws SecurityException if permission is denied
+   * @see java.awt.Toolkit#getPrintJob(java.awt.Frame, String, Properties)
+   * @since 1.1
+   */
+  public void checkPrintJobAccess()
+  {
+    checkPermission(new RuntimePermission("queuePrintJob"));
+  }
+
+  /**
+   * Check if the current thread is allowed to use the system clipboard. This
+   * method is called by Toolkit.getSystemClipboard(). The default
+   * implementation checks <code>AWTPermission("accessClipboard")</code>. If
+   * you override this, call <code>super.checkSystemClipboardAccess</code>
+   * rather than throwing an exception.
+   *
+   * @throws SecurityException if permission is denied
+   * @see java.awt.Toolkit#getSystemClipboard()
+   * @since 1.1
+   */
+  public void checkSystemClipboardAccess()
+  {
+    checkPermission(new AWTPermission("accessClipboard"));
+  }
+
+  /**
+   * Check if the current thread is allowed to use the AWT event queue. This
+   * method is called by Toolkit.getSystemEventQueue(). The default
+   * implementation checks <code>AWTPermission("accessEventQueue")</code>.
+   * you override this, call <code>super.checkAwtEventQueueAccess</code>
+   * rather than throwing an exception.
+   *
+   * @throws SecurityException if permission is denied
+   * @see java.awt.Toolkit#getSystemEventQueue()
+   * @since 1.1
+   */
+  public void checkAwtEventQueueAccess()
+  {
+    checkPermission(new AWTPermission("accessEventQueue"));
+  }
+
+  /**
+   * Check if the current thread is allowed to access the specified package
+   * at all. This method is called by ClassLoader.loadClass() in user-created
+   * ClassLoaders. The default implementation gets a list of all restricted
+   * packages, via <code>Security.getProperty("package.access")</code>. Then,
+   * if packageName starts with or equals any restricted package, it checks
+   * <code>RuntimePermission("accessClassInPackage." + packageName)</code>.
+   * If you override this, you should call
+   * <code>super.checkPackageAccess</code> before doing anything else.
+   *
+   * @param packageName the package name to check access to
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if packageName is null
+   * @see ClassLoader#loadClass(String, boolean)
+   * @see Security#getProperty(String)
+   */
+  public void checkPackageAccess(String packageName)
+  {
+    checkPackageList(packageName, "package.access", "accessClassInPackage.");
+  }
+
+  /**
+   * Check if the current thread is allowed to define a class into the
+   * specified package. This method is called by ClassLoader.loadClass() in
+   * user-created ClassLoaders. The default implementation gets a list of all
+   * restricted packages, via
+   * <code>Security.getProperty("package.definition")</code>. Then, if
+   * packageName starts with or equals any restricted package, it checks
+   * <code>RuntimePermission("defineClassInPackage." + packageName)</code>.
+   * If you override this, you should call
+   * <code>super.checkPackageDefinition</code> before doing anything else.
+   *
+   * @param packageName the package name to check access to
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if packageName is null
+   * @see ClassLoader#loadClass(String, boolean)
+   * @see Security#getProperty(String)
+   */
+  public void checkPackageDefinition(String packageName)
+  {
+    checkPackageList(packageName, "package.definition", "defineClassInPackage.");
+  }
+
+  /**
+   * Check if the current thread is allowed to set the current socket factory.
+   * This method is called by Socket.setSocketImplFactory(),
+   * ServerSocket.setSocketFactory(), and URL.setURLStreamHandlerFactory().
+   * The default implementation checks
+   * <code>RuntimePermission("setFactory")</code>. If you override this, call
+   * <code>super.checkSetFactory</code> rather than throwing an exception.
+   *
+   * @throws SecurityException if permission is denied
+   * @see Socket#setSocketImplFactory(SocketImplFactory)
+   * @see ServerSocket#setSocketFactory(SocketImplFactory)
+   * @see URL#setURLStreamHandlerFactory(URLStreamHandlerFactory)
+   */
+  public void checkSetFactory()
+  {
+    checkPermission(new RuntimePermission("setFactory"));
+  }
+
+  /**
+   * Check if the current thread is allowed to get certain types of Methods,
+   * Fields and Constructors from a Class object. This method is called by
+   * Class.getMethod[s](), Class.getField[s](), Class.getConstructor[s],
+   * Class.getDeclaredMethod[s](), Class.getDeclaredField[s](), and
+   * Class.getDeclaredConstructor[s](). The default implementation allows
+   * PUBLIC access, and access to classes defined by the same classloader as
+   * the code performing the reflection. Otherwise, it checks
+   * <code>RuntimePermission("accessDeclaredMembers")</code>. If you override
+   * this, do not call <code>super.checkMemberAccess</code>, as this would
+   * mess up the stack depth check that determines the ClassLoader requesting
+   * the access.
+   *
+   * @param c the Class to check
+   * @param memberType either DECLARED or PUBLIC
+   * @throws SecurityException if permission is denied, including when
+   *         memberType is not DECLARED or PUBLIC
+   * @throws NullPointerException if c is null
+   * @see Class
+   * @see Member#DECLARED
+   * @see Member#PUBLIC
+   * @since 1.1
+   */
+  public void checkMemberAccess(Class c, int memberType)
+  {
+    if (c == null)
+      throw new NullPointerException();
+    if (memberType == Member.PUBLIC)
+      return;
+    // XXX Allow access to classes created by same classloader before next
+    // check.
+    checkPermission(new RuntimePermission("accessDeclaredMembers"));
+  }
+
+  /**
+   * Test whether a particular security action may be taken. The default
+   * implementation checks <code>SecurityPermission(action)</code>. If you
+   * override this, call <code>super.checkSecurityAccess</code> rather than
+   * throwing an exception.
+   *
+   * @param action the desired action to take
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if action is null
+   * @throws IllegalArgumentException if action is ""
+   * @since 1.1
+   */
+  public void checkSecurityAccess(String action)
+  {
+    checkPermission(new SecurityPermission(action));
+  }
+
+  /**
+   * Get the ThreadGroup that a new Thread should belong to by default. Called
+   * by Thread.Thread(). The default implementation returns the current
+   * ThreadGroup of the current Thread. <STRONG>Spec Note:</STRONG> it is not
+   * clear whether the new Thread is guaranteed to pass the
+   * checkAccessThreadGroup() test when using this ThreadGroup, but I presume
+   * so.
+   *
+   * @return the ThreadGroup to put the new Thread into
+   * @since 1.1
+   */
+  public ThreadGroup getThreadGroup()
+  {
+    return Thread.currentThread().getThreadGroup();
+  }
+
+  /**
+   * Helper that checks a comma-separated list of restricted packages, from
+   * <code>Security.getProperty("package.definition")</code>, for the given
+   * package access permission. If packageName starts with or equals any
+   * restricted package, it checks
+   * <code>RuntimePermission(permission + packageName)</code>.
+   *
+   * @param packageName the package name to check access to
+   * @param restriction "package.access" or "package.definition"
+   * @param permission the base permission, including the '.'
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if packageName is null
+   * @see #checkPackageAccess(String)
+   * @see #checkPackageDefinition(String)
+   */
+  void checkPackageList(String packageName, final String restriction,
+                        String permission)
+  {
+    if (packageName == null)
+      throw new NullPointerException();
+
+    String list = (String)AccessController.doPrivileged(new PrivilegedAction()
+      {
+	public Object run()
+        {
+	  return Security.getProperty(restriction);
+	}
+      });
+
+    if (list == null || list.equals(""))
+      return;
+
+    String packageNamePlusDot = packageName + ".";
+
+    StringTokenizer st = new StringTokenizer(list, ",");
+    while (st.hasMoreTokens())
+      {
+	if (packageNamePlusDot.startsWith(st.nextToken()))
+	  {
+	    Permission p = new RuntimePermission(permission + packageName);
+	    checkPermission(p);
+	    return;
+	  }
+      }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/String.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/String.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/String.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/String.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1397 @@
+/* String.java -- immutable character sequences; the object of string literals
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang;
+
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.lang.Comparable;
+import java.util.Comparator;
+import java.util.Locale;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * Strings represent an immutable set of characters.  All String literals
+ * are instances of this class, and two string literals with the same contents
+ * refer to the same String object.
+ *
+ * <p>This class also includes a number of methods for manipulating the
+ * contents of strings (of course, creating a new object if there are any
+ * changes, as String is immutable). Case mapping relies on Unicode 3.0.0
+ * standards, where some character sequences have a different number of
+ * characters in the uppercase version than the lower case.
+ *
+ * <p>Strings are special, in that they are the only object with an overloaded
+ * operator. When you use '+' with at least one String argument, both
+ * arguments have String conversion performed on them, and another String (not
+ * guaranteed to be unique) results.
+ *
+ * <p>String is special-cased when doing data serialization - rather than
+ * listing the fields of this class, a String object is converted to a string
+ * literal in the object stream.
+ *
+ * @author Paul N. Fisher
+ * @author Eric Blake (ebb9 at email.byu.edu)
+ * @author Per Bothner (bothner at cygnus.com)
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public final class String implements Serializable, Comparable, CharSequence
+{
+  // WARNING: String is a CORE class in the bootstrap cycle. See the comments
+  // in vm/reference/java/lang/Runtime for implications of this fact.
+
+  /**
+   * This is probably not necessary because this class is special cased already
+   * but it will avoid showing up as a discrepancy when comparing SUIDs.
+   */
+  private static final long serialVersionUID = -6849794470754667710L;
+
+  /**
+   * This is the object that holds the characters that make up the
+   * String.  It might be a char[], or it could be String.  It could
+   * even be `this'.  The actual characters can't be located using
+   * pure Java code.
+   * @see #boffset
+   */
+  private Object data;
+
+  /**
+   * This is a <emph>byte</emph> offset of the actual characters from
+   * the start of the character-holding object.  Don't use this field
+   * in Java code.
+   */
+  private int boffset;
+
+  /**
+   * Holds the number of characters in value.  Package visible for use
+   * by trusted code.
+   */
+  int count;
+
+  /**
+   * Caches the result of hashCode().  If this value is zero, the hashcode
+   * is considered uncached (even if 0 is the correct hash value).
+   */
+  private int cachedHashCode;
+
+  /**
+   * An implementation for {@link CASE_INSENSITIVE_ORDER}.
+   * This must be {@link Serializable}. The class name is dictated by
+   * compatibility with Sun's JDK.
+   */
+  private static final class CaseInsensitiveComparator
+    implements Comparator, Serializable
+  {
+    /**
+     * Compatible with JDK 1.2.
+     */
+    private static final long serialVersionUID = 8575799808933029326L;
+
+    /**
+     * The default private constructor generates unnecessary overhead.
+     */
+    CaseInsensitiveComparator() {}
+
+    /**
+     * Compares to Strings, using
+     * <code>String.compareToIgnoreCase(String)</code>.
+     *
+     * @param o1 the first string
+     * @param o2 the second string
+     * @return < 0, 0, or > 0 depending on the case-insensitive
+     *         comparison of the two strings.
+     * @throws NullPointerException if either argument is null
+     * @throws ClassCastException if either argument is not a String
+     * @see #compareToIgnoreCase(String)
+     */
+    public int compare(Object o1, Object o2)
+    {
+      return ((String) o1).compareToIgnoreCase((String) o2);
+    }
+  } // class CaseInsensitiveComparator
+
+  /**
+   * A Comparator that uses <code>String.compareToIgnoreCase(String)</code>.
+   * This comparator is {@link Serializable}. Note that it ignores Locale,
+   * for that, you want a Collator.
+   *
+   * @see Collator#compare(String, String)
+   * @since 1.2
+   */
+  public static final Comparator CASE_INSENSITIVE_ORDER
+    = new CaseInsensitiveComparator();
+
+  /**
+   * Creates an empty String (length 0). Unless you really need a new object,
+   * consider using <code>""</code> instead.
+   */
+  public String()
+  {
+    data = "".data;
+    boffset = 0;
+    count = 0;
+  }
+
+  /**
+   * Copies the contents of a String to a new String. Since Strings are
+   * immutable, only a shallow copy is performed.
+   *
+   * @param str String to copy
+   * @throws NullPointerException if value is null
+   */
+  public String(String str)
+  {
+    data = str.data;
+    boffset = str.boffset;
+    count = str.count;
+    cachedHashCode = str.cachedHashCode;
+  }
+
+  /**
+   * Creates a new String using the character sequence of the char array.
+   * Subsequent changes to data do not affect the String.
+   *
+   * @param data char array to copy
+   * @throws NullPointerException if data is null
+   */
+  public String(char[] data)
+  {
+    init(data, 0, data.length, false);
+  }
+
+  /**
+   * Creates a new String using the character sequence of a subarray of
+   * characters. The string starts at offset, and copies count chars.
+   * Subsequent changes to data do not affect the String.
+   *
+   * @param data char array to copy
+   * @param offset position (base 0) to start copying out of data
+   * @param count the number of characters from data to copy
+   * @throws NullPointerException if data is null
+   * @throws IndexOutOfBoundsException if (offset < 0 || count < 0
+   *         || offset + count > data.length)
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   */
+  public String(char[] data, int offset, int count)
+  {
+    init(data, offset, count, false);
+  }
+
+  /**
+   * Creates a new String using an 8-bit array of integer values, starting at
+   * an offset, and copying up to the count. Each character c, using
+   * corresponding byte b, is created in the new String as if by performing:
+   *
+   * <pre>
+   * c = (char) (((hibyte & 0xff) << 8) | (b & 0xff))
+   * </pre>
+   *
+   * @param ascii array of integer values
+   * @param hibyte top byte of each Unicode character
+   * @param offset position (base 0) to start copying out of ascii
+   * @param count the number of characters from ascii to copy
+   * @throws NullPointerException if ascii is null
+   * @throws IndexOutOfBoundsException if (offset < 0 || count < 0
+   *         || offset + count > ascii.length)
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   * @see #String(byte[])
+   * @see #String(byte[], String)
+   * @see #String(byte[], int, int)
+   * @see #String(byte[], int, int, String)
+   * @deprecated use {@link #String(byte[], int, int, String)} to perform
+   *             correct encoding
+   */
+  public String(byte[] ascii, int hibyte, int offset, int count)
+  {
+    init(ascii, hibyte, offset, count);
+  }
+
+  /**
+   * Creates a new String using an 8-bit array of integer values. Each
+   * character c, using corresponding byte b, is created in the new String
+   * as if by performing:
+   *
+   * <pre>
+   * c = (char) (((hibyte & 0xff) << 8) | (b & 0xff))
+   * </pre>
+   *
+   * @param ascii array of integer values
+   * @param hibyte top byte of each Unicode character
+   * @throws NullPointerException if ascii is null
+   * @see #String(byte[])
+   * @see #String(byte[], String)
+   * @see #String(byte[], int, int)
+   * @see #String(byte[], int, int, String)
+   * @see #String(byte[], int, int, int)
+   * @deprecated use {@link #String(byte[], String)} to perform
+   *             correct encoding
+   */
+  public String(byte[] ascii, int hibyte)
+  {
+    init(ascii, hibyte, 0, ascii.length);
+  }
+
+  /**
+   * Creates a new String using the portion of the byte array starting at the
+   * offset and ending at offset + count. Uses the specified encoding type
+   * to decode the byte array, so the resulting string may be longer or
+   * shorter than the byte array. For more decoding control, use
+   * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
+   * see {@link java.nio.charset.Charset}. The behavior is not specified if
+   * the decoder encounters invalid characters; this implementation throws
+   * an Error.
+   *
+   * @param data byte array to copy
+   * @param offset the offset to start at
+   * @param count the number of characters in the array to use
+   * @param encoding the name of the encoding to use
+   * @throws NullPointerException if data or encoding is null
+   * @throws IndexOutOfBoundsException if offset or count is incorrect
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   * @throws UnsupportedEncodingException if encoding is not found
+   * @throws Error if the decoding fails
+   * @since 1.1
+   */
+  public String(byte[] data, int offset, int count, String encoding)
+    throws UnsupportedEncodingException
+  {
+    init (data, offset, count, encoding);
+  }
+
+  /**
+   * Creates a new String using the byte array. Uses the specified encoding
+   * type to decode the byte array, so the resulting string may be longer or
+   * shorter than the byte array. For more decoding control, use
+   * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
+   * see {@link java.nio.charset.Charset}. The behavior is not specified if
+   * the decoder encounters invalid characters; this implementation throws
+   * an Error.
+   *
+   * @param data byte array to copy
+   * @param encoding the name of the encoding to use
+   * @throws NullPointerException if data or encoding is null
+   * @throws UnsupportedEncodingException if encoding is not found
+   * @throws Error if the decoding fails
+   * @see #String(byte[], int, int, String)
+   * @since 1.1
+   */
+  public String(byte[] data, String encoding)
+    throws UnsupportedEncodingException
+  {
+    this(data, 0, data.length, encoding);
+  }
+
+  /**
+   * Creates a new String using the portion of the byte array starting at the
+   * offset and ending at offset + count. Uses the encoding of the platform's
+   * default charset, so the resulting string may be longer or shorter than
+   * the byte array. For more decoding control, use
+   * {@link java.nio.charset.CharsetDecoder}.  The behavior is not specified
+   * if the decoder encounters invalid characters; this implementation throws
+   * an Error.
+   *
+   * @param data byte array to copy
+   * @param offset the offset to start at
+   * @param count the number of characters in the array to use
+   * @throws NullPointerException if data is null
+   * @throws IndexOutOfBoundsException if offset or count is incorrect
+   * @throws Error if the decoding fails
+   * @see #String(byte[], int, int, String)
+   * @since 1.1
+   */
+  public String(byte[] data, int offset, int count)
+  {
+    try
+      {
+	init (data, offset, count,
+	      System.getProperty("file.encoding", "8859_1"));
+      }
+    catch (UnsupportedEncodingException x1)
+      {
+	// Maybe the default encoding is bad.
+	try
+	  {
+	    init (data, offset, count, "8859_1");
+	  }
+	catch (UnsupportedEncodingException x2)
+	  {
+	    // We know this can't happen.
+	  }
+      }
+  }
+
+  /**
+   * Creates a new String using the byte array. Uses the encoding of the
+   * platform's default charset, so the resulting string may be longer or
+   * shorter than the byte array. For more decoding control, use
+   * {@link java.nio.charset.CharsetDecoder}.  The behavior is not specified
+   * if the decoder encounters invalid characters; this implementation throws
+   * an Error.
+   *
+   * @param data byte array to copy
+   * @throws NullPointerException if data is null
+   * @throws Error if the decoding fails
+   * @see #String(byte[], int, int)
+   * @see #String(byte[], int, int, String)
+   * @since 1.1
+   */
+  public String(byte[] data)
+  {
+    this(data, 0, data.length);
+  }
+
+  /**
+   * Creates a new String using the character sequence represented by
+   * the StringBuffer. Subsequent changes to buf do not affect the String.
+   *
+   * @param buffer StringBuffer to copy
+   * @throws NullPointerException if buffer is null
+   */
+  public String(StringBuffer buffer)
+  {
+    synchronized (buffer)
+      {
+	// Share unless buffer is 3/4 empty.
+	boolean should_copy = ((buffer.count << 2) < buffer.value.length);
+	if (! should_copy)
+	  buffer.shared = true;
+	init (buffer.value, 0, buffer.count, ! should_copy);
+      }
+  }
+
+  /**
+   * Creates a new String using the character sequence represented by
+   * the StringBuilder. Subsequent changes to buf do not affect the String.
+   *
+   * @param buffer StringBuilder to copy
+   * @throws NullPointerException if buffer is null
+   */
+  public String(StringBuilder buffer)
+  {
+    this(buffer.value, 0, buffer.count);
+  }
+
+  /**
+   * Special constructor which can share an array when safe to do so.
+   *
+   * @param data the characters to copy
+   * @param offset the location to start from
+   * @param count the number of characters to use
+   * @param dont_copy true if the array is trusted, and need not be copied
+   * @throws NullPointerException if chars is null
+   * @throws StringIndexOutOfBoundsException if bounds check fails
+   */
+  String(char[] data, int offset, int count, boolean dont_copy)
+  {
+    init(data, offset, count, dont_copy);
+  }
+
+  // This is used by gnu.gcj.runtime.StringBuffer, so it must have
+  // package-private protection.  It is accessed via CNI and so avoids
+  // ordinary protection mechanisms.
+  String(gnu.gcj.runtime.StringBuffer buffer)
+  {
+    // No need to synchronize or mark the buffer, since we know it is
+    // only used once.
+    init (buffer);
+  }
+
+  /**
+   * Returns the number of characters contained in this String.
+   *
+   * @return the length of this String
+   */
+  public int length()
+  {
+    return count;
+  }
+
+  /**
+   * Returns the character located at the specified index within this String.
+   *
+   * @param index position of character to return (base 0)
+   * @return character located at position index
+   * @throws IndexOutOfBoundsException if index < 0 || index >= length()
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   */
+  public native char charAt(int index);
+
+  /**
+   * Get the code point at the specified index.  This is like #charAt(int),
+   * but if the character is the start of a surrogate pair, and the
+   * following character completes the pair, then the corresponding
+   * supplementary code point is returned.
+   * @param index the index of the codepoint to get, starting at 0
+   * @return the codepoint at the specified index
+   * @throws IndexOutOfBoundsException if index is negative or >= length()
+   * @since 1.5
+   */
+  public synchronized int codePointAt(int index)
+  {
+    // Use the CharSequence overload as we get better range checking
+    // this way.
+    return Character.codePointAt(this, index);
+  }
+
+  /**
+   * Get the code point before the specified index.  This is like
+   * #codePointAt(int), but checks the characters at <code>index-1</code> and
+   * <code>index-2</code> to see if they form a supplementary code point.
+   * @param index the index just past the codepoint to get, starting at 0
+   * @return the codepoint at the specified index
+   * @throws IndexOutOfBoundsException if index is negative or >= length()
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   * @since 1.5
+   */
+  public synchronized int codePointBefore(int index)
+  {
+    // Use the CharSequence overload as we get better range checking
+    // this way.
+    return Character.codePointBefore(this, index);
+  }
+
+  /**
+   * Copies characters from this String starting at a specified start index,
+   * ending at a specified stop index, to a character array starting at
+   * a specified destination begin index.
+   *
+   * @param srcBegin index to begin copying characters from this String
+   * @param srcEnd index after the last character to be copied from this String
+   * @param dst character array which this String is copied into
+   * @param dstBegin index to start writing characters into dst
+   * @throws NullPointerException if dst is null
+   * @throws IndexOutOfBoundsException if any indices are out of bounds
+   *         (while unspecified, source problems cause a
+   *         StringIndexOutOfBoundsException, and dst problems cause an
+   *         ArrayIndexOutOfBoundsException)
+   */
+  public native void getChars(int srcBegin, int srcEnd,
+			      char[] dst, int dstBegin);
+
+  /**
+   * Copies the low byte of each character from this String starting at a
+   * specified start index, ending at a specified stop index, to a byte array
+   * starting at a specified destination begin index.
+   *
+   * @param srcBegin index to being copying characters from this String
+   * @param srcEnd index after the last character to be copied from this String
+   * @param dst byte array which each low byte of this String is copied into
+   * @param dstBegin index to start writing characters into dst
+   * @throws NullPointerException if dst is null and copy length is non-zero
+   * @throws IndexOutOfBoundsException if any indices are out of bounds
+   *         (while unspecified, source problems cause a
+   *         StringIndexOutOfBoundsException, and dst problems cause an
+   *         ArrayIndexOutOfBoundsException)
+   * @see #getBytes()
+   * @see #getBytes(String)
+   * @deprecated use {@link #getBytes()}, which uses a char to byte encoder
+   */
+  public native void getBytes(int srcBegin, int srcEnd,
+			      byte[] dst, int dstBegin);
+
+  /**
+   * Converts the Unicode characters in this String to a byte array. Uses the
+   * specified encoding method, so the result may be longer or shorter than
+   * the String. For more encoding control, use
+   * {@link java.nio.charset.CharsetEncoder}, and for valid character sets,
+   * see {@link java.nio.charset.Charset}. The behavior is not specified if
+   * the encoder encounters a problem; this implementation returns null.
+   *
+   * @param enc encoding name
+   * @return the resulting byte array, or null on a problem
+   * @throws NullPointerException if enc is null
+   * @throws UnsupportedEncodingException if encoding is not supported
+   * @since 1.1
+   */
+  public native byte[] getBytes(String enc)
+    throws UnsupportedEncodingException;
+
+  /**
+   * Converts the Unicode characters in this String to a byte array. Uses the
+   * encoding of the platform's default charset, so the result may be longer
+   * or shorter than the String. For more encoding control, use
+   * {@link java.nio.charset.CharsetEncoder}.  The behavior is not specified if
+   * the encoder encounters a problem; this implementation returns null.
+   *
+   * @return the resulting byte array, or null on a problem
+   * @since 1.1
+   */
+  public byte[] getBytes()
+  {
+    try
+      {
+	return getBytes (System.getProperty("file.encoding", "8859_1"));
+      }
+    catch (UnsupportedEncodingException x)
+      {
+	// This probably shouldn't happen, but could if file.encoding
+	// is somehow changed to a value we don't understand.
+	try
+	  {
+	    return getBytes ("8859_1");
+	  }
+	catch (UnsupportedEncodingException x2)
+	  {
+	    // This really shouldn't happen, because the 8859_1
+	    // encoding should always be available.
+	    throw new InternalError ("couldn't find 8859_1 encoder");
+	  }
+      }
+  }
+
+  /**
+   * Predicate which compares anObject to this. This is true only for Strings
+   * with the same character sequence.
+   *
+   * @param anObject the object to compare
+   * @return true if anObject is semantically equal to this
+   * @see #compareTo(String)
+   * @see #equalsIgnoreCase(String)
+   */
+  public native boolean equals(Object anObject);
+
+  /**
+   * Compares the given StringBuffer to this String. This is true if the
+   * StringBuffer has the same content as this String at this moment.
+   *
+   * @param buffer the StringBuffer to compare to
+   * @return true if StringBuffer has the same character sequence
+   * @throws NullPointerException if the given StringBuffer is null
+   * @since 1.4
+   */
+  public native boolean contentEquals(StringBuffer buffer);
+
+  /**
+   * Compares the given CharSequence to this String. This is true if
+   * the CharSequence has the same content as this String at this
+   * moment.
+   *
+   * @param seq the CharSequence to compare to
+   * @return true if CharSequence has the same character sequence
+   * @throws NullPointerException if the given CharSequence is null
+   * @since 1.5
+   */
+  public native boolean contentEquals(CharSequence seq);
+
+  /**
+   * Compares a String to this String, ignoring case. This does not handle
+   * multi-character capitalization exceptions; instead the comparison is
+   * made on a character-by-character basis, and is true if:<br><ul>
+   * <li><code>c1 == c2</code></li>
+   * <li><code>Character.toUpperCase(c1)
+   *     == Character.toUpperCase(c2)</code></li>
+   * <li><code>Character.toLowerCase(c1)
+   *     == Character.toLowerCase(c2)</code></li>
+   * </ul>
+   *
+   * @param anotherString String to compare to this String
+   * @return true if anotherString is equal, ignoring case
+   * @see #equals(Object)
+   * @see Character#toUpperCase(char)
+   * @see Character#toLowerCase(char)
+   */
+  public native boolean equalsIgnoreCase(String anotherString);
+
+  /**
+   * Compares this String and another String (case sensitive,
+   * lexicographically). The result is less than 0 if this string sorts
+   * before the other, 0 if they are equal, and greater than 0 otherwise.
+   * After any common starting sequence is skipped, the result is
+   * <code>this.charAt(k) - anotherString.charAt(k)</code> if both strings
+   * have characters remaining, or
+   * <code>this.length() - anotherString.length()</code> if one string is
+   * a subsequence of the other.
+   *
+   * @param anotherString the String to compare against
+   * @return the comparison
+   * @throws NullPointerException if anotherString is null
+   */
+  public native int compareTo(String anotherString);
+
+  /**
+   * Behaves like <code>compareTo(java.lang.String)</code> unless the Object
+   * is not a <code>String</code>.  Then it throws a
+   * <code>ClassCastException</code>.
+   *
+   * @param o the object to compare against
+   * @return the comparison
+   * @throws NullPointerException if o is null
+   * @throws ClassCastException if o is not a <code>String</code>
+   * @since 1.2
+   */
+  public int compareTo(Object o)
+  {
+    return compareTo((String) o);
+  }
+
+  /**
+   * Compares this String and another String (case insensitive). This
+   * comparison is <em>similar</em> to equalsIgnoreCase, in that it ignores
+   * locale and multi-characater capitalization, and compares characters
+   * after performing
+   * <code>Character.toLowerCase(Character.toUpperCase(c))</code> on each
+   * character of the string. This is unsatisfactory for locale-based
+   * comparison, in which case you should use {@link java.text.Collator}.
+   *
+   * @param str the string to compare against
+   * @return the comparison
+   * @see Collator#compare(String, String)
+   * @since 1.2
+   */
+  public int compareToIgnoreCase(String str)
+  {
+    return this.toUpperCase().toLowerCase().compareTo(
+     str.toUpperCase().toLowerCase());
+  }  
+
+  /**
+   * Predicate which determines if this String matches another String
+   * starting at a specified offset for each String and continuing
+   * for a specified length. Indices out of bounds are harmless, and give
+   * a false result.
+   *
+   * @param toffset index to start comparison at for this String
+   * @param other String to compare region to this String
+   * @param ooffset index to start comparison at for other
+   * @param len number of characters to compare
+   * @return true if regions match (case sensitive)
+   * @throws NullPointerException if other is null
+   */
+  public native boolean regionMatches(int toffset,
+				      String other, int ooffset, int len);
+
+  /**
+   * Predicate which determines if this String matches another String
+   * starting at a specified offset for each String and continuing
+   * for a specified length, optionally ignoring case. Indices out of bounds
+   * are harmless, and give a false result. Case comparisons are based on
+   * <code>Character.toLowerCase()</code> and
+   * <code>Character.toUpperCase()</code>, not on multi-character
+   * capitalization expansions.
+   *
+   * @param ignoreCase true if case should be ignored in comparision
+   * @param toffset index to start comparison at for this String
+   * @param other String to compare region to this String
+   * @param oofset index to start comparison at for other
+   * @param len number of characters to compare
+   * @return true if regions match, false otherwise
+   * @throws NullPointerException if other is null
+   */
+  public native boolean regionMatches(boolean ignoreCase, int toffset,
+				      String other, int ooffset, int len);
+
+  /**
+   * Predicate which determines if this String contains the given prefix,
+   * beginning comparison at toffset. The result is false if toffset is
+   * negative or greater than this.length(), otherwise it is the same as
+   * <code>this.substring(toffset).startsWith(prefix)</code>.
+   *
+   * @param prefix String to compare
+   * @param toffset offset for this String where comparison starts
+   * @return true if this String starts with prefix
+   * @throws NullPointerException if prefix is null
+   * @see #regionMatches(boolean, int, String, int, int)
+   */
+  public native boolean startsWith(String prefix, int toffset);
+
+  /**
+   * Predicate which determines if this String starts with a given prefix.
+   * If the prefix is an empty String, true is returned.
+   *
+   * @param prefix String to compare
+   * @return true if this String starts with the prefix
+   * @throws NullPointerException if prefix is null
+   * @see #startsWith(String, int)
+   */
+  public boolean startsWith(String prefix)
+  {
+    return startsWith (prefix, 0);
+  }
+
+  /**
+   * Predicate which determines if this String ends with a given suffix.
+   * If the suffix is an empty String, true is returned.
+   *
+   * @param suffix String to compare
+   * @return true if this String ends with the suffix
+   * @throws NullPointerException if suffix is null
+   * @see #regionMatches(boolean, int, String, int, int)
+   */
+  public boolean endsWith(String suffix)
+  {
+    return regionMatches (this.count - suffix.count, suffix, 0, suffix.count);
+  }
+
+  /**
+   * Computes the hashcode for this String. This is done with int arithmetic,
+   * where ** represents exponentiation, by this formula:<br>
+   * <code>s[0]*31**(n-1) + s[1]*31**(n-2) + ... + s[n-1]</code>.
+   *
+   * @return hashcode value of this String
+   */
+  public native int hashCode();
+
+  /**
+   * Finds the first instance of a character in this String.
+   *
+   * @param ch character to find
+   * @return location (base 0) of the character, or -1 if not found
+   */
+  public int indexOf(int ch)
+  {
+    return indexOf(ch, 0);
+  }
+
+  /**
+   * Finds the first instance of a character in this String, starting at
+   * a given index.  If starting index is less than 0, the search
+   * starts at the beginning of this String.  If the starting index
+   * is greater than the length of this String, -1 is returned.
+   *
+   * @param ch character to find
+   * @param fromIndex index to start the search
+   * @return location (base 0) of the character, or -1 if not found
+   */
+  public native int indexOf(int ch, int fromIndex);
+
+  /**
+   * Finds the last instance of a character in this String.
+   *
+   * @param ch character to find
+   * @return location (base 0) of the character, or -1 if not found
+   */
+  public int lastIndexOf(int ch)
+  {
+    return lastIndexOf(ch, count - 1);
+  }
+
+  /**
+   * Finds the last instance of a character in this String, starting at
+   * a given index.  If starting index is greater than the maximum valid
+   * index, then the search begins at the end of this String.  If the
+   * starting index is less than zero, -1 is returned.
+   *
+   * @param ch character to find
+   * @param fromIndex index to start the search
+   * @return location (base 0) of the character, or -1 if not found
+   */
+  public native int lastIndexOf(int ch, int fromIndex);
+
+  /**
+   * Finds the first instance of a String in this String.
+   *
+   * @param str String to find
+   * @return location (base 0) of the String, or -1 if not found
+   * @throws NullPointerException if str is null
+   */
+  public int indexOf(String str)
+  {
+    return indexOf(str, 0);
+  }
+
+  /**
+   * Finds the first instance of a String in this String, starting at
+   * a given index.  If starting index is less than 0, the search
+   * starts at the beginning of this String.  If the starting index
+   * is greater than the length of this String, -1 is returned.
+   *
+   * @param str String to find
+   * @param fromIndex index to start the search
+   * @return location (base 0) of the String, or -1 if not found
+   * @throws NullPointerException if str is null
+   */
+  public native int indexOf(String str, int fromIndex);
+
+  /**
+   * Finds the last instance of a String in this String.
+   *
+   * @param str String to find
+   * @return location (base 0) of the String, or -1 if not found
+   * @throws NullPointerException if str is null
+   */
+  public int lastIndexOf(String str)
+  {
+    return lastIndexOf(str, count - str.count);
+  }
+
+  /**
+   * Finds the last instance of a String in this String, starting at
+   * a given index.  If starting index is greater than the maximum valid
+   * index, then the search begins at the end of this String.  If the
+   * starting index is less than zero, -1 is returned.
+   *
+   * @param str String to find
+   * @param fromIndex index to start the search
+   * @return location (base 0) of the String, or -1 if not found
+   * @throws NullPointerException if str is null
+   */
+  public int lastIndexOf(String str, int fromIndex)
+  {
+    if (fromIndex >= count)
+      fromIndex = count - str.count;
+    for (;; --fromIndex)
+      {
+	if (fromIndex < 0)
+	  return -1;
+	if (startsWith(str, fromIndex))
+	  return fromIndex;
+      }
+  }
+
+  /**
+   * Creates a substring of this String, starting at a specified index
+   * and ending at the end of this String.
+   *
+   * @param begin index to start substring (base 0)
+   * @return new String which is a substring of this String
+   * @throws IndexOutOfBoundsException if begin < 0 || begin > length()
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   */
+  public String substring(int begin)
+  {
+    return substring(begin, count);
+  }
+
+  /**
+   * Creates a substring of this String, starting at a specified index
+   * and ending at one character before a specified index.
+   *
+   * @param begin index to start substring (inclusive, base 0)
+   * @param end index to end at (exclusive)
+   * @return new String which is a substring of this String
+   * @throws IndexOutOfBoundsException if begin < 0 || end > length()
+   *         || begin > end (while unspecified, this is a
+   *         StringIndexOutOfBoundsException)
+   */
+  public native String substring(int begin, int end);
+
+  /**
+   * Creates a substring of this String, starting at a specified index
+   * and ending at one character before a specified index. This behaves like
+   * <code>substring(begin, end)</code>.
+   *
+   * @param begin index to start substring (inclusive, base 0)
+   * @param end index to end at (exclusive)
+   * @return new String which is a substring of this String
+   * @throws IndexOutOfBoundsException if begin < 0 || end > length()
+   *         || begin > end
+   * @since 1.4
+   */
+  public CharSequence subSequence(int begin, int end)
+  {
+    return substring(begin, end);
+  }
+
+  /**
+   * Concatenates a String to this String. This results in a new string unless
+   * one of the two originals is "".
+   *
+   * @param str String to append to this String
+   * @return newly concatenated String
+   * @throws NullPointerException if str is null
+   */
+  public native String concat(String str);
+
+  /**
+   * Replaces every instance of a character in this String with a new
+   * character. If no replacements occur, this is returned.
+   *
+   * @param oldChar the old character to replace
+   * @param newChar the new character
+   * @return new String with all instances of oldChar replaced with newChar
+   */
+  public native String replace(char oldChar, char newChar);
+
+  /**
+   * Test if this String matches a regular expression. This is shorthand for
+   * <code>{@link Pattern}.matches(regex, this)</code>.
+   *
+   * @param regex the pattern to match
+   * @return true if the pattern matches
+   * @throws NullPointerException if regex is null
+   * @throws PatternSyntaxException if regex is invalid
+   * @see Pattern#matches(String, CharSequence)
+   * @since 1.4
+   */
+  public boolean matches(String regex)
+  {
+    return Pattern.matches(regex, this);
+  }
+
+  /**
+   * Replaces the first substring match of the regular expression with a
+   * given replacement. This is shorthand for <code>{@link Pattern}
+   *   .compile(regex).matcher(this).replaceFirst(replacement)</code>.
+   *
+   * @param regex the pattern to match
+   * @param replacement the replacement string
+   * @return the modified string
+   * @throws NullPointerException if regex or replacement is null
+   * @throws PatternSyntaxException if regex is invalid
+   * @see #replaceAll(String, String)
+   * @see Pattern#compile(String)
+   * @see Pattern#matcher(CharSequence)
+   * @see Matcher#replaceFirst(String)
+   * @since 1.4
+   */
+  public String replaceFirst(String regex, String replacement)
+  {
+    return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
+  }
+
+  /**
+   * Replaces all matching substrings of the regular expression with a
+   * given replacement. This is shorthand for <code>{@link Pattern}
+   *   .compile(regex).matcher(this).replaceAll(replacement)</code>.
+   *
+   * @param regex the pattern to match
+   * @param replacement the replacement string
+   * @return the modified string
+   * @throws NullPointerException if regex or replacement is null
+   * @throws PatternSyntaxException if regex is invalid
+   * @see #replaceFirst(String, String)
+   * @see Pattern#compile(String)
+   * @see Pattern#matcher(CharSequence)
+   * @see Matcher#replaceAll(String)
+   * @since 1.4
+   */
+  public String replaceAll(String regex, String replacement)
+  {
+    return Pattern.compile(regex).matcher(this).replaceAll(replacement);
+  }
+
+  /**
+   * Split this string around the matches of a regular expression. Each
+   * element of the returned array is the largest block of characters not
+   * terminated by the regular expression, in the order the matches are found.
+   *
+   * <p>The limit affects the length of the array. If it is positive, the
+   * array will contain at most n elements (n - 1 pattern matches). If
+   * negative, the array length is unlimited, but there can be trailing empty
+   * entries. if 0, the array length is unlimited, and trailing empty entries
+   * are discarded.
+   *
+   * <p>For example, splitting "boo:and:foo" yields:<br>
+   * <table border=0>
+   * <th><td>Regex</td> <td>Limit</td> <td>Result</td></th>
+   * <tr><td>":"</td>   <td>2</td>  <td>{ "boo", "and:foo" }</td></tr>
+   * <tr><td>":"</td>   <td>t</td>  <td>{ "boo", "and", "foo" }</td></tr>
+   * <tr><td>":"</td>   <td>-2</td> <td>{ "boo", "and", "foo" }</td></tr>
+   * <tr><td>"o"</td>   <td>5</td>  <td>{ "b", "", ":and:f", "", "" }</td></tr>
+   * <tr><td>"o"</td>   <td>-2</td> <td>{ "b", "", ":and:f", "", "" }</td></tr>
+   * <tr><td>"o"</td>   <td>0</td>  <td>{ "b", "", ":and:f" }</td></tr>
+   * </table>
+   *
+   * <p>This is shorthand for
+   * <code>{@link Pattern}.compile(regex).split(this, limit)</code>.
+   *
+   * @param regex the pattern to match
+   * @param limit the limit threshold
+   * @return the array of split strings
+   * @throws NullPointerException if regex or replacement is null
+   * @throws PatternSyntaxException if regex is invalid
+   * @see Pattern#compile(String)
+   * @see Pattern#split(CharSequence, int)
+   * @since 1.4
+   */
+  public String[] split(String regex, int limit)
+  {
+    return Pattern.compile(regex).split(this, limit);
+  }
+
+  /**
+   * Split this string around the matches of a regular expression. Each
+   * element of the returned array is the largest block of characters not
+   * terminated by the regular expression, in the order the matches are found.
+   * The array length is unlimited, and trailing empty entries are discarded,
+   * as though calling <code>split(regex, 0)</code>.
+   *
+   * @param regex the pattern to match
+   * @return the array of split strings
+   * @throws NullPointerException if regex or replacement is null
+   * @throws PatternSyntaxException if regex is invalid
+   * @see #split(String, int)
+   * @see Pattern#compile(String)
+   * @see Pattern#split(CharSequence, int)
+   * @since 1.4
+   */
+  public String[] split(String regex)
+  {
+    return Pattern.compile(regex).split(this, 0);
+  }
+
+  /**
+   * Lowercases this String according to a particular locale. This uses
+   * Unicode's special case mappings, as applied to the given Locale, so the
+   * resulting string may be a different length.
+   *
+   * @param loc locale to use
+   * @return new lowercased String, or this if no characters were lowercased
+   * @throws NullPointerException if loc is null
+   * @see #toUpperCase(Locale)
+   * @since 1.1
+   */
+  public native String toLowerCase(Locale locale);
+
+  /**
+   * Lowercases this String. This uses Unicode's special case mappings, as
+   * applied to the platform's default Locale, so the resulting string may
+   * be a different length.
+   *
+   * @return new lowercased String, or this if no characters were lowercased
+   * @see #toLowerCase(Locale)
+   * @see #toUpperCase()
+   */
+  public String toLowerCase()
+  {
+    // The JDK is a bit confused about what to do here.  If we pass in
+    // the default Locale then special Locale handling might be
+    // invoked.  However, the docs also say that Character.toLowerCase
+    // rules here.  We go with the latter.
+    return toLowerCase (null);
+  }
+
+  /**
+   * Uppercases this String according to a particular locale. This uses
+   * Unicode's special case mappings, as applied to the given Locale, so the
+   * resulting string may be a different length.
+   *
+   * @param loc locale to use
+   * @return new uppercased String, or this if no characters were uppercased
+   * @throws NullPointerException if loc is null
+   * @see #toLowerCase(Locale)
+   * @since 1.1
+   */
+  public native String toUpperCase(Locale locale);
+
+  /**
+   * Uppercases this String. This uses Unicode's special case mappings, as
+   * applied to the platform's default Locale, so the resulting string may
+   * be a different length.
+   *
+   * @return new uppercased String, or this if no characters were uppercased
+   * @see #toUpperCase(Locale)
+   * @see #toLowerCase()
+   */
+  public String toUpperCase()
+  {
+    // The JDK is a bit confused about what to do here.  If we pass in
+    // the default Locale then special Locale handling might be
+    // invoked.  However, the docs also say that Character.toLowerCase
+    // rules here.  We go with the latter.
+    return toUpperCase (null);
+  }
+
+  /**
+   * Trims all characters less than or equal to <code>'\u0020'</code>
+   * (<code>' '</code>) from the beginning and end of this String. This
+   * includes many, but not all, ASCII control characters, and all
+   * {@link Character#whitespace(char)}.
+   *
+   * @return new trimmed String, or this if nothing trimmed
+   */
+  public native String trim();
+
+  /**
+   * Returns this, as it is already a String!
+   *
+   * @return this
+   */
+  public String toString()
+  {
+    return this;
+  }
+
+  /**
+   * Copies the contents of this String into a character array. Subsequent
+   * changes to the array do not affect the String.
+   *
+   * @return character array copying the String
+   */
+  public native char[] toCharArray();
+
+  /**
+   * Returns a String representation of an Object. This is "null" if the
+   * object is null, otherwise it is <code>obj.toString()</code> (which
+   * can be null).
+   *
+   * @param obj the Object
+   * @return the string conversion of obj
+   */
+  public static String valueOf(Object obj)
+  {
+    return obj == null ? "null" : obj.toString();
+  }
+
+  /**
+   * Returns a String representation of a character array. Subsequent
+   * changes to the array do not affect the String.
+   *
+   * @param data the character array
+   * @return a String containing the same character sequence as data
+   * @throws NullPointerException if data is null
+   * @see #valueOf(char[], int, int)
+   * @see #String(char[])
+   */
+  public static String valueOf(char[] data)
+  {
+    return valueOf (data, 0, data.length);
+  }
+
+  /**
+   * Returns a String representing the character sequence of the char array,
+   * starting at the specified offset, and copying chars up to the specified
+   * count. Subsequent changes to the array do not affect the String.
+   *
+   * @param data character array
+   * @param offset position (base 0) to start copying out of data
+   * @param count the number of characters from data to copy
+   * @return String containing the chars from data[offset..offset+count]
+   * @throws NullPointerException if data is null
+   * @throws IndexOutOfBoundsException if (offset < 0 || count < 0
+   *         || offset + count > data.length)
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   * @see #String(char[], int, int)
+   */
+  public static native String valueOf(char[] data, int offset, int count);
+
+  /**
+   * Returns a String representing the character sequence of the char array,
+   * starting at the specified offset, and copying chars up to the specified
+   * count. Subsequent changes to the array do not affect the String.
+   *
+   * @param data character array
+   * @param offset position (base 0) to start copying out of data
+   * @param count the number of characters from data to copy
+   * @return String containing the chars from data[offset..offset+count]
+   * @throws NullPointerException if data is null
+   * @throws IndexOutOfBoundsException if (offset < 0 || count < 0
+   *         || offset + count > data.length)
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   * @see #String(char[], int, int)
+   */
+  public static String copyValueOf(char[] data, int offset, int count)
+  {
+    String r = new String ();
+    r.init(data, offset, count, false);
+    return r;
+  }
+
+  /**
+   * Returns a String representation of a character array. Subsequent
+   * changes to the array do not affect the String.
+   *
+   * @param data the character array
+   * @return a String containing the same character sequence as data
+   * @throws NullPointerException if data is null
+   * @see #copyValueOf(char[], int, int)
+   * @see #String(char[])
+   */
+  public static String copyValueOf(char[] data)
+  {
+    return copyValueOf (data, 0, data.length);
+  }
+
+  /**
+   * Returns a String representing a boolean.
+   *
+   * @param b the boolean
+   * @return "true" if b is true, else "false"
+   */
+  public static String valueOf(boolean b)
+  {
+    return b ? "true" : "false";
+  }
+
+  /**
+   * Returns a String representing a character.
+   *
+   * @param c the character
+   * @return String containing the single character c
+   */
+  public static native String valueOf(char c);
+
+  /**
+   * Returns a String representing an integer.
+   *
+   * @param i the integer
+   * @return String containing the integer in base 10
+   * @see Integer#toString(int)
+   */
+  public static native String valueOf(int i);
+
+  /**
+   * Returns a String representing a long.
+   *
+   * @param l the long
+   * @return String containing the long in base 10
+   * @see Long#toString(long)
+   */
+  public static String valueOf(long l)
+  {
+    return Long.toString(l);
+  }
+
+  /**
+   * Returns a String representing a float.
+   *
+   * @param f the float
+   * @return String containing the float
+   * @see Float#toString(float)
+   */
+  public static String valueOf(float f)
+  {
+    return Float.toString(f);
+  }
+
+  /**
+   * Returns a String representing a double.
+   *
+   * @param d the double
+   * @return String containing the double
+   * @see Double#toString(double)
+   */
+  public static String valueOf(double d)
+  {
+    return Double.toString(d);
+  }
+
+  /**
+   * 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.
+   *
+   * @return the interned String
+   */
+  public native String intern();
+
+  /**
+   * Return the number of code points between two indices in the
+   * <code>String</code>.  An unpaired surrogate counts as a
+   * code point for this purpose.  Characters outside the indicated
+   * range are not examined, even if the range ends in the middle of a
+   * surrogate pair.
+   *
+   * @param start the starting index
+   * @param end one past the ending index
+   * @return the number of code points
+   * @since 1.5
+   */
+  public synchronized int codePointCount(int start, int end)
+  {
+    if (start < 0 || end > count || start > end)
+      throw new StringIndexOutOfBoundsException();
+
+    int count = 0;
+    while (start < end)
+      {
+	char base = charAt(start);
+	if (base < Character.MIN_HIGH_SURROGATE
+	    || base > Character.MAX_HIGH_SURROGATE
+	    || start == end
+	    || start == count
+	    || charAt(start + 1) < Character.MIN_LOW_SURROGATE
+	    || charAt(start + 1) > Character.MAX_LOW_SURROGATE)
+	  {
+	    // Nothing.
+	  }
+	else
+	  {
+	    // Surrogate pair.
+	    ++start;
+	  }
+	++start;
+	++count;
+      }
+    return count;
+  }
+
+  /**
+   * Returns true iff this String contains the sequence of Characters
+   * described in s.
+   * @param s the CharSequence
+   * @return true iff this String contains s
+   *
+   * @since 1.5
+   */
+  public boolean contains (CharSequence s)
+  {
+    return this.indexOf(s.toString()) != -1;
+  }
+
+  /**
+   * Returns a string that is this string with all instances of the sequence
+   * represented by <code>target</code> replaced by the sequence in 
+   * <code>replacement</code>.
+   * @param target the sequence to be replaced
+   * @param replacement the sequence used as the replacement
+   * @return the string constructed as above
+   */
+  public String replace (CharSequence target, CharSequence replacement)
+  {
+    String targetString = target.toString();
+    String replaceString = replacement.toString();
+    int targetLength = target.length();
+    int replaceLength = replacement.length();
+    
+    int startPos = this.indexOf(targetString);
+    StringBuilder result = new StringBuilder(this);    
+    while (startPos != -1)
+      {
+        // Replace the target with the replacement
+        result.replace(startPos, startPos + targetLength, replaceString);
+
+        // Search for a new occurrence of the target
+        startPos = result.indexOf(targetString, startPos + replaceLength);
+      }
+    return result.toString();
+  }
+
+
+  private native void init(char[] chars, int offset, int count,
+			   boolean dont_copy);
+  private native void init(byte[] chars, int hibyte, int offset, int count);
+  private native void init(byte[] chars, int offset, int count, String enc)
+    throws UnsupportedEncodingException;
+  private native void init(gnu.gcj.runtime.StringBuffer buffer);
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/StringBuffer.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/StringBuffer.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/StringBuffer.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/StringBuffer.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1178 @@
+/* StringBuffer.java -- Growable strings
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.io.Serializable;
+
+/**
+ * <code>StringBuffer</code> represents a changeable <code>String</code>.
+ * It provides the operations required to modify the
+ * <code>StringBuffer</code>, including insert, replace, delete, append,
+ * and reverse. It is thread-safe; meaning that all modifications to a buffer
+ * are in synchronized methods.
+ *
+ * <p><code>StringBuffer</code>s are variable-length in nature, so even if
+ * you initialize them to a certain size, they can still grow larger than
+ * that. <em>Capacity</em> indicates the number of characters the
+ * <code>StringBuffer</code> can have in it before it has to grow (growing
+ * the char array is an expensive operation involving <code>new</code>).
+ *
+ * <p>Incidentally, compilers often implement the String operator "+"
+ * by using a <code>StringBuffer</code> operation:<br>
+ * <code>a + b</code><br>
+ * is the same as<br>
+ * <code>new StringBuffer().append(a).append(b).toString()</code>.
+ *
+ * <p>Classpath's StringBuffer is capable of sharing memory with Strings for
+ * efficiency.  This will help when a StringBuffer is converted to a String
+ * and the StringBuffer is not changed after that (quite common when performing
+ * string concatenation).
+ *
+ * @author Paul Fisher
+ * @author John Keiser
+ * @author Tom Tromey
+ * @author Eric Blake (ebb9 at email.byu.edu)
+ * @see String
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public final class StringBuffer implements Serializable, CharSequence
+{
+  /**
+   * Compatible with JDK 1.0+.
+   */
+  private static final long serialVersionUID = 3388685877147921107L;
+
+  /**
+   * Index of next available character (and thus the size of the current
+   * string contents).  Note that this has permissions set this way so that
+   * String can get the value.
+   *
+   * @serial the number of characters in the buffer
+   */
+  int count;
+
+  /**
+   * The buffer.  Note that this has permissions set this way so that String
+   * can get the value.
+   *
+   * @serial the buffer
+   */
+  char[] value;
+
+  /**
+   * True if the buffer is shared with another object (StringBuffer or
+   * String); this means the buffer must be copied before writing to it again.
+   * Note that this has permissions set this way so that String can get the
+   * value.
+   *
+   * @serial whether the buffer is shared
+   */
+  boolean shared;
+
+  /**
+   * The default capacity of a buffer.
+   */
+  private static final int DEFAULT_CAPACITY = 16;
+
+  /**
+   * Create a new StringBuffer with default capacity 16.
+   */
+  public StringBuffer()
+  {
+    this(DEFAULT_CAPACITY);
+  }
+
+  /**
+   * Create an empty <code>StringBuffer</code> with the specified initial
+   * capacity.
+   *
+   * @param capacity the initial capacity
+   * @throws NegativeArraySizeException if capacity is negative
+   */
+  public StringBuffer(int capacity)
+  {
+    value = new char[capacity];
+  }
+
+  /**
+   * Create a new <code>StringBuffer</code> with the characters in the
+   * specified <code>String</code>. Initial capacity will be the size of the
+   * String plus 16.
+   *
+   * @param str the <code>String</code> to convert
+   * @throws NullPointerException if str is null
+   */
+  public StringBuffer(String str)
+  {
+    // Unfortunately, because the size is 16 larger, we cannot share.
+    count = str.count;
+    value = new char[count + DEFAULT_CAPACITY];
+    str.getChars(0, count, value, 0);
+  }
+
+  /**
+   * Create a new <code>StringBuffer</code> with the characters from the
+   * specified <code>CharSequence</code>. Initial capacity will be the
+   * size of the CharSequence plus 16.
+   *
+   * @param sequence the <code>String</code> to convert
+   * @throws NullPointerException if str is null
+   *
+   * @since 1.5
+   */
+  public StringBuffer(CharSequence sequence)
+  {
+    count = Math.max(0, sequence.length());
+    value = new char[count + DEFAULT_CAPACITY];
+    for (int i = 0; i < count; ++i)
+      value[i] = sequence.charAt(i);
+  }
+
+  /**
+   * Get the length of the <code>String</code> this <code>StringBuffer</code>
+   * would create. Not to be confused with the <em>capacity</em> of the
+   * <code>StringBuffer</code>.
+   *
+   * @return the length of this <code>StringBuffer</code>
+   * @see #capacity()
+   * @see #setLength(int)
+   */
+  public synchronized int length()
+  {
+    return count;
+  }
+
+  /**
+   * Get the total number of characters this <code>StringBuffer</code> can
+   * support before it must be grown.  Not to be confused with <em>length</em>.
+   *
+   * @return the capacity of this <code>StringBuffer</code>
+   * @see #length()
+   * @see #ensureCapacity(int)
+   */
+  public synchronized int capacity()
+  {
+    return value.length;
+  }
+
+  /**
+   * Increase the capacity of this <code>StringBuffer</code>. This will
+   * ensure that an expensive growing operation will not occur until
+   * <code>minimumCapacity</code> is reached. The buffer is grown to the
+   * larger of <code>minimumCapacity</code> and
+   * <code>capacity() * 2 + 2</code>, if it is not already large enough.
+   *
+   * @param minimumCapacity the new capacity
+   * @see #capacity()
+   */
+  public synchronized void ensureCapacity(int minimumCapacity)
+  {
+    ensureCapacity_unsynchronized(minimumCapacity);
+  }
+
+  /**
+   * Set the length of this StringBuffer. If the new length is greater than
+   * the current length, all the new characters are set to '\0'. If the new
+   * length is less than the current length, the first <code>newLength</code>
+   * characters of the old array will be preserved, and the remaining
+   * characters are truncated.
+   *
+   * @param newLength the new length
+   * @throws IndexOutOfBoundsException if the new length is negative
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   * @see #length()
+   */
+  public synchronized void setLength(int newLength)
+  {
+    if (newLength < 0)
+      throw new StringIndexOutOfBoundsException(newLength);
+
+    int valueLength = value.length;
+
+    /* Always call ensureCapacity_unsynchronized in order to preserve
+       copy-on-write semantics.  */
+    ensureCapacity_unsynchronized(newLength);
+
+    if (newLength < valueLength)
+      {
+        /* If the StringBuffer's value just grew, then we know that
+           value is newly allocated and the region between count and
+           newLength is filled with '\0'.  */
+	count = newLength;
+      }
+    else
+      {
+	/* The StringBuffer's value doesn't need to grow.  However,
+	   we should clear out any cruft that may exist.  */
+	while (count < newLength)
+          value[count++] = '\0';
+      }
+  }
+
+  /**
+   * Get the character at the specified index.
+   *
+   * @param index the index of the character to get, starting at 0
+   * @return the character at the specified index
+   * @throws IndexOutOfBoundsException if index is negative or >= length()
+   */
+  public synchronized char charAt(int index)
+  {
+    if (index < 0 || index >= count)
+      throw new StringIndexOutOfBoundsException(index);
+    return value[index];
+  }
+
+  /**
+   * Get the code point at the specified index.  This is like #charAt(int),
+   * but if the character is the start of a surrogate pair, and the
+   * following character completes the pair, then the corresponding
+   * supplementary code point is returned.
+   * @param index the index of the codepoint to get, starting at 0
+   * @return the codepoint at the specified index
+   * @throws IndexOutOfBoundsException if index is negative or >= length()
+   * @since 1.5
+   */
+  public synchronized int codePointAt(int index)
+  {
+    return Character.codePointAt(value, index, count);
+  }
+
+  /**
+   * Get the code point before the specified index.  This is like
+   * #codePointAt(int), but checks the characters at <code>index-1</code> and
+   * <code>index-2</code> to see if they form a supplementary code point.
+   * @param index the index just past the codepoint to get, starting at 0
+   * @return the codepoint at the specified index
+   * @throws IndexOutOfBoundsException if index is negative or >= length()
+   * @since 1.5
+   */
+  public synchronized int codePointBefore(int index)
+  {
+    // Character.codePointBefore() doesn't perform this check.  We
+    // could use the CharSequence overload, but this is just as easy.
+    if (index >= count)
+      throw new IndexOutOfBoundsException();
+    return Character.codePointBefore(value, index, 1);
+  }
+
+  /**
+   * Get the specified array of characters. <code>srcOffset - srcEnd</code>
+   * characters will be copied into the array you pass in.
+   *
+   * @param srcOffset the index to start copying from (inclusive)
+   * @param srcEnd the index to stop copying from (exclusive)
+   * @param dst the array to copy into
+   * @param dstOffset the index to start copying into
+   * @throws NullPointerException if dst is null
+   * @throws IndexOutOfBoundsException if any source or target indices are
+   *         out of range (while unspecified, source problems cause a
+   *         StringIndexOutOfBoundsException, and dest problems cause an
+   *         ArrayIndexOutOfBoundsException)
+   * @see System#arraycopy(Object, int, Object, int, int)
+   */
+  public synchronized void getChars(int srcOffset, int srcEnd,
+                                    char[] dst, int dstOffset)
+  {
+    if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset)
+      throw new StringIndexOutOfBoundsException();
+    System.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset);
+  }
+
+  /**
+   * Set the character at the specified index.
+   *
+   * @param index the index of the character to set starting at 0
+   * @param ch the value to set that character to
+   * @throws IndexOutOfBoundsException if index is negative or >= length()
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   */
+  public synchronized void setCharAt(int index, char ch)
+  {
+    if (index < 0 || index >= count)
+      throw new StringIndexOutOfBoundsException(index);
+    // Call ensureCapacity to enforce copy-on-write.
+    ensureCapacity_unsynchronized(count);
+    value[index] = ch;
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param obj the <code>Object</code> to convert and append
+   * @return this <code>StringBuffer</code>
+   * @see String#valueOf(Object)
+   * @see #append(String)
+   */
+  public StringBuffer append(Object obj)
+  {
+    return append(obj == null ? "null" : obj.toString());
+  }
+
+  /**
+   * Append the <code>String</code> to this <code>StringBuffer</code>. If
+   * str is null, the String "null" is appended.
+   *
+   * @param str the <code>String</code> to append
+   * @return this <code>StringBuffer</code>
+   */
+  public synchronized StringBuffer append(String str)
+  {
+    if (str == null)
+      str = "null";
+    int len = str.count;
+    ensureCapacity_unsynchronized(count + len);
+    str.getChars(0, len, value, count);
+    count += len;
+    return this;
+  }
+
+  /**
+   * Append the <code>StringBuffer</code> value of the argument to this
+   * <code>StringBuffer</code>. This behaves the same as
+   * <code>append((Object) stringBuffer)</code>, except it is more efficient.
+   *
+   * @param stringBuffer the <code>StringBuffer</code> to convert and append
+   * @return this <code>StringBuffer</code>
+   * @see #append(Object)
+   * @since 1.4
+   */
+  public synchronized StringBuffer append(StringBuffer stringBuffer)
+  {
+    if (stringBuffer == null)
+      return append("null");
+    synchronized (stringBuffer)
+      {
+        int len = stringBuffer.count;
+        ensureCapacity_unsynchronized(count + len);
+        System.arraycopy(stringBuffer.value, 0, value, count, len);
+        count += len;
+      }
+    return this;
+  }
+
+  /**
+   * Append the <code>CharSequence</code> value of the argument to this
+   * <code>StringBuffer</code>.
+   *
+   * @param sequence the <code>CharSequence</code> to append
+   * @return this <code>StringBuffer</code>
+   * @see #append(Object)
+   * @since 1.5
+   */
+  public synchronized StringBuffer append(CharSequence sequence)
+  {
+    if (sequence == null)
+      sequence = "null";
+    return append(sequence, 0, sequence.length());
+  }
+
+  /**
+   * Append the specified subsequence of the <code>CharSequence</code>
+   * argument to this <code>StringBuffer</code>.
+   *
+   * @param sequence the <code>CharSequence</code> to append
+   * @param start the starting index
+   * @param end one past the ending index
+   * @return this <code>StringBuffer</code>
+   * @see #append(Object)
+   * @since 1.5
+   */
+  public synchronized StringBuffer append(CharSequence sequence,
+					  int start, int end)
+  {
+    if (sequence == null)
+      sequence = "null";
+    if (start < 0 || end < 0 || start > end || end > sequence.length())
+      throw new IndexOutOfBoundsException();
+    ensureCapacity_unsynchronized(this.count + end - start);
+    for (int i = start; i < end; ++i)
+      value[count++] = sequence.charAt(i);
+    return this;
+  }
+
+  /**
+   * Append the <code>char</code> array to this <code>StringBuffer</code>.
+   * This is similar (but more efficient) than
+   * <code>append(new String(data))</code>, except in the case of null.
+   *
+   * @param data the <code>char[]</code> to append
+   * @return this <code>StringBuffer</code>
+   * @throws NullPointerException if <code>str</code> is <code>null</code>
+   * @see #append(char[], int, int)
+   */
+  public StringBuffer append(char[] data)
+  {
+    return append(data, 0, data.length);
+  }
+
+  /**
+   * Append part of the <code>char</code> array to this
+   * <code>StringBuffer</code>. This is similar (but more efficient) than
+   * <code>append(new String(data, offset, count))</code>, except in the case
+   * of null.
+   *
+   * @param data the <code>char[]</code> to append
+   * @param offset the start location in <code>str</code>
+   * @param count the number of characters to get from <code>str</code>
+   * @return this <code>StringBuffer</code>
+   * @throws NullPointerException if <code>str</code> is <code>null</code>
+   * @throws IndexOutOfBoundsException if offset or count is out of range
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   */
+  public synchronized StringBuffer append(char[] data, int offset, int count)
+  {
+    if (offset < 0 || count < 0 || offset > data.length - count)
+      throw new StringIndexOutOfBoundsException();
+    ensureCapacity_unsynchronized(this.count + count);
+    System.arraycopy(data, offset, value, this.count, count);
+    this.count += count;
+    return this;
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param bool the <code>boolean</code> to convert and append
+   * @return this <code>StringBuffer</code>
+   * @see String#valueOf(boolean)
+   */
+  public StringBuffer append(boolean bool)
+  {
+    return append(bool ? "true" : "false");
+  }
+
+  /**
+   * Append the <code>char</code> to this <code>StringBuffer</code>.
+   *
+   * @param ch the <code>char</code> to append
+   * @return this <code>StringBuffer</code>
+   */
+  public synchronized StringBuffer append(char ch)
+  {
+    ensureCapacity_unsynchronized(count + 1);
+    value[count++] = ch;
+    return this;
+  }
+
+  /**
+   * Append the code point to this <code>StringBuffer</code>.
+   * This is like #append(char), but will append two characters
+   * if a supplementary code point is given.
+   *
+   * @param code the code point to append
+   * @return this <code>StringBuffer</code>
+   * @see Character#toChars(int, char[], int)
+   * @since 1.5
+   */
+  public synchronized StringBuffer appendCodePoint(int code)
+  {
+    int len = Character.charCount(code);
+    ensureCapacity_unsynchronized(count + len);
+    Character.toChars(code, value, count);
+    count += len;
+    return this;
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param inum the <code>int</code> to convert and append
+   * @return this <code>StringBuffer</code>
+   * @see String#valueOf(int)
+   */
+  // GCJ LOCAL: this is native for efficiency.
+  public native StringBuffer append (int inum);
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param lnum the <code>long</code> to convert and append
+   * @return this <code>StringBuffer</code>
+   * @see String#valueOf(long)
+   */
+  public StringBuffer append(long lnum)
+  {
+    return append(Long.toString(lnum, 10));
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param fnum the <code>float</code> to convert and append
+   * @return this <code>StringBuffer</code>
+   * @see String#valueOf(float)
+   */
+  public StringBuffer append(float fnum)
+  {
+    return append(Float.toString(fnum));
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param dnum the <code>double</code> to convert and append
+   * @return this <code>StringBuffer</code>
+   * @see String#valueOf(double)
+   */
+  public StringBuffer append(double dnum)
+  {
+    return append(Double.toString(dnum));
+  }
+
+  /**
+   * Delete characters from this <code>StringBuffer</code>.
+   * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
+   * harmless for end to be larger than length().
+   *
+   * @param start the first character to delete
+   * @param end the index after the last character to delete
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+   * @since 1.2
+   */
+  public synchronized StringBuffer delete(int start, int end)
+  {
+    if (start < 0 || start > count || start > end)
+      throw new StringIndexOutOfBoundsException(start);
+    if (end > count)
+      end = count;
+    // This will unshare if required.
+    ensureCapacity_unsynchronized(count);
+    if (count - end != 0)
+      System.arraycopy(value, end, value, start, count - end);
+    count -= end - start;
+    return this;
+  }
+
+  /**
+   * Delete a character from this <code>StringBuffer</code>.
+   *
+   * @param index the index of the character to delete
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if index is out of bounds
+   * @since 1.2
+   */
+  public StringBuffer deleteCharAt(int index)
+  {
+    return delete(index, index + 1);
+  }
+
+  /**
+   * Replace characters between index <code>start</code> (inclusive) and
+   * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
+   * is larger than the size of this StringBuffer, all characters after
+   * <code>start</code> are replaced.
+   *
+   * @param start the beginning index of characters to delete (inclusive)
+   * @param end the ending index of characters to delete (exclusive)
+   * @param str the new <code>String</code> to insert
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+   * @throws NullPointerException if str is null
+   * @since 1.2
+   */
+  public synchronized StringBuffer replace(int start, int end, String str)
+  {
+    if (start < 0 || start > count || start > end)
+      throw new StringIndexOutOfBoundsException(start);
+
+    int len = str.count;
+    // Calculate the difference in 'count' after the replace.
+    int delta = len - (end > count ? count : end) + start;
+    ensureCapacity_unsynchronized(count + delta);
+
+    if (delta != 0 && end < count)
+      System.arraycopy(value, end, value, end + delta, count - end);
+
+    str.getChars(0, len, value, start);
+    count += delta;
+    return this;
+  }
+
+  /**
+   * Creates a substring of this StringBuffer, starting at a specified index
+   * and ending at the end of this StringBuffer.
+   *
+   * @param beginIndex index to start substring (base 0)
+   * @return new String which is a substring of this StringBuffer
+   * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds
+   * @see #substring(int, int)
+   * @since 1.2
+   */
+  public String substring(int beginIndex)
+  {
+    return substring(beginIndex, count);
+  }
+
+  /**
+   * Creates a substring of this StringBuffer, starting at a specified index
+   * and ending at one character before a specified index. This is implemented
+   * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy
+   * the CharSequence interface.
+   *
+   * @param beginIndex index to start at (inclusive, base 0)
+   * @param endIndex index to end at (exclusive)
+   * @return new String which is a substring of this StringBuffer
+   * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of
+   *         bounds
+   * @see #substring(int, int)
+   * @since 1.4
+   */
+  public CharSequence subSequence(int beginIndex, int endIndex)
+  {
+    return substring(beginIndex, endIndex);
+  }
+
+  /**
+   * Creates a substring of this StringBuffer, starting at a specified index
+   * and ending at one character before a specified index.
+   *
+   * @param beginIndex index to start at (inclusive, base 0)
+   * @param endIndex index to end at (exclusive)
+   * @return new String which is a substring of this StringBuffer
+   * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out
+   *         of bounds
+   * @since 1.2
+   */
+  public synchronized String substring(int beginIndex, int endIndex)
+  {
+    int len = endIndex - beginIndex;
+    if (beginIndex < 0 || endIndex > count || endIndex < beginIndex)
+      throw new StringIndexOutOfBoundsException();
+    if (len == 0)
+      return "";
+    // Don't copy unless substring is smaller than 1/4 of the buffer.
+    boolean share_buffer = ((len << 2) >= value.length);
+    if (share_buffer)
+      this.shared = true;
+    // Package constructor avoids an array copy.
+    return new String(value, beginIndex, len, share_buffer);
+  }
+
+  /**
+   * Insert a subarray of the <code>char[]</code> argument into this
+   * <code>StringBuffer</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param str the <code>char[]</code> to insert
+   * @param str_offset the index in <code>str</code> to start inserting from
+   * @param len the number of characters to insert
+   * @return this <code>StringBuffer</code>
+   * @throws NullPointerException if <code>str</code> is <code>null</code>
+   * @throws StringIndexOutOfBoundsException if any index is out of bounds
+   * @since 1.2
+   */
+  public synchronized StringBuffer insert(int offset,
+                                          char[] str, int str_offset, int len)
+  {
+    if (offset < 0 || offset > count || len < 0
+        || str_offset < 0 || str_offset > str.length - len)
+      throw new StringIndexOutOfBoundsException();
+    ensureCapacity_unsynchronized(count + len);
+    System.arraycopy(value, offset, value, offset + len, count - offset);
+    System.arraycopy(str, str_offset, value, offset, len);
+    count += len;
+    return this;
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param obj the <code>Object</code> to convert and insert
+   * @return this <code>StringBuffer</code>
+   * @exception StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(Object)
+   */
+  public StringBuffer insert(int offset, Object obj)
+  {
+    return insert(offset, obj == null ? "null" : obj.toString());
+  }
+
+  /**
+   * Insert the <code>String</code> argument into this
+   * <code>StringBuffer</code>. If str is null, the String "null" is used
+   * instead.
+   *
+   * @param offset the place to insert in this buffer
+   * @param str the <code>String</code> to insert
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   */
+  public synchronized StringBuffer insert(int offset, String str)
+  {
+    if (offset < 0 || offset > count)
+      throw new StringIndexOutOfBoundsException(offset);
+    if (str == null)
+      str = "null";
+    int len = str.count;
+    ensureCapacity_unsynchronized(count + len);
+    System.arraycopy(value, offset, value, offset + len, count - offset);
+    str.getChars(0, len, value, offset);
+    count += len;
+    return this;
+  }
+
+  /**
+   * Insert the <code>CharSequence</code> argument into this
+   * <code>StringBuffer</code>.  If the sequence is null, the String
+   * "null" is used instead.
+   *
+   * @param offset the place to insert in this buffer
+   * @param sequence the <code>CharSequence</code> to insert
+   * @return this <code>StringBuffer</code>
+   * @throws IndexOutOfBoundsException if offset is out of bounds
+   * @since 1.5
+   */
+  public synchronized StringBuffer insert(int offset, CharSequence sequence)
+  {
+    if (sequence == null)
+      sequence = "null";
+    return insert(offset, sequence, 0, sequence.length());
+  }
+
+  /**
+   * Insert a subsequence of the <code>CharSequence</code> argument into this
+   * <code>StringBuffer</code>.  If the sequence is null, the String
+   * "null" is used instead.
+   *
+   * @param offset the place to insert in this buffer
+   * @param sequence the <code>CharSequence</code> to insert
+   * @param start the starting index of the subsequence
+   * @param end one past the ending index of the subsequence
+   * @return this <code>StringBuffer</code>
+   * @throws IndexOutOfBoundsException if offset, start,
+   * or end are out of bounds
+   * @since 1.5
+   */
+  public synchronized StringBuffer insert(int offset, CharSequence sequence,
+					  int start, int end)
+  {
+    if (sequence == null)
+      sequence = "null";
+    if (start < 0 || end < 0 || start > end || end > sequence.length())
+      throw new IndexOutOfBoundsException();
+    int len = end - start;
+    ensureCapacity_unsynchronized(count + len);
+    System.arraycopy(value, offset, value, offset + len, count - offset);
+    for (int i = start; i < end; ++i)
+      value[offset++] = sequence.charAt(i);
+    count += len;
+    return this;
+  }
+
+  /**
+   * Insert the <code>char[]</code> argument into this
+   * <code>StringBuffer</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param data the <code>char[]</code> to insert
+   * @return this <code>StringBuffer</code>
+   * @throws NullPointerException if <code>data</code> is <code>null</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see #insert(int, char[], int, int)
+   */
+  public StringBuffer insert(int offset, char[] data)
+  {
+    return insert(offset, data, 0, data.length);
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param bool the <code>boolean</code> to convert and insert
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(boolean)
+   */
+  public StringBuffer insert(int offset, boolean bool)
+  {
+    return insert(offset, bool ? "true" : "false");
+  }
+
+  /**
+   * Insert the <code>char</code> argument into this <code>StringBuffer</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param ch the <code>char</code> to insert
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   */
+  public synchronized StringBuffer insert(int offset, char ch)
+  {
+    if (offset < 0 || offset > count)
+      throw new StringIndexOutOfBoundsException(offset);
+    ensureCapacity_unsynchronized(count + 1);
+    System.arraycopy(value, offset, value, offset + 1, count - offset);
+    value[offset] = ch;
+    count++;
+    return this;
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param inum the <code>int</code> to convert and insert
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(int)
+   */
+  public StringBuffer insert(int offset, int inum)
+  {
+    return insert(offset, String.valueOf(inum));
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param lnum the <code>long</code> to convert and insert
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(long)
+   */
+  public StringBuffer insert(int offset, long lnum)
+  {
+    return insert(offset, Long.toString(lnum, 10));
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param fnum the <code>float</code> to convert and insert
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(float)
+   */
+  public StringBuffer insert(int offset, float fnum)
+  {
+    return insert(offset, Float.toString(fnum));
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param dnum the <code>double</code> to convert and insert
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(double)
+   */
+  public StringBuffer insert(int offset, double dnum)
+  {
+    return insert(offset, Double.toString(dnum));
+  }
+
+  /**
+   * Finds the first instance of a substring in this StringBuffer.
+   *
+   * @param str String to find
+   * @return location (base 0) of the String, or -1 if not found
+   * @throws NullPointerException if str is null
+   * @see #indexOf(String, int)
+   * @since 1.4
+   */
+  public int indexOf(String str)
+  {
+    return indexOf(str, 0);
+  }
+
+  /**
+   * Finds the first instance of a String in this StringBuffer, starting at
+   * a given index.  If starting index is less than 0, the search starts at
+   * the beginning of this String.  If the starting index is greater than the
+   * length of this String, or the substring is not found, -1 is returned.
+   *
+   * @param str String to find
+   * @param fromIndex index to start the search
+   * @return location (base 0) of the String, or -1 if not found
+   * @throws NullPointerException if str is null
+   * @since 1.4
+   */
+  public synchronized int indexOf(String str, int fromIndex)
+  {
+    if (fromIndex < 0)
+      fromIndex = 0;
+    int limit = count - str.count;
+    for ( ; fromIndex <= limit; fromIndex++)
+      if (regionMatches(fromIndex, str))
+        return fromIndex;
+    return -1;
+  }
+
+  /**
+   * Finds the last instance of a substring in this StringBuffer.
+   *
+   * @param str String to find
+   * @return location (base 0) of the String, or -1 if not found
+   * @throws NullPointerException if str is null
+   * @see #lastIndexOf(String, int)
+   * @since 1.4
+   */
+  public int lastIndexOf(String str)
+  {
+    return lastIndexOf(str, count - str.count);
+  }
+
+  /**
+   * Finds the last instance of a String in this StringBuffer, starting at a
+   * given index.  If starting index is greater than the maximum valid index,
+   * then the search begins at the end of this String.  If the starting index
+   * is less than zero, or the substring is not found, -1 is returned.
+   *
+   * @param str String to find
+   * @param fromIndex index to start the search
+   * @return location (base 0) of the String, or -1 if not found
+   * @throws NullPointerException if str is null
+   * @since 1.4
+   */
+  public synchronized int lastIndexOf(String str, int fromIndex)
+  {
+    fromIndex = Math.min(fromIndex, count - str.count);
+    for ( ; fromIndex >= 0; fromIndex--)
+      if (regionMatches(fromIndex, str))
+        return fromIndex;
+    return -1;
+  }
+
+  /**
+   * Reverse the characters in this StringBuffer. The same sequence of
+   * characters exists, but in the reverse index ordering.
+   *
+   * @return this <code>StringBuffer</code>
+   */
+  public synchronized StringBuffer reverse()
+  {
+    // Call ensureCapacity to enforce copy-on-write.
+    ensureCapacity_unsynchronized(count);
+    for (int i = count >> 1, j = count - i; --i >= 0; ++j)
+      {
+        char c = value[i];
+        value[i] = value[j];
+        value[j] = c;
+      }
+    return this;
+  }
+
+  /**
+   * Convert this <code>StringBuffer</code> to a <code>String</code>. The
+   * String is composed of the characters currently in this StringBuffer. Note
+   * that the result is a copy, and that future modifications to this buffer
+   * do not affect the String.
+   *
+   * @return the characters in this StringBuffer
+   */
+  public String toString()
+  {
+    // The string will set this.shared = true.
+    return new String(this);
+  }
+
+  /**
+   * This may reduce the amount of memory used by the StringBuffer,
+   * by resizing the internal array to remove unused space.  However,
+   * this method is not required to resize, so this behavior cannot
+   * be relied upon.
+   * @since 1.5
+   */
+  public synchronized void trimToSize()
+  {
+    int wouldSave = value.length - count;
+    // Some random heuristics: if we save less than 20 characters, who
+    // cares.
+    if (wouldSave < 20)
+      return;
+    // If we save more than 200 characters, shrink.
+    // If we save more than 1/4 of the buffer, shrink.
+    if (wouldSave > 200 || wouldSave * 4 > value.length)
+      {
+	char[] newValue = new char[count];
+	System.arraycopy(value, 0, newValue, 0, count);
+	value = newValue;
+      }
+  }
+
+  /**
+   * Return the number of code points between two indices in the
+   * <code>StringBuffer</code>.  An unpaired surrogate counts as a
+   * code point for this purpose.  Characters outside the indicated
+   * range are not examined, even if the range ends in the middle of a
+   * surrogate pair.
+   *
+   * @param start the starting index
+   * @param end one past the ending index
+   * @return the number of code points
+   * @since 1.5
+   */
+  public synchronized int codePointCount(int start, int end)
+  {
+    if (start < 0 || end >= count || start > end)
+      throw new StringIndexOutOfBoundsException();
+
+    int count = 0;
+    while (start < end)
+      {
+	char base = value[start];
+	if (base < Character.MIN_HIGH_SURROGATE
+	    || base > Character.MAX_HIGH_SURROGATE
+	    || start == end
+	    || start == count
+	    || value[start + 1] < Character.MIN_LOW_SURROGATE
+	    || value[start + 1] > Character.MAX_LOW_SURROGATE)
+	  {
+	    // Nothing.
+	  }
+	else
+	  {
+	    // Surrogate pair.
+	    ++start;
+	  }
+	++start;
+	++count;
+      }
+    return count;
+  }
+
+  /**
+   * Starting at the given index, this counts forward by the indicated
+   * number of code points, and then returns the resulting index.  An
+   * unpaired surrogate counts as a single code point for this
+   * purpose.
+   *
+   * @param start the starting index
+   * @param codePoints the number of code points
+   * @return the resulting index
+   * @since 1.5
+   */
+  public synchronized int offsetByCodePoints(int start, int codePoints)
+  {
+    while (codePoints > 0)
+      {
+	char base = value[start];
+	if (base < Character.MIN_HIGH_SURROGATE
+	    || base > Character.MAX_HIGH_SURROGATE
+	    || start == count
+	    || value[start + 1] < Character.MIN_LOW_SURROGATE
+	    || value[start + 1] > Character.MAX_LOW_SURROGATE)
+	  {
+	    // Nothing.
+	  }
+	else
+	  {
+	    // Surrogate pair.
+	    ++start;
+	  }
+	++start;
+	--codePoints;
+      }
+    return start;
+  }
+
+  /**
+   * An unsynchronized version of ensureCapacity, used internally to avoid
+   * the cost of a second lock on the same object. This also has the side
+   * effect of duplicating the array, if it was shared (to form copy-on-write
+   * semantics).
+   *
+   * @param minimumCapacity the minimum capacity
+   * @see #ensureCapacity(int)
+   */
+  private void ensureCapacity_unsynchronized(int minimumCapacity)
+  {
+    if (shared || minimumCapacity > value.length)
+      {
+        // We don't want to make a larger vector when `shared' is
+        // set.  If we do, then setLength becomes very inefficient
+        // when repeatedly reusing a StringBuffer in a loop.
+        int max = (minimumCapacity > value.length
+                   ? value.length * 2 + 2
+                   : value.length);
+        minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
+        char[] nb = new char[minimumCapacity];
+        System.arraycopy(value, 0, nb, 0, count);
+        value = nb;
+        shared = false;
+      }
+  }
+
+  /**
+   * Predicate which determines if a substring of this matches another String
+   * starting at a specified offset for each String and continuing for a
+   * specified length. This is more efficient than creating a String to call
+   * indexOf on.
+   *
+   * @param toffset index to start comparison at for this String
+   * @param other non-null String to compare to region of this
+   * @return true if regions match, false otherwise
+   * @see #indexOf(String, int)
+   * @see #lastIndexOf(String, int)
+   * @see String#regionMatches(boolean, int, String, int, int)
+   */
+  // GCJ LOCAL: native for gcj.
+  private native boolean regionMatches(int toffset, String other);
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/StringBuilder.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/StringBuilder.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/StringBuilder.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/StringBuilder.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1002 @@
+/* StringBuilder.java -- Unsynchronized growable strings
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.io.Serializable;
+
+/**
+ * <code>StringBuilder</code> represents a changeable <code>String</code>.
+ * It provides the operations required to modify the
+ * <code>StringBuilder</code>, including insert, replace, delete, append,
+ * and reverse. It like <code>StringBuffer</code>, but is not
+ * synchronized.  It is ideal for use when it is known that the
+ * object will only be used from a single thread.
+ *
+ * <p><code>StringBuilder</code>s are variable-length in nature, so even if
+ * you initialize them to a certain size, they can still grow larger than
+ * that. <em>Capacity</em> indicates the number of characters the
+ * <code>StringBuilder</code> can have in it before it has to grow (growing
+ * the char array is an expensive operation involving <code>new</code>).
+ *
+ * <p>Incidentally, compilers often implement the String operator "+"
+ * by using a <code>StringBuilder</code> operation:<br>
+ * <code>a + b</code><br>
+ * is the same as<br>
+ * <code>new StringBuilder().append(a).append(b).toString()</code>.
+ *
+ * <p>Classpath's StringBuilder is capable of sharing memory with Strings for
+ * efficiency.  This will help when a StringBuilder is converted to a String
+ * and the StringBuilder is not changed after that (quite common when
+ * performing string concatenation).
+ *
+ * @author Paul Fisher
+ * @author John Keiser
+ * @author Tom Tromey
+ * @author Eric Blake (ebb9 at email.byu.edu)
+ * @see String
+ * @see StringBuffer
+ *
+ * @since 1.5
+ */
+// FIX15: Implement Appendable when co-variant methods are available
+public final class StringBuilder
+  implements Serializable, CharSequence
+{
+  // Implementation note: if you change this class, you usually will
+  // want to change StringBuffer as well.
+
+  /**
+   * For compatability with Sun's JDK
+   */
+  private static final long serialVersionUID = 4383685877147921099L;
+
+  /**
+   * Index of next available character (and thus the size of the current
+   * string contents).  Note that this has permissions set this way so that
+   * String can get the value.
+   *
+   * @serial the number of characters in the buffer
+   */
+  int count;
+
+  /**
+   * The buffer.  Note that this has permissions set this way so that String
+   * can get the value.
+   *
+   * @serial the buffer
+   */
+  char[] value;
+
+  /**
+   * The default capacity of a buffer.
+   */
+  private static final int DEFAULT_CAPACITY = 16;
+
+  /**
+   * Create a new StringBuilder with default capacity 16.
+   */
+  public StringBuilder()
+  {
+    this(DEFAULT_CAPACITY);
+  }
+
+  /**
+   * Create an empty <code>StringBuilder</code> with the specified initial
+   * capacity.
+   *
+   * @param capacity the initial capacity
+   * @throws NegativeArraySizeException if capacity is negative
+   */
+  public StringBuilder(int capacity)
+  {
+    value = new char[capacity];
+  }
+
+  /**
+   * Create a new <code>StringBuilder</code> with the characters in the
+   * specified <code>String</code>. Initial capacity will be the size of the
+   * String plus 16.
+   *
+   * @param str the <code>String</code> to convert
+   * @throws NullPointerException if str is null
+   */
+  public StringBuilder(String str)
+  {
+    // Unfortunately, because the size is 16 larger, we cannot share.
+    count = str.count;
+    value = new char[count + DEFAULT_CAPACITY];
+    str.getChars(0, count, value, 0);
+  }
+
+  /**
+   * Create a new <code>StringBuilder</code> with the characters in the
+   * specified <code>CharSequence</code>. Initial capacity will be the
+   * length of the sequence plus 16; if the sequence reports a length
+   * less than or equal to 0, then the initial capacity will be 16.
+   *
+   * @param seq the initializing <code>CharSequence</code>
+   * @throws NullPointerException if str is null
+   */
+  public StringBuilder(CharSequence seq)
+  {
+    int len = seq.length();
+    count = len <= 0 ? 0 : len;
+    value = new char[count + DEFAULT_CAPACITY];
+    for (int i = 0; i < len; ++i)
+      value[i] = seq.charAt(i);
+  }
+
+  /**
+   * Get the length of the <code>String</code> this <code>StringBuilder</code>
+   * would create. Not to be confused with the <em>capacity</em> of the
+   * <code>StringBuilder</code>.
+   *
+   * @return the length of this <code>StringBuilder</code>
+   * @see #capacity()
+   * @see #setLength(int)
+   */
+  public int length()
+  {
+    return count;
+  }
+
+  /**
+   * Get the total number of characters this <code>StringBuilder</code> can
+   * support before it must be grown.  Not to be confused with <em>length</em>.
+   *
+   * @return the capacity of this <code>StringBuilder</code>
+   * @see #length()
+   * @see #ensureCapacity(int)
+   */
+  public int capacity()
+  {
+    return value.length;
+  }
+
+  /**
+   * Increase the capacity of this <code>StringBuilder</code>. This will
+   * ensure that an expensive growing operation will not occur until
+   * <code>minimumCapacity</code> is reached. The buffer is grown to the
+   * larger of <code>minimumCapacity</code> and
+   * <code>capacity() * 2 + 2</code>, if it is not already large enough.
+   *
+   * @param minimumCapacity the new capacity
+   * @see #capacity()
+   */
+  public void ensureCapacity(int minimumCapacity)
+  {
+    if (minimumCapacity > value.length)
+      {
+        int max = value.length * 2 + 2;
+        minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
+        char[] nb = new char[minimumCapacity];
+        System.arraycopy(value, 0, nb, 0, count);
+        value = nb;
+      }
+  }
+
+  /**
+   * Set the length of this StringBuilder. If the new length is greater than
+   * the current length, all the new characters are set to '\0'. If the new
+   * length is less than the current length, the first <code>newLength</code>
+   * characters of the old array will be preserved, and the remaining
+   * characters are truncated.
+   *
+   * @param newLength the new length
+   * @throws IndexOutOfBoundsException if the new length is negative
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   * @see #length()
+   */
+  public void setLength(int newLength)
+  {
+    if (newLength < 0)
+      throw new StringIndexOutOfBoundsException(newLength);
+
+    int valueLength = value.length;
+
+    /* Always call ensureCapacity in order to preserve copy-on-write
+       semantics.  */
+    ensureCapacity(newLength);
+
+    if (newLength < valueLength)
+      {
+        /* If the StringBuilder's value just grew, then we know that
+           value is newly allocated and the region between count and
+           newLength is filled with '\0'.  */
+	count = newLength;
+      }
+    else
+      {
+	/* The StringBuilder's value doesn't need to grow.  However,
+	   we should clear out any cruft that may exist.  */
+	while (count < newLength)
+          value[count++] = '\0';
+      }
+  }
+
+  /**
+   * Get the character at the specified index.
+   *
+   * @param index the index of the character to get, starting at 0
+   * @return the character at the specified index
+   * @throws IndexOutOfBoundsException if index is negative or >= length()
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   */
+  public char charAt(int index)
+  {
+    if (index < 0 || index >= count)
+      throw new StringIndexOutOfBoundsException(index);
+    return value[index];
+  }
+
+  /**
+   * Get the specified array of characters. <code>srcOffset - srcEnd</code>
+   * characters will be copied into the array you pass in.
+   *
+   * @param srcOffset the index to start copying from (inclusive)
+   * @param srcEnd the index to stop copying from (exclusive)
+   * @param dst the array to copy into
+   * @param dstOffset the index to start copying into
+   * @throws NullPointerException if dst is null
+   * @throws IndexOutOfBoundsException if any source or target indices are
+   *         out of range (while unspecified, source problems cause a
+   *         StringIndexOutOfBoundsException, and dest problems cause an
+   *         ArrayIndexOutOfBoundsException)
+   * @see System#arraycopy(Object, int, Object, int, int)
+   */
+  public void getChars(int srcOffset, int srcEnd,
+		       char[] dst, int dstOffset)
+  {
+    if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset)
+      throw new StringIndexOutOfBoundsException();
+    System.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset);
+  }
+
+  /**
+   * Set the character at the specified index.
+   *
+   * @param index the index of the character to set starting at 0
+   * @param ch the value to set that character to
+   * @throws IndexOutOfBoundsException if index is negative or >= length()
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   */
+  public void setCharAt(int index, char ch)
+  {
+    if (index < 0 || index >= count)
+      throw new StringIndexOutOfBoundsException(index);
+    // Call ensureCapacity to enforce copy-on-write.
+    ensureCapacity(count);
+    value[index] = ch;
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param obj the <code>Object</code> to convert and append
+   * @return this <code>StringBuilder</code>
+   * @see String#valueOf(Object)
+   * @see #append(String)
+   */
+  public StringBuilder append(Object obj)
+  {
+    return append(obj == null ? "null" : obj.toString());
+  }
+
+  /**
+   * Append the <code>String</code> to this <code>StringBuilder</code>. If
+   * str is null, the String "null" is appended.
+   *
+   * @param str the <code>String</code> to append
+   * @return this <code>StringBuilder</code>
+   */
+  public StringBuilder append(String str)
+  {
+    if (str == null)
+      str = "null";
+    int len = str.count;
+    ensureCapacity(count + len);
+    str.getChars(0, len, value, count);
+    count += len;
+    return this;
+  }
+
+  /**
+   * Append the <code>StringBuilder</code> value of the argument to this
+   * <code>StringBuilder</code>. This behaves the same as
+   * <code>append((Object) stringBuffer)</code>, except it is more efficient.
+   *
+   * @param stringBuffer the <code>StringBuilder</code> to convert and append
+   * @return this <code>StringBuilder</code>
+   * @see #append(Object)
+   */
+  public StringBuilder append(StringBuffer stringBuffer)
+  {
+    if (stringBuffer == null)
+      return append("null");
+    synchronized (stringBuffer)
+      {
+	int len = stringBuffer.count;
+	ensureCapacity(count + len);
+	System.arraycopy(stringBuffer.value, 0, value, count, len);
+	count += len;
+      }
+    return this;
+  }
+
+  /**
+   * Append the <code>char</code> array to this <code>StringBuilder</code>.
+   * This is similar (but more efficient) than
+   * <code>append(new String(data))</code>, except in the case of null.
+   *
+   * @param data the <code>char[]</code> to append
+   * @return this <code>StringBuilder</code>
+   * @throws NullPointerException if <code>str</code> is <code>null</code>
+   * @see #append(char[], int, int)
+   */
+  public StringBuilder append(char[] data)
+  {
+    return append(data, 0, data.length);
+  }
+
+  /**
+   * Append part of the <code>char</code> array to this
+   * <code>StringBuilder</code>. This is similar (but more efficient) than
+   * <code>append(new String(data, offset, count))</code>, except in the case
+   * of null.
+   *
+   * @param data the <code>char[]</code> to append
+   * @param offset the start location in <code>str</code>
+   * @param count the number of characters to get from <code>str</code>
+   * @return this <code>StringBuilder</code>
+   * @throws NullPointerException if <code>str</code> is <code>null</code>
+   * @throws IndexOutOfBoundsException if offset or count is out of range
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   */
+  public StringBuilder append(char[] data, int offset, int count)
+  {
+    if (offset < 0 || count < 0 || offset > data.length - count)
+      throw new StringIndexOutOfBoundsException();
+    ensureCapacity(this.count + count);
+    System.arraycopy(data, offset, value, this.count, count);
+    this.count += count;
+    return this;
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param bool the <code>boolean</code> to convert and append
+   * @return this <code>StringBuilder</code>
+   * @see String#valueOf(boolean)
+   */
+  public StringBuilder append(boolean bool)
+  {
+    return append(bool ? "true" : "false");
+  }
+
+  /**
+   * Append the <code>char</code> to this <code>StringBuilder</code>.
+   *
+   * @param ch the <code>char</code> to append
+   * @return this <code>StringBuilder</code>
+   */
+  public StringBuilder append(char ch)
+  {
+    ensureCapacity(count + 1);
+    value[count++] = ch;
+    return this;
+  }
+
+  /**
+   * Append the characters in the <code>CharSequence</code> to this
+   * buffer.
+   *
+   * @param seq the <code>CharSequence</code> providing the characters
+   * @return this <code>StringBuilder</code>
+   */
+  public StringBuilder append(CharSequence seq)
+  {
+    return append(seq, 0, seq.length());
+  }
+
+  /**
+   * Append some characters from the <code>CharSequence</code> to this
+   * buffer.  If the argument is null, the four characters "null" are
+   * appended.
+   *
+   * @param seq the <code>CharSequence</code> providing the characters
+   * @param start the starting index
+   * @param end one past the final index
+   * @return this <code>StringBuilder</code>
+   */
+  public StringBuilder append(CharSequence seq, int start,
+			      int end)
+  {
+    if (seq == null)
+      return append("null");
+    if (end - start > 0)
+      {
+	ensureCapacity(count + end - start);
+	for (; start < end; ++start)
+	  value[count++] = seq.charAt(start);
+      }
+    return this;
+  }
+
+  /**
+   * Append the code point to this <code>StringBuilder</code>.
+   * This is like #append(char), but will append two characters
+   * if a supplementary code point is given.
+   *
+   * @param code the code point to append
+   * @return this <code>StringBuilder</code>
+   * @see Character#toChars(int, char[], int)
+   * @since 1.5
+   */
+  public synchronized StringBuilder appendCodePoint(int code)
+  {
+    int len = Character.charCount(code);
+    ensureCapacity(count + len);
+    Character.toChars(code, value, count);
+    count += len;
+    return this;
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param inum the <code>int</code> to convert and append
+   * @return this <code>StringBuilder</code>
+   * @see String#valueOf(int)
+   */
+  // FIXME: this is native in libgcj in StringBuffer.
+  public StringBuilder append(int inum)
+  {
+    return append(String.valueOf(inum));
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param lnum the <code>long</code> to convert and append
+   * @return this <code>StringBuilder</code>
+   * @see String#valueOf(long)
+   */
+  public StringBuilder append(long lnum)
+  {
+    return append(Long.toString(lnum, 10));
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param fnum the <code>float</code> to convert and append
+   * @return this <code>StringBuilder</code>
+   * @see String#valueOf(float)
+   */
+  public StringBuilder append(float fnum)
+  {
+    return append(Float.toString(fnum));
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param dnum the <code>double</code> to convert and append
+   * @return this <code>StringBuilder</code>
+   * @see String#valueOf(double)
+   */
+  public StringBuilder append(double dnum)
+  {
+    return append(Double.toString(dnum));
+  }
+
+  /**
+   * Delete characters from this <code>StringBuilder</code>.
+   * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
+   * harmless for end to be larger than length().
+   *
+   * @param start the first character to delete
+   * @param end the index after the last character to delete
+   * @return this <code>StringBuilder</code>
+   * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+   */
+  public StringBuilder delete(int start, int end)
+  {
+    if (start < 0 || start > count || start > end)
+      throw new StringIndexOutOfBoundsException(start);
+    if (end > count)
+      end = count;
+    // This will unshare if required.
+    ensureCapacity(count);
+    if (count - end != 0)
+      System.arraycopy(value, end, value, start, count - end);
+    count -= end - start;
+    return this;
+  }
+
+  /**
+   * Delete a character from this <code>StringBuilder</code>.
+   *
+   * @param index the index of the character to delete
+   * @return this <code>StringBuilder</code>
+   * @throws StringIndexOutOfBoundsException if index is out of bounds
+   */
+  public StringBuilder deleteCharAt(int index)
+  {
+    return delete(index, index + 1);
+  }
+
+  /**
+   * Replace characters between index <code>start</code> (inclusive) and
+   * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
+   * is larger than the size of this StringBuilder, all characters after
+   * <code>start</code> are replaced.
+   *
+   * @param start the beginning index of characters to delete (inclusive)
+   * @param end the ending index of characters to delete (exclusive)
+   * @param str the new <code>String</code> to insert
+   * @return this <code>StringBuilder</code>
+   * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+   * @throws NullPointerException if str is null
+   */
+  public StringBuilder replace(int start, int end, String str)
+  {
+    if (start < 0 || start > count || start > end)
+      throw new StringIndexOutOfBoundsException(start);
+
+    int len = str.count;
+    // Calculate the difference in 'count' after the replace.
+    int delta = len - (end > count ? count : end) + start;
+    ensureCapacity(count + delta);
+
+    if (delta != 0 && end < count)
+      System.arraycopy(value, end, value, end + delta, count - end);
+
+    str.getChars(0, len, value, start);
+    count += delta;
+    return this;
+  }
+
+  /**
+   * Creates a substring of this StringBuilder, starting at a specified index
+   * and ending at the end of this StringBuilder.
+   *
+   * @param beginIndex index to start substring (base 0)
+   * @return new String which is a substring of this StringBuilder
+   * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds
+   * @see #substring(int, int)
+   */
+  public String substring(int beginIndex)
+  {
+    return substring(beginIndex, count);
+  }
+
+  /**
+   * Creates a substring of this StringBuilder, starting at a specified index
+   * and ending at one character before a specified index. This is implemented
+   * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy
+   * the CharSequence interface.
+   *
+   * @param beginIndex index to start at (inclusive, base 0)
+   * @param endIndex index to end at (exclusive)
+   * @return new String which is a substring of this StringBuilder
+   * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of
+   *         bounds
+   * @see #substring(int, int)
+   */
+  public CharSequence subSequence(int beginIndex, int endIndex)
+  {
+    return substring(beginIndex, endIndex);
+  }
+
+  /**
+   * Creates a substring of this StringBuilder, starting at a specified index
+   * and ending at one character before a specified index.
+   *
+   * @param beginIndex index to start at (inclusive, base 0)
+   * @param endIndex index to end at (exclusive)
+   * @return new String which is a substring of this StringBuilder
+   * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out
+   *         of bounds
+   */
+  public String substring(int beginIndex, int endIndex)
+  {
+    int len = endIndex - beginIndex;
+    if (beginIndex < 0 || endIndex > count || endIndex < beginIndex)
+      throw new StringIndexOutOfBoundsException();
+    if (len == 0)
+      return "";
+    return new String(value, beginIndex, len);
+  }
+
+  /**
+   * Insert a subarray of the <code>char[]</code> argument into this
+   * <code>StringBuilder</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param str the <code>char[]</code> to insert
+   * @param str_offset the index in <code>str</code> to start inserting from
+   * @param len the number of characters to insert
+   * @return this <code>StringBuilder</code>
+   * @throws NullPointerException if <code>str</code> is <code>null</code>
+   * @throws StringIndexOutOfBoundsException if any index is out of bounds
+   */
+  public StringBuilder insert(int offset,
+			      char[] str, int str_offset, int len)
+  {
+    if (offset < 0 || offset > count || len < 0
+        || str_offset < 0 || str_offset > str.length - len)
+      throw new StringIndexOutOfBoundsException();
+    ensureCapacity(count + len);
+    System.arraycopy(value, offset, value, offset + len, count - offset);
+    System.arraycopy(str, str_offset, value, offset, len);
+    count += len;
+    return this;
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param obj the <code>Object</code> to convert and insert
+   * @return this <code>StringBuilder</code>
+   * @exception StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(Object)
+   */
+  public StringBuilder insert(int offset, Object obj)
+  {
+    return insert(offset, obj == null ? "null" : obj.toString());
+  }
+
+  /**
+   * Insert the <code>String</code> argument into this
+   * <code>StringBuilder</code>. If str is null, the String "null" is used
+   * instead.
+   *
+   * @param offset the place to insert in this buffer
+   * @param str the <code>String</code> to insert
+   * @return this <code>StringBuilder</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   */
+  public StringBuilder insert(int offset, String str)
+  {
+    if (offset < 0 || offset > count)
+      throw new StringIndexOutOfBoundsException(offset);
+    if (str == null)
+      str = "null";
+    int len = str.count;
+    ensureCapacity(count + len);
+    System.arraycopy(value, offset, value, offset + len, count - offset);
+    str.getChars(0, len, value, offset);
+    count += len;
+    return this;
+  }
+
+  /**
+   * Insert the <code>CharSequence</code> argument into this
+   * <code>StringBuilder</code>.  If the sequence is null, the String
+   * "null" is used instead.
+   *
+   * @param offset the place to insert in this buffer
+   * @param sequence the <code>CharSequence</code> to insert
+   * @return this <code>StringBuilder</code>
+   * @throws IndexOutOfBoundsException if offset is out of bounds
+   */
+  public synchronized StringBuilder insert(int offset, CharSequence sequence)
+  {
+    if (sequence == null)
+      sequence = "null";
+    return insert(offset, sequence, 0, sequence.length());
+  }
+
+  /**
+   * Insert a subsequence of the <code>CharSequence</code> argument into this
+   * <code>StringBuilder</code>.  If the sequence is null, the String
+   * "null" is used instead.
+   *
+   * @param offset the place to insert in this buffer
+   * @param sequence the <code>CharSequence</code> to insert
+   * @param start the starting index of the subsequence
+   * @param end one past the ending index of the subsequence
+   * @return this <code>StringBuilder</code>
+   * @throws IndexOutOfBoundsException if offset, start,
+   * or end are out of bounds
+   */
+  public synchronized StringBuilder insert(int offset, CharSequence sequence,
+                      int start, int end)
+  {
+    if (sequence == null)
+      sequence = "null";
+    if (start < 0 || end < 0 || start > end || end > sequence.length())
+      throw new IndexOutOfBoundsException();
+    int len = end - start;
+    ensureCapacity(count + len);
+    System.arraycopy(value, offset, value, offset + len, count - offset);
+    for (int i = start; i < end; ++i)
+      value[offset++] = sequence.charAt(i);
+    count += len;
+    return this;
+  }
+
+  /**
+   * Insert the <code>char[]</code> argument into this
+   * <code>StringBuilder</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param data the <code>char[]</code> to insert
+   * @return this <code>StringBuilder</code>
+   * @throws NullPointerException if <code>data</code> is <code>null</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see #insert(int, char[], int, int)
+   */
+  public StringBuilder insert(int offset, char[] data)
+  {
+    return insert(offset, data, 0, data.length);
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param bool the <code>boolean</code> to convert and insert
+   * @return this <code>StringBuilder</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(boolean)
+   */
+  public StringBuilder insert(int offset, boolean bool)
+  {
+    return insert(offset, bool ? "true" : "false");
+  }
+
+  /**
+   * Insert the <code>char</code> argument into this <code>StringBuilder</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param ch the <code>char</code> to insert
+   * @return this <code>StringBuilder</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   */
+  public StringBuilder insert(int offset, char ch)
+  {
+    if (offset < 0 || offset > count)
+      throw new StringIndexOutOfBoundsException(offset);
+    ensureCapacity(count + 1);
+    System.arraycopy(value, offset, value, offset + 1, count - offset);
+    value[offset] = ch;
+    count++;
+    return this;
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param inum the <code>int</code> to convert and insert
+   * @return this <code>StringBuilder</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(int)
+   */
+  public StringBuilder insert(int offset, int inum)
+  {
+    return insert(offset, String.valueOf(inum));
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param lnum the <code>long</code> to convert and insert
+   * @return this <code>StringBuilder</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(long)
+   */
+  public StringBuilder insert(int offset, long lnum)
+  {
+    return insert(offset, Long.toString(lnum, 10));
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param fnum the <code>float</code> to convert and insert
+   * @return this <code>StringBuilder</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(float)
+   */
+  public StringBuilder insert(int offset, float fnum)
+  {
+    return insert(offset, Float.toString(fnum));
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param dnum the <code>double</code> to convert and insert
+   * @return this <code>StringBuilder</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(double)
+   */
+  public StringBuilder insert(int offset, double dnum)
+  {
+    return insert(offset, Double.toString(dnum));
+  }
+
+  /**
+   * Finds the first instance of a substring in this StringBuilder.
+   *
+   * @param str String to find
+   * @return location (base 0) of the String, or -1 if not found
+   * @throws NullPointerException if str is null
+   * @see #indexOf(String, int)
+   */
+  public int indexOf(String str)
+  {
+    return indexOf(str, 0);
+  }
+
+  /**
+   * Finds the first instance of a String in this StringBuilder, starting at
+   * a given index.  If starting index is less than 0, the search starts at
+   * the beginning of this String.  If the starting index is greater than the
+   * length of this String, or the substring is not found, -1 is returned.
+   *
+   * @param str String to find
+   * @param fromIndex index to start the search
+   * @return location (base 0) of the String, or -1 if not found
+   * @throws NullPointerException if str is null
+   */
+  public int indexOf(String str, int fromIndex)
+  {
+    if (fromIndex < 0)
+      fromIndex = 0;
+    int limit = count - str.count;
+    for ( ; fromIndex <= limit; fromIndex++)
+      if (regionMatches(fromIndex, str))
+        return fromIndex;
+    return -1;
+  }
+
+  /**
+   * Finds the last instance of a substring in this StringBuilder.
+   *
+   * @param str String to find
+   * @return location (base 0) of the String, or -1 if not found
+   * @throws NullPointerException if str is null
+   * @see #lastIndexOf(String, int)
+   */
+  public int lastIndexOf(String str)
+  {
+    return lastIndexOf(str, count - str.count);
+  }
+
+  /**
+   * Finds the last instance of a String in this StringBuilder, starting at a
+   * given index.  If starting index is greater than the maximum valid index,
+   * then the search begins at the end of this String.  If the starting index
+   * is less than zero, or the substring is not found, -1 is returned.
+   *
+   * @param str String to find
+   * @param fromIndex index to start the search
+   * @return location (base 0) of the String, or -1 if not found
+   * @throws NullPointerException if str is null
+   */
+  public int lastIndexOf(String str, int fromIndex)
+  {
+    fromIndex = Math.min(fromIndex, count - str.count);
+    for ( ; fromIndex >= 0; fromIndex--)
+      if (regionMatches(fromIndex, str))
+        return fromIndex;
+    return -1;
+  }
+
+  /**
+   * Reverse the characters in this StringBuilder. The same sequence of
+   * characters exists, but in the reverse index ordering.
+   *
+   * @return this <code>StringBuilder</code>
+   */
+  public StringBuilder reverse()
+  {
+    // Call ensureCapacity to enforce copy-on-write.
+    ensureCapacity(count);
+    for (int i = count >> 1, j = count - i; --i >= 0; ++j)
+      {
+        char c = value[i];
+        value[i] = value[j];
+        value[j] = c;
+      }
+    return this;
+  }
+
+  /**
+   * Convert this <code>StringBuilder</code> to a <code>String</code>. The
+   * String is composed of the characters currently in this StringBuilder. Note
+   * that the result is a copy, and that future modifications to this buffer
+   * do not affect the String.
+   *
+   * @return the characters in this StringBuilder
+   */
+  public String toString()
+  {
+    return new String(this);
+  }
+
+  /**
+   * Predicate which determines if a substring of this matches another String
+   * starting at a specified offset for each String and continuing for a
+   * specified length. This is more efficient than creating a String to call
+   * indexOf on.
+   *
+   * @param toffset index to start comparison at for this String
+   * @param other non-null String to compare to region of this
+   * @return true if regions match, false otherwise
+   * @see #indexOf(String, int)
+   * @see #lastIndexOf(String, int)
+   * @see String#regionMatches(boolean, int, String, int, int)
+   */
+  // GCJ LOCAL: Native to access String internals properly.
+  private native boolean regionMatches(int toffset, String other);
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/System.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/System.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/System.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/System.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,560 @@
+/* System.java -- useful methods to interface with the system
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang;
+
+import gnu.classpath.SystemProperties;
+
+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;
+import java.util.Properties;
+import java.util.PropertyPermission;
+
+/**
+ * System represents system-wide resources; things that represent the
+ * general environment.  As such, all methods are static.
+ *
+ * @author John Keiser
+ * @author Eric Blake (ebb9 at email.byu.edu)
+ * @since 1.0
+ * @status still missing 1.4 functionality
+ */
+public final class System
+{
+  // WARNING: System is a CORE class in the bootstrap cycle. See the comments
+  // in vm/reference/java/lang/Runtime for implications of this fact.
+
+  /**
+   * The standard InputStream. This is assigned at startup and starts its
+   * life perfectly valid. Although it is marked final, you can change it
+   * using {@link #setIn(InputStream)} through some hefty VM magic.
+   *
+   * <p>This corresponds to the C stdin and C++ cin variables, which
+   * typically input from the keyboard, but may be used to pipe input from
+   * other processes or files.  That should all be transparent to you,
+   * however.
+   */
+  public static final InputStream in
+    = new BufferedInputStream(new FileInputStream(FileDescriptor.in));
+  /**
+   * The standard output PrintStream.  This is assigned at startup and
+   * starts its life perfectly valid. Although it is marked final, you can
+   * change it using {@link #setOut(PrintStream)} through some hefty VM magic.
+   *
+   * <p>This corresponds to the C stdout and C++ cout variables, which
+   * typically output normal messages to the screen, but may be used to pipe
+   * output to other processes or files.  That should all be transparent to
+   * you, however.
+   */
+  public static final PrintStream out
+    = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)), true);
+  /**
+   * The standard output PrintStream.  This is assigned at startup and
+   * starts its life perfectly valid. Although it is marked final, you can
+   * change it using {@link #setErr(PrintStream)} through some hefty VM magic.
+   *
+   * <p>This corresponds to the C stderr and C++ cerr variables, which
+   * typically output error messages to the screen, but may be used to pipe
+   * output to other processes or files.  That should all be transparent to
+   * you, however.
+   */
+  public static final PrintStream err
+    = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.err)), true);
+
+  /**
+   * This class is uninstantiable.
+   */
+  private System()
+  {
+  }
+
+  /**
+   * Set {@link #in} to a new InputStream. This uses some VM magic to change
+   * a "final" variable, so naturally there is a security check,
+   * <code>RuntimePermission("setIO")</code>.
+   *
+   * @param in the new InputStream
+   * @throws SecurityException if permission is denied
+   * @since 1.1
+   */
+  public static void setIn(InputStream in)
+  {
+    SecurityManager sm = SecurityManager.current; // Be thread-safe.
+    if (sm != null)
+      sm.checkPermission(new RuntimePermission("setIO"));
+    setIn0(in);
+  }
+
+  /**
+   * Set {@link #out} to a new PrintStream. This uses some VM magic to change
+   * a "final" variable, so naturally there is a security check,
+   * <code>RuntimePermission("setIO")</code>.
+   *
+   * @param out the new PrintStream
+   * @throws SecurityException if permission is denied
+   * @since 1.1
+   */
+  public static void setOut(PrintStream out)
+  {
+    SecurityManager sm = SecurityManager.current; // Be thread-safe.
+    if (sm != null)
+      sm.checkPermission(new RuntimePermission("setIO"));
+    
+    setOut0(out);
+  }
+
+  /**
+   * Set {@link #err} to a new PrintStream. This uses some VM magic to change
+   * a "final" variable, so naturally there is a security check,
+   * <code>RuntimePermission("setIO")</code>.
+   *
+   * @param err the new PrintStream
+   * @throws SecurityException if permission is denied
+   * @since 1.1
+   */
+  public static void setErr(PrintStream err)
+  {
+    SecurityManager sm = SecurityManager.current; // Be thread-safe.
+    if (sm != null)
+      sm.checkPermission(new RuntimePermission("setIO"));
+    setErr0(err);
+  }
+
+  /**
+   * Set the current SecurityManager. If a security manager already exists,
+   * then <code>RuntimePermission("setSecurityManager")</code> is checked
+   * first. Since this permission is denied by the default security manager,
+   * setting the security manager is often an irreversible action.
+   *
+   * @param sm the new SecurityManager
+   * @throws SecurityException if permission is denied
+   */
+  public static synchronized void setSecurityManager(SecurityManager sm)
+  {
+    // Implementation note: the field lives in SecurityManager because of
+    // bootstrap initialization issues. This method is synchronized so that
+    // no other thread changes it to null before this thread makes the change.
+    if (SecurityManager.current != null)
+      SecurityManager.current.checkPermission
+        (new RuntimePermission("setSecurityManager"));
+    SecurityManager.current = sm;
+  }
+
+  /**
+   * Get the current SecurityManager. If the SecurityManager has not been
+   * set yet, then this method returns null.
+   *
+   * @return the current SecurityManager, or null
+   */
+  public static SecurityManager getSecurityManager()
+  {
+    return SecurityManager.current;
+  }
+
+  /**
+   * 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();
+
+  /**
+   * Get the current time, measured in nanoseconds.  The result is as
+   * precise as possible, and is measured against a fixed epoch.
+   * However, unlike currentTimeMillis(), the epoch chosen is
+   * arbitrary and may vary by platform, etc.
+   * @since 1.5
+   */
+  public static native long nanoTime();
+
+  /**
+   * 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
+   */
+  public 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
+   * @since 1.1
+   */
+  public static native int identityHashCode(Object o);
+
+  /**
+   * Get all the system properties at once. A security check may be performed,
+   * <code>checkPropertiesAccess</code>. Note that a security manager may
+   * allow getting a single property, but not the entire group.
+   *
+   * <p>The required properties include:
+   * <dl>
+   * <dt>java.version</dt>         <dd>Java version number</dd>
+   * <dt>java.vendor</dt>          <dd>Java vendor specific string</dd>
+   * <dt>java.vendor.url</dt>      <dd>Java vendor URL</dd>
+   * <dt>java.home</dt>            <dd>Java installation directory</dd>
+   * <dt>java.vm.specification.version</dt> <dd>VM Spec version</dd>
+   * <dt>java.vm.specification.vendor</dt>  <dd>VM Spec vendor</dd>
+   * <dt>java.vm.specification.name</dt>    <dd>VM Spec name</dd>
+   * <dt>java.vm.version</dt>      <dd>VM implementation version</dd>
+   * <dt>java.vm.vendor</dt>       <dd>VM implementation vendor</dd>
+   * <dt>java.vm.name</dt>         <dd>VM implementation name</dd>
+   * <dt>java.specification.version</dt>    <dd>Java Runtime Environment version</dd>
+   * <dt>java.specification.vendor</dt>     <dd>Java Runtime Environment vendor</dd>
+   * <dt>java.specification.name</dt>       <dd>Java Runtime Environment name</dd>
+   * <dt>java.class.version</dt>   <dd>Java class version number</dd>
+   * <dt>java.class.path</dt>      <dd>Java classpath</dd>
+   * <dt>java.library.path</dt>    <dd>Path for finding Java libraries</dd>
+   * <dt>java.io.tmpdir</dt>       <dd>Default temp file path</dd>
+   * <dt>java.compiler</dt>        <dd>Name of JIT to use</dd>
+   * <dt>java.ext.dirs</dt>        <dd>Java extension path</dd>
+   * <dt>os.name</dt>              <dd>Operating System Name</dd>
+   * <dt>os.arch</dt>              <dd>Operating System Architecture</dd>
+   * <dt>os.version</dt>           <dd>Operating System Version</dd>
+   * <dt>file.separator</dt>       <dd>File separator ("/" on Unix)</dd>
+   * <dt>path.separator</dt>       <dd>Path separator (":" on Unix)</dd>
+   * <dt>line.separator</dt>       <dd>Line separator ("\n" on Unix)</dd>
+   * <dt>user.name</dt>            <dd>User account name</dd>
+   * <dt>user.home</dt>            <dd>User home directory</dd>
+   * <dt>user.dir</dt>             <dd>User's current working directory</dd>
+   * </dl>
+   *
+   * In addition, gnu defines several other properties, where ? stands for
+   * each character in '0' through '9':
+   * <dl>
+   * <dt>gnu.classpath.home</dt>         <dd>Path to the classpath libraries.</dd>
+   * <dt>gnu.classpath.version</dt>      <dd>Version of the classpath libraries.</dd>
+   * <dt>gnu.classpath.vm.shortname</dt> <dd>Succinct version of the VM name;
+   *     used for finding property files in file system</dd>
+   * <dt>gnu.classpath.home.url</dt>     <dd> Base URL; used for finding
+   *     property files in file system</dd>
+   * <dt>gnu.cpu.endian</dt>             <dd>big or little</dd>
+   * <dt>gnu.java.io.encoding_scheme_alias.ISO-8859-?</dt>   <dd>8859_?</dd>
+   * <dt>gnu.java.io.encoding_scheme_alias.iso-8859-?</dt>   <dd>8859_?</dd>
+   * <dt>gnu.java.io.encoding_scheme_alias.iso8859_?</dt>    <dd>8859_?</dd>
+   * <dt>gnu.java.io.encoding_scheme_alias.iso-latin-_?</dt> <dd>8859_?</dd>
+   * <dt>gnu.java.io.encoding_scheme_alias.latin?</dt>       <dd>8859_?</dd>
+   * <dt>gnu.java.io.encoding_scheme_alias.UTF-8</dt>        <dd>UTF8</dd>
+   * <dt>gnu.java.io.encoding_scheme_alias.utf-8</dt>        <dd>UTF8</dd>
+   * </dl>
+   *
+   * @return the system properties, will never be null
+   * @throws SecurityException if permission is denied
+   */
+  public static Properties getProperties()
+  {
+    SecurityManager sm = SecurityManager.current; // Be thread-safe.
+    if (sm != null)
+      sm.checkPropertiesAccess();
+    return SystemProperties.getProperties();
+  }
+
+  /**
+   * Set all the system properties at once. A security check may be performed,
+   * <code>checkPropertiesAccess</code>. Note that a security manager may
+   * allow setting a single property, but not the entire group. An argument
+   * of null resets the properties to the startup default.
+   *
+   * @param properties the new set of system properties
+   * @throws SecurityException if permission is denied
+   */
+  public static void setProperties(Properties properties)
+  {
+    SecurityManager sm = SecurityManager.current; // Be thread-safe.
+    if (sm != null)
+      sm.checkPropertiesAccess();
+    SystemProperties.setProperties(properties);
+  }
+
+  /**
+   * Get a single system property by name. A security check may be performed,
+   * <code>checkPropertyAccess(key)</code>.
+   *
+   * @param key the name of the system property to get
+   * @return the property, or null if not found
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if key is null
+   * @throws IllegalArgumentException if key is ""
+   */
+  public static String getProperty(String key)
+  {
+    SecurityManager sm = SecurityManager.current; // Be thread-safe.
+    if (sm != null)
+      sm.checkPropertyAccess(key);
+    else if (key.length() == 0)
+      throw new IllegalArgumentException("key can't be empty");
+    return SystemProperties.getProperty(key);
+  }
+
+  /**
+   * Get a single system property by name. A security check may be performed,
+   * <code>checkPropertyAccess(key)</code>.
+   *
+   * @param key the name of the system property to get
+   * @param def the default
+   * @return the property, or def if not found
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if key is null
+   * @throws IllegalArgumentException if key is ""
+   */
+  public static String getProperty(String key, String def)
+  {
+    SecurityManager sm = SecurityManager.current; // Be thread-safe.
+    if (sm != null)
+      sm.checkPropertyAccess(key);
+    return SystemProperties.getProperty(key, def);
+  }
+
+  /**
+   * Set a single system property by name. A security check may be performed,
+   * <code>checkPropertyAccess(key, "write")</code>.
+   *
+   * @param key the name of the system property to set
+   * @param value the new value
+   * @return the previous value, or null
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if key is null
+   * @throws IllegalArgumentException if key is ""
+   * @since 1.2
+   */
+  public static String setProperty(String key, String value)
+  {
+    SecurityManager sm = SecurityManager.current; // Be thread-safe.
+    if (sm != null)
+      sm.checkPermission(new PropertyPermission(key, "write"));
+    return SystemProperties.setProperty(key, value);
+  }
+
+  /**
+   * Gets the value of an environment variable.
+   *
+   * @param name the name of the environment variable
+   * @return the string value of the variable or null when the
+   *         environment variable is not defined.
+   * @throws NullPointerException
+   * @throws SecurityException if permission is denied
+   * @since 1.5
+   * @specnote This method was deprecated in some JDK releases, but
+   *           was restored in 1.5.
+   */
+  public static String getenv(String name)
+  {
+    if (name == null)
+      throw new NullPointerException();
+    SecurityManager sm = SecurityManager.current; // Be thread-safe.
+    if (sm != null)
+      sm.checkPermission(new RuntimePermission("getenv." + name));
+    return getenv0(name);
+  }
+
+  /**
+   * Terminate the Virtual Machine. This just calls
+   * <code>Runtime.getRuntime().exit(status)</code>, and never returns.
+   * Obviously, a security check is in order, <code>checkExit</code>.
+   *
+   * @param status the exit status; by convention non-zero is abnormal
+   * @throws SecurityException if permission is denied
+   * @see Runtime#exit(int)
+   */
+  public static void exit(int status)
+  {
+    Runtime.getRuntime().exit(status);
+  }
+
+  /**
+   * Calls the garbage collector. This is only a hint, and it is up to the
+   * implementation what this hint suggests, but it usually causes a
+   * best-effort attempt to reclaim unused memory from discarded objects.
+   * This calls <code>Runtime.getRuntime().gc()</code>.
+   *
+   * @see Runtime#gc()
+   */
+  public static void gc()
+  {
+    Runtime.getRuntime().gc();
+  }
+
+  /**
+   * Runs object finalization on pending objects. This is only a hint, and
+   * it is up to the implementation what this hint suggests, but it usually
+   * causes a best-effort attempt to run finalizers on all objects ready
+   * to be reclaimed. This calls
+   * <code>Runtime.getRuntime().runFinalization()</code>.
+   *
+   * @see Runtime#runFinalization()
+   */
+  public static void runFinalization()
+  {
+    Runtime.getRuntime().runFinalization();
+  }
+
+  /**
+   * Tell the Runtime whether to run finalization before exiting the
+   * JVM.  This is inherently unsafe in multi-threaded applications,
+   * since it can force initialization on objects which are still in use
+   * by live threads, leading to deadlock; therefore this is disabled by
+   * default. There may be a security check, <code>checkExit(0)</code>. This
+   * calls <code>Runtime.getRuntime().runFinalizersOnExit()</code>.
+   *
+   * @param finalizeOnExit whether to run finalizers on exit
+   * @throws SecurityException if permission is denied
+   * @see Runtime#runFinalizersOnExit()
+   * @since 1.1
+   * @deprecated never rely on finalizers to do a clean, thread-safe,
+   *             mop-up from your code
+   */
+  public static void runFinalizersOnExit(boolean finalizeOnExit)
+  {
+    Runtime.getRuntime().runFinalizersOnExit(finalizeOnExit);
+  }
+
+  /**
+   * Load a code file using its explicit system-dependent filename. A security
+   * check may be performed, <code>checkLink</code>. This just calls
+   * <code>Runtime.getRuntime().load(filename)</code>.
+   *
+   * <p>
+   * The library is loaded using the class loader associated with the
+   * class associated with the invoking method.
+   *
+   * @param filename the code file to load
+   * @throws SecurityException if permission is denied
+   * @throws UnsatisfiedLinkError if the file cannot be loaded
+   * @see Runtime#load(String)
+   */
+  public static void load(String filename)
+  {
+    Runtime.getRuntime().load(filename);
+  }
+
+  /**
+   * Load a library using its explicit system-dependent filename. A security
+   * check may be performed, <code>checkLink</code>. This just calls
+   * <code>Runtime.getRuntime().load(filename)</code>.
+   *
+   * <p>
+   * The library is loaded using the class loader associated with the
+   * class associated with the invoking method.
+   *
+   * @param libname the library file to load
+   * @throws SecurityException if permission is denied
+   * @throws UnsatisfiedLinkError if the file cannot be loaded
+   * @see Runtime#load(String)
+   */
+  public static void loadLibrary(String libname)
+  {
+    Runtime.getRuntime().loadLibrary(libname);
+  }
+
+  /**
+   * 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
+   * @since 1.2
+   */
+  public static String mapLibraryName(String libname)
+  {
+    // XXX Fix this!!!!
+    return Runtime.nativeGetLibname("", libname);
+  }
+
+  /**
+   * Set {@link #in} to a new InputStream.
+   *
+   * @param in the new InputStream
+   * @see #setIn(InputStream)
+   */
+  private static native void setIn0(InputStream in);
+
+  /**
+   * Set {@link #out} to a new PrintStream.
+   *
+   * @param out the new PrintStream
+   * @see #setOut(PrintStream)
+   */
+  private static native void setOut0(PrintStream out);
+
+  /**
+   * Set {@link #err} to a new PrintStream.
+   *
+   * @param err the new PrintStream
+   * @see #setErr(PrintStream)
+   */
+  private static native void setErr0(PrintStream err);
+
+  /**
+   * Gets the value of an environment variable.
+   *
+   * @see #getenv(String)
+   */
+  static native String getenv0(String name);
+} // class System

Added: llvm-gcc-4.2/trunk/libjava/java/lang/Thread.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/Thread.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/Thread.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/Thread.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1128 @@
+/* Thread -- an independent thread of executable code
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang;
+
+import gnu.gcj.RawData;
+import gnu.gcj.RawDataManaged;
+import gnu.java.util.WeakIdentityHashMap;
+import java.util.Map;
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status:  Believed complete to version 1.4, with caveats. We do not
+ *          implement the deprecated (and dangerous) stop, suspend, and resume
+ *          methods. Security implementation is not complete.
+ */
+
+/**
+ * Thread represents a single thread of execution in the VM. When an
+ * application VM starts up, it creates a non-daemon Thread which calls the
+ * main() method of a particular class.  There may be other Threads running,
+ * such as the garbage collection thread.
+ *
+ * <p>Threads have names to identify them.  These names are not necessarily
+ * unique. Every Thread has a priority, as well, which tells the VM which
+ * Threads should get more running time. New threads inherit the priority
+ * and daemon status of the parent thread, by default.
+ *
+ * <p>There are two methods of creating a Thread: you may subclass Thread and
+ * implement the <code>run()</code> method, at which point you may start the
+ * Thread by calling its <code>start()</code> method, or you may implement
+ * <code>Runnable</code> in the class you want to use and then call new
+ * <code>Thread(your_obj).start()</code>.
+ *
+ * <p>The virtual machine runs until all non-daemon threads have died (either
+ * by returning from the run() method as invoked by start(), or by throwing
+ * an uncaught exception); or until <code>System.exit</code> is called with
+ * adequate permissions.
+ *
+ * <p>It is unclear at what point a Thread should be added to a ThreadGroup,
+ * and at what point it should be removed. Should it be inserted when it
+ * starts, or when it is created?  Should it be removed when it is suspended
+ * or interrupted?  The only thing that is clear is that the Thread should be
+ * removed when it is stopped.
+ *
+ * @author Tom Tromey
+ * @author John Keiser
+ * @author Eric Blake (ebb9 at email.byu.edu)
+ * @see Runnable
+ * @see Runtime#exit(int)
+ * @see #run()
+ * @see #start()
+ * @see ThreadLocal
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public class Thread implements Runnable
+{
+  /** The minimum priority for a Thread. */
+  public static final int MIN_PRIORITY = 1;
+
+  /** The priority a Thread gets by default. */
+  public static final int NORM_PRIORITY = 5;
+
+  /** The maximum priority for a Thread. */
+  public static final int MAX_PRIORITY = 10;
+
+  /**
+   * The group this thread belongs to. This is set to null by
+   * ThreadGroup.removeThread when the thread dies.
+   */
+  ThreadGroup group;
+
+  /** The object to run(), null if this is the target. */
+  private Runnable runnable;
+
+  /** The thread name, non-null. */
+  String name;
+
+  /** Whether the thread is a daemon. */
+  private boolean daemon;
+
+  /** The thread priority, 1 to 10. */
+  private int priority;
+
+  boolean interrupt_flag;
+  private boolean alive_flag;
+  private boolean startable_flag;
+
+  /** The context classloader for this Thread. */
+  private ClassLoader contextClassLoader;
+
+  /** This thread's ID.  */
+  private final long threadId;
+
+  /** The next thread ID to use.  */
+  private static long nextThreadId;
+
+  /** The default exception handler.  */
+  private static UncaughtExceptionHandler defaultHandler;
+
+  /** Thread local storage. Package accessible for use by
+    * InheritableThreadLocal.
+    */
+  WeakIdentityHashMap locals;
+
+  /** The uncaught exception handler.  */
+  UncaughtExceptionHandler exceptionHandler;
+
+  /** The access control state for this thread.  Package accessible
+    * for use by java.security.VMAccessControlState's native method.
+    */
+  Object accessControlState = null;
+  
+  // This describes the top-most interpreter frame for this thread.
+  RawData interp_frame;
+
+  // Our native data - points to an instance of struct natThread.
+  private RawDataManaged data;
+
+  /**
+   * Allocates a new <code>Thread</code> object. This constructor has
+   * the same effect as <code>Thread(null, null,</code>
+   * <i>gname</i><code>)</code>, where <b><i>gname</i></b> is
+   * a newly generated name. Automatically generated names are of the
+   * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
+   * <p>
+   * Threads created this way must have overridden their
+   * <code>run()</code> method to actually do anything.  An example
+   * illustrating this method being used follows:
+   * <p><blockquote><pre>
+   *     import java.lang.*;
+   *
+   *     class plain01 implements Runnable {
+   *         String name;
+   *         plain01() {
+   *             name = null;
+   *         }
+   *         plain01(String s) {
+   *             name = s;
+   *         }
+   *         public void run() {
+   *             if (name == null)
+   *                 System.out.println("A new thread created");
+   *             else
+   *                 System.out.println("A new thread with name " + name +
+   *                                    " created");
+   *         }
+   *     }
+   *     class threadtest01 {
+   *         public static void main(String args[] ) {
+   *             int failed = 0 ;
+   *
+   *             <b>Thread t1 = new Thread();</b>
+   *             if (t1 != null)
+   *                 System.out.println("new Thread() succeed");
+   *             else {
+   *                 System.out.println("new Thread() failed");
+   *                 failed++;
+   *             }
+   *         }
+   *     }
+   * </pre></blockquote>
+   *
+   * @see     java.lang.Thread#Thread(java.lang.ThreadGroup,
+   *          java.lang.Runnable, java.lang.String)
+   */
+  public Thread()
+  {
+    this(null, null, gen_name());
+  }
+
+  /**
+   * Allocates a new <code>Thread</code> object. This constructor has
+   * the same effect as <code>Thread(null, target,</code>
+   * <i>gname</i><code>)</code>, where <i>gname</i> is
+   * a newly generated name. Automatically generated names are of the
+   * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
+   *
+   * @param target the object whose <code>run</code> method is called.
+   * @see java.lang.Thread#Thread(java.lang.ThreadGroup,
+   *                              java.lang.Runnable, java.lang.String)
+   */
+  public Thread(Runnable target)
+  {
+    this(null, target, gen_name());
+  }
+
+  /**
+   * Allocates a new <code>Thread</code> object. This constructor has
+   * the same effect as <code>Thread(null, null, name)</code>.
+   *
+   * @param   name   the name of the new thread.
+   * @see     java.lang.Thread#Thread(java.lang.ThreadGroup,
+   *          java.lang.Runnable, java.lang.String)
+   */
+  public Thread(String name)
+  {
+    this(null, null, name);
+  }
+
+  /**
+   * Allocates a new <code>Thread</code> object. This constructor has
+   * the same effect as <code>Thread(group, target,</code>
+   * <i>gname</i><code>)</code>, where <i>gname</i> is
+   * a newly generated name. Automatically generated names are of the
+   * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
+   *
+   * @param group the group to put the Thread into
+   * @param target the Runnable object to execute
+   * @throws SecurityException if this thread cannot access <code>group</code>
+   * @throws IllegalThreadStateException if group is destroyed
+   * @see #Thread(ThreadGroup, Runnable, String)
+   */
+  public Thread(ThreadGroup group, Runnable target)
+  {
+    this(group, target, gen_name());
+  }
+
+  /**
+   * Allocates a new <code>Thread</code> object. This constructor has
+   * the same effect as <code>Thread(group, null, name)</code>
+   *
+   * @param group the group to put the Thread into
+   * @param name the name for the Thread
+   * @throws NullPointerException if name is null
+   * @throws SecurityException if this thread cannot access <code>group</code>
+   * @throws IllegalThreadStateException if group is destroyed
+   * @see #Thread(ThreadGroup, Runnable, String)
+   */
+  public Thread(ThreadGroup group, String name)
+  {
+    this(group, null, name);
+  }
+
+  /**
+   * Allocates a new <code>Thread</code> object. This constructor has
+   * the same effect as <code>Thread(null, target, name)</code>.
+   *
+   * @param target the Runnable object to execute
+   * @param name the name for the Thread
+   * @throws NullPointerException if name is null
+   * @see #Thread(ThreadGroup, Runnable, String)
+   */
+  public Thread(Runnable target, String name)
+  {
+    this(null, target, name);
+  }
+
+  /**
+   * Allocate a new Thread object, with the specified ThreadGroup and name, and
+   * using the specified Runnable object's <code>run()</code> method to
+   * execute.  If the Runnable object is null, <code>this</code> (which is
+   * a Runnable) is used instead.
+   *
+   * <p>If the ThreadGroup is null, the security manager is checked. If a
+   * manager exists and returns a non-null object for
+   * <code>getThreadGroup</code>, that group is used; otherwise the group
+   * of the creating thread is used. Note that the security manager calls
+   * <code>checkAccess</code> if the ThreadGroup is not null.
+   *
+   * <p>The new Thread will inherit its creator's priority and daemon status.
+   * These can be changed with <code>setPriority</code> and
+   * <code>setDaemon</code>.
+   *
+   * @param group the group to put the Thread into
+   * @param target the Runnable object to execute
+   * @param name the name for the Thread
+   * @throws NullPointerException if name is null
+   * @throws SecurityException if this thread cannot access <code>group</code>
+   * @throws IllegalThreadStateException if group is destroyed
+   * @see Runnable#run()
+   * @see #run()
+   * @see #setDaemon(boolean)
+   * @see #setPriority(int)
+   * @see SecurityManager#checkAccess(ThreadGroup)
+   * @see ThreadGroup#checkAccess()
+   */
+  public Thread(ThreadGroup group, Runnable target, String name)
+  {
+    this(currentThread(), group, target, name);
+  }
+
+  /**
+   * Allocate a new Thread object, as if by
+   * <code>Thread(group, null, name)</code>, and give it the specified stack
+   * size, in bytes. The stack size is <b>highly platform independent</b>,
+   * and the virtual machine is free to round up or down, or ignore it
+   * completely.  A higher value might let you go longer before a
+   * <code>StackOverflowError</code>, while a lower value might let you go
+   * longer before an <code>OutOfMemoryError</code>.  Or, it may do absolutely
+   * nothing! So be careful, and expect to need to tune this value if your
+   * virtual machine even supports it.
+   *
+   * @param group the group to put the Thread into
+   * @param target the Runnable object to execute
+   * @param name the name for the Thread
+   * @param size the stack size, in bytes; 0 to be ignored
+   * @throws NullPointerException if name is null
+   * @throws SecurityException if this thread cannot access <code>group</code>
+   * @throws IllegalThreadStateException if group is destroyed
+   * @since 1.4
+   */
+  public Thread(ThreadGroup group, Runnable target, String name, long size)
+  {
+    // Just ignore stackSize for now.
+    this(currentThread(), group, target, name);
+  }
+
+  private Thread (Thread current, ThreadGroup g, Runnable r, String n)
+  {
+    // Make sure the current thread may create a new thread.
+    checkAccess();
+    
+    // The Class Libraries book says ``threadName cannot be null''.  I
+    // take this to mean NullPointerException.
+    if (n == null)
+      throw new NullPointerException ();
+      
+    if (g == null)
+      {
+	// If CURRENT is null, then we are bootstrapping the first thread. 
+	// Use ThreadGroup.root, the main threadgroup.
+	if (current == null)
+	  group = ThreadGroup.root;
+	else
+	  group = current.getThreadGroup();
+      }
+    else
+      group = g;
+
+    data = null;
+    interrupt_flag = false;
+    alive_flag = false;
+    startable_flag = true;
+
+    synchronized (Thread.class)
+      {
+        this.threadId = nextThreadId++;
+      }
+
+    if (current != null)
+      {
+	group.checkAccess();
+
+	daemon = current.isDaemon();
+        int gmax = group.getMaxPriority();
+	int pri = current.getPriority();
+	priority = (gmax < pri ? gmax : pri);
+	contextClassLoader = current.contextClassLoader;
+	InheritableThreadLocal.newChildThread(this);
+      }
+    else
+      {
+	daemon = false;
+	priority = NORM_PRIORITY;
+      }
+
+    name = n;
+    group.addThread(this);
+    runnable = r;
+
+    initialize_native ();
+  }
+
+  /**
+   * Get the number of active threads in the current Thread's ThreadGroup.
+   * This implementation calls
+   * <code>currentThread().getThreadGroup().activeCount()</code>.
+   *
+   * @return the number of active threads in the current ThreadGroup
+   * @see ThreadGroup#activeCount()
+   */
+  public static int activeCount()
+  {
+    return currentThread().group.activeCount();
+  }
+
+  /**
+   * Check whether the current Thread is allowed to modify this Thread. This
+   * passes the check on to <code>SecurityManager.checkAccess(this)</code>.
+   *
+   * @throws SecurityException if the current Thread cannot modify this Thread
+   * @see SecurityManager#checkAccess(Thread)
+   */
+  public final void checkAccess()
+  {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      sm.checkAccess(this);
+  }
+
+  /**
+   * Count the number of stack frames in this Thread.  The Thread in question
+   * must be suspended when this occurs.
+   *
+   * @return the number of stack frames in this Thread
+   * @throws IllegalThreadStateException if this Thread is not suspended
+   * @deprecated pointless, since suspend is deprecated
+   */
+  public native int countStackFrames();
+
+  /**
+   * Get the currently executing Thread.
+   *
+   * @return the currently executing Thread
+   */
+  public static native Thread currentThread();
+
+  /**
+   * Originally intended to destroy this thread, this method was never
+   * implemented by Sun, and is hence a no-op.
+   */
+  public void destroy()
+  {
+    throw new NoSuchMethodError();
+  }
+  
+  /**
+   * Print a stack trace of the current thread to stderr using the same
+   * format as Throwable's printStackTrace() method.
+   *
+   * @see Throwable#printStackTrace()
+   */
+  public static void dumpStack()
+  {
+    (new Exception("Stack trace")).printStackTrace();
+  }
+
+  /**
+   * Copy every active thread in the current Thread's ThreadGroup into the
+   * array. Extra threads are silently ignored. This implementation calls
+   * <code>getThreadGroup().enumerate(array)</code>, which may have a
+   * security check, <code>checkAccess(group)</code>.
+   *
+   * @param array the array to place the Threads into
+   * @return the number of Threads placed into the array
+   * @throws NullPointerException if array is null
+   * @throws SecurityException if you cannot access the ThreadGroup
+   * @see ThreadGroup#enumerate(Thread[])
+   * @see #activeCount()
+   * @see SecurityManager#checkAccess(ThreadGroup)
+   */
+  public static int enumerate(Thread[] array)
+  {
+    return currentThread().group.enumerate(array);
+  }
+  
+  /**
+   * Get this Thread's name.
+   *
+   * @return this Thread's name
+   */
+  public final String getName()
+  {
+    return name;
+  }
+
+  /**
+   * Get this Thread's priority.
+   *
+   * @return the Thread's priority
+   */
+  public final int getPriority()
+  {
+    return priority;
+  }
+
+  /**
+   * Get the ThreadGroup this Thread belongs to. If the thread has died, this
+   * returns null.
+   *
+   * @return this Thread's ThreadGroup
+   */
+  public final ThreadGroup getThreadGroup()
+  {
+    return group;
+  }
+
+  /**
+   * 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 test lock ownership on.
+   * @return true if the current thread is currently synchronized on obj
+   * @throws NullPointerException if obj is null
+   * @since 1.4
+   */
+  public static native boolean holdsLock(Object obj);
+
+  /**
+   * Interrupt this Thread. First, there is a security check,
+   * <code>checkAccess</code>. Then, depending on the current state of the
+   * thread, various actions take place:
+   *
+   * <p>If the thread is waiting because of {@link #wait()},
+   * {@link #sleep(long)}, or {@link #join()}, its <i>interrupt status</i>
+   * will be cleared, and an InterruptedException will be thrown. Notice that
+   * this case is only possible if an external thread called interrupt().
+   *
+   * <p>If the thread is blocked in an interruptible I/O operation, in
+   * {@link java.nio.channels.InterruptibleChannel}, the <i>interrupt
+   * status</i> will be set, and ClosedByInterruptException will be thrown.
+   *
+   * <p>If the thread is blocked on a {@link java.nio.channels.Selector}, the
+   * <i>interrupt status</i> will be set, and the selection will return, with
+   * a possible non-zero value, as though by the wakeup() method.
+   *
+   * <p>Otherwise, the interrupt status will be set.
+   *
+   * @throws SecurityException if you cannot modify this Thread
+   */
+  public native void interrupt();
+
+  /**
+   * 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
+   * @see #isInterrupted()
+   */
+  public static boolean interrupted()
+  {
+    return currentThread().isInterrupted(true);
+  }
+
+  /**
+   * Determine whether the given Thread has been interrupted, but leave
+   * the <i>interrupted status</i> alone in the process.
+   *
+   * @return whether the Thread has been interrupted
+   * @see #interrupted()
+   */
+  public boolean isInterrupted()
+  {
+    return interrupt_flag;
+  }
+
+  /**
+   * Determine whether this Thread is alive. A thread which is alive has
+   * started and not yet died.
+   *
+   * @return whether this Thread is alive
+   */
+  public final synchronized boolean isAlive()
+  {
+    return alive_flag;
+  }
+
+  /**
+   * Tell whether this is a daemon Thread or not.
+   *
+   * @return whether this is a daemon Thread or not
+   * @see #setDaemon(boolean)
+   */
+  public final boolean isDaemon()
+  {
+    return daemon;
+  }
+
+  /**
+   * Wait forever for the Thread in question to die.
+   *
+   * @throws InterruptedException if the Thread is interrupted; it's
+   *         <i>interrupted status</i> will be cleared
+   */
+  public final void join() throws InterruptedException
+  {
+    join(0, 0);
+  }
+
+  /**
+   * Wait the specified amount of time for the Thread in question to die.
+   *
+   * @param ms the number of milliseconds to wait, or 0 for forever
+   * @throws InterruptedException if the Thread is interrupted; it's
+   *         <i>interrupted status</i> will be cleared
+   */
+  public final void join(long ms) throws InterruptedException
+  {
+    join(ms, 0);
+  }
+
+  /**
+   * 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
+   * @throws IllegalArgumentException if ns is invalid
+   * @XXX A ThreadListener would be nice, to make this efficient.
+   */
+  public final native void join(long ms, int ns)
+    throws InterruptedException;
+
+  /**
+   * Resume a suspended thread.
+   *
+   * @throws SecurityException if you cannot resume the Thread
+   * @see #checkAccess()
+   * @see #suspend()
+   * @deprecated pointless, since suspend is deprecated
+   */
+  public final native void resume();
+
+  private final native void finish_();
+
+  /**
+   * Determine whether the given Thread has been interrupted, but leave
+   * the <i>interrupted status</i> alone in the process.
+   *
+   * @return whether the current Thread has been interrupted
+   * @see #interrupted()
+   */
+  private boolean isInterrupted(boolean clear_flag)
+  {
+    boolean r = interrupt_flag;
+    if (clear_flag && r)
+      {
+	// Only clear the flag if we saw it as set. Otherwise this could 
+	// potentially cause us to miss an interrupt in a race condition, 
+	// because this method is not synchronized.
+	interrupt_flag = false;
+      }
+    return r;
+  }
+  
+  /**
+   * The method of Thread that will be run if there is no Runnable object
+   * associated with the Thread. Thread's implementation does nothing at all.
+   *
+   * @see #start()
+   * @see #Thread(ThreadGroup, Runnable, String)
+   */
+  public void run()
+  {
+    if (runnable != null)
+      runnable.run();
+  }
+
+  /**
+   * Set the daemon status of this Thread.  If this is a daemon Thread, then
+   * the VM may exit even if it is still running.  This may only be called
+   * before the Thread starts running. There may be a security check,
+   * <code>checkAccess</code>.
+   *
+   * @param daemon whether this should be a daemon thread or not
+   * @throws SecurityException if you cannot modify this Thread
+   * @throws IllegalThreadStateException if the Thread is active
+   * @see #isDaemon()
+   * @see #checkAccess()
+   */
+  public final void setDaemon(boolean daemon)
+  {
+    if (!startable_flag)
+      throw new IllegalThreadStateException();
+    checkAccess();
+    this.daemon = daemon;
+  }
+
+  /**
+   * Returns the context classloader of this Thread. The context
+   * classloader can be used by code that want to load classes depending
+   * on the current thread. Normally classes are loaded depending on
+   * the classloader of the current class. There may be a security check
+   * for <code>RuntimePermission("getClassLoader")</code> if the caller's
+   * class loader is not null or an ancestor of this thread's context class
+   * loader.
+   *
+   * @return the context class loader
+   * @throws SecurityException when permission is denied
+   * @see setContextClassLoader(ClassLoader)
+   * @since 1.2
+   */
+  public synchronized ClassLoader getContextClassLoader()
+  {
+    if (contextClassLoader == null)
+      contextClassLoader = ClassLoader.getSystemClassLoader();
+
+    SecurityManager sm = System.getSecurityManager();
+    // FIXME: we can't currently find the caller's class loader.
+    ClassLoader callers = null;
+    if (sm != null && callers != null)
+      {
+	// See if the caller's class loader is the same as or an
+	// ancestor of this thread's class loader.
+	while (callers != null && callers != contextClassLoader)
+	  {
+	    // FIXME: should use some internal version of getParent
+	    // that avoids security checks.
+	    callers = callers.getParent();
+	  }
+
+	if (callers != contextClassLoader)
+	  sm.checkPermission(new RuntimePermission("getClassLoader"));
+      }
+
+    return contextClassLoader;
+  }
+
+  /**
+   * Sets the context classloader for this Thread. When not explicitly set,
+   * the context classloader for a thread is the same as the context
+   * classloader of the thread that created this thread. The first thread has
+   * as context classloader the system classloader. There may be a security
+   * check for <code>RuntimePermission("setContextClassLoader")</code>.
+   *
+   * @param classloader the new context class loader
+   * @throws SecurityException when permission is denied
+   * @see getContextClassLoader()
+   * @since 1.2
+   */
+  public synchronized void setContextClassLoader(ClassLoader classloader)
+  {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+    this.contextClassLoader = classloader;
+  }
+
+  /**
+   * Set this Thread's name.  There may be a security check,
+   * <code>checkAccess</code>.
+   *
+   * @param name the new name for this Thread
+   * @throws NullPointerException if name is null
+   * @throws SecurityException if you cannot modify this Thread
+   */
+  public final void setName(String name)
+  {
+    checkAccess();
+    // The Class Libraries book says ``threadName cannot be null''.  I
+    // take this to mean NullPointerException.
+    if (name == null)
+      throw new NullPointerException();
+    this.name = name;
+  }
+
+  /**
+   * Causes the currently executing thread object to temporarily pause
+   * and allow other threads to execute.
+   */
+  public 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.
+   *
+   * @param ms the number of milliseconds to sleep, or 0 for forever
+   * @throws InterruptedException if the Thread is interrupted; it's
+   *         <i>interrupted status</i> will be cleared
+   * @see #notify()
+   * @see #wait(long)
+   */
+  public static void sleep(long ms) throws InterruptedException
+  {
+    sleep(ms, 0);
+  }
+
+  /**
+   * 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, 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
+   * @throws IllegalArgumentException if ns is invalid
+   * @see #notify()
+   * @see #wait(long, int)
+   */
+  public static native void sleep(long timeout, int nanos)
+    throws InterruptedException;
+
+  /**
+   * Start this Thread, calling the run() method of the Runnable this Thread
+   * was created with, or else the run() method of the Thread itself. This
+   * is the only way to start a new thread; calling run by yourself will just
+   * stay in the same thread. The virtual machine will remove the thread from
+   * its thread group when the run() method completes.
+   *
+   * @throws IllegalThreadStateException if the thread has already started
+   * @see #run()
+   */
+  public native void start();
+
+  /**
+   * Cause this Thread to stop abnormally because of the throw of a ThreadDeath
+   * error. If you stop a Thread that has not yet started, it will stop
+   * immediately when it is actually started.
+   *
+   * <p>This is inherently unsafe, as it can interrupt synchronized blocks and
+   * leave data in bad states.  Hence, there is a security check:
+   * <code>checkAccess(this)</code>, plus another one if the current thread
+   * is not this: <code>RuntimePermission("stopThread")</code>. If you must
+   * catch a ThreadDeath, be sure to rethrow it after you have cleaned up.
+   * ThreadDeath is the only exception which does not print a stack trace when
+   * the thread dies.
+   *
+   * @throws SecurityException if you cannot stop the Thread
+   * @see #interrupt()
+   * @see #checkAccess()
+   * @see #start()
+   * @see ThreadDeath
+   * @see ThreadGroup#uncaughtException(Thread, Throwable)
+   * @see SecurityManager#checkAccess(Thread)
+   * @see SecurityManager#checkPermission(Permission)
+   * @deprecated unsafe operation, try not to use
+   */
+  public final void stop()
+  {
+    // Argument doesn't matter, because this is no longer
+    // supported.
+    stop(null);
+  }
+
+  /**
+   * Cause this Thread to stop abnormally and throw the specified exception.
+   * If you stop a Thread that has not yet started, it will stop immediately
+   * when it is actually started. <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.  Hence, there is a security check:
+   * <code>checkAccess(this)</code>, plus another one if the current thread
+   * is not this: <code>RuntimePermission("stopThread")</code>. If you must
+   * catch a ThreadDeath, be sure to rethrow it after you have cleaned up.
+   * ThreadDeath is the only exception which does not print a stack trace when
+   * the thread dies.
+   *
+   * @param t the Throwable to throw when the Thread dies
+   * @throws SecurityException if you cannot stop the Thread
+   * @throws NullPointerException in the calling thread, if t is null
+   * @see #interrupt()
+   * @see #checkAccess()
+   * @see #start()
+   * @see ThreadDeath
+   * @see ThreadGroup#uncaughtException(Thread, Throwable)
+   * @see SecurityManager#checkAccess(Thread)
+   * @see SecurityManager#checkPermission(Permission)
+   * @deprecated unsafe operation, try not to use
+   */
+  public final native void stop(Throwable t);
+
+  /**
+   * Suspend this Thread.  It will not come back, ever, unless it is resumed.
+   *
+   * <p>This is inherently unsafe, as the suspended thread still holds locks,
+   * and can potentially deadlock your program.  Hence, there is a security
+   * check: <code>checkAccess</code>.
+   *
+   * @throws SecurityException if you cannot suspend the Thread
+   * @see #checkAccess()
+   * @see #resume()
+   * @deprecated unsafe operation, try not to use
+   */
+  public final native void suspend();
+
+  /**
+   * Set this Thread's priority. There may be a security check,
+   * <code>checkAccess</code>, then the priority is set to the smaller of
+   * priority and the ThreadGroup maximum priority.
+   *
+   * @param priority the new priority for this Thread
+   * @throws IllegalArgumentException if priority exceeds MIN_PRIORITY or
+   *         MAX_PRIORITY
+   * @throws SecurityException if you cannot modify this Thread
+   * @see #getPriority()
+   * @see #checkAccess()
+   * @see ThreadGroup#getMaxPriority()
+   * @see #MIN_PRIORITY
+   * @see #MAX_PRIORITY
+   */
+  public final native void setPriority(int newPriority);
+
+  /**
+   * Returns a string representation of this thread, including the
+   * thread's name, priority, and thread group.
+   *
+   * @return a human-readable String representing this Thread
+   */
+  public String toString()
+  {
+    return ("Thread[" + name + "," + priority + ","
+	    + (group == null ? "" : group.getName()) + "]");
+  }
+
+  private final native void initialize_native();
+
+  private final native static String gen_name();
+
+  /**
+   * Returns the map used by ThreadLocal to store the thread local values.
+   */
+  static Map getThreadLocals()
+  {
+    Thread thread = currentThread();
+    Map locals = thread.locals;
+    if (locals == null)
+      {
+        locals = thread.locals = new WeakIdentityHashMap();
+      }
+    return locals;
+  }
+
+  /** 
+   * Assigns the given <code>UncaughtExceptionHandler</code> to this
+   * thread.  This will then be called if the thread terminates due
+   * to an uncaught exception, pre-empting that of the
+   * <code>ThreadGroup</code>.
+   *
+   * @param h the handler to use for this thread.
+   * @throws SecurityException if the current thread can't modify this thread.
+   * @since 1.5 
+   */
+  public void setUncaughtExceptionHandler(UncaughtExceptionHandler h)
+  {
+    SecurityManager sm = SecurityManager.current; // Be thread-safe.
+    if (sm != null)
+      sm.checkAccess(this);    
+    exceptionHandler = h;
+  }
+
+  /** 
+   * <p>
+   * Returns the handler used when this thread terminates due to an
+   * uncaught exception.  The handler used is determined by the following:
+   * </p>
+   * <ul>
+   * <li>If this thread has its own handler, this is returned.</li>
+   * <li>If not, then the handler of the thread's <code>ThreadGroup</code>
+   * object is returned.</li>
+   * <li>If both are unavailable, then <code>null</code> is returned
+   *     (which can only happen when the thread was terminated since
+   *      then it won't have an associated thread group anymore).</li>
+   * </ul>
+   * 
+   * @return the appropriate <code>UncaughtExceptionHandler</code> or
+   *         <code>null</code> if one can't be obtained.
+   * @since 1.5 
+   */
+  public UncaughtExceptionHandler getUncaughtExceptionHandler()
+  {
+    return exceptionHandler != null ? exceptionHandler : group;
+  }
+
+  /** 
+   * <p>
+   * Sets the default uncaught exception handler used when one isn't
+   * provided by the thread or its associated <code>ThreadGroup</code>.
+   * This exception handler is used when the thread itself does not
+   * have an exception handler, and the thread's <code>ThreadGroup</code>
+   * does not override this default mechanism with its own.  As the group
+   * calls this handler by default, this exception handler should not defer
+   * to that of the group, as it may lead to infinite recursion.
+   * </p>
+   * <p>
+   * Uncaught exception handlers are used when a thread terminates due to
+   * an uncaught exception.  Replacing this handler allows default code to
+   * be put in place for all threads in order to handle this eventuality.
+   * </p>
+   *
+   * @param h the new default uncaught exception handler to use.
+   * @throws SecurityException if a security manager is present and
+   *                           disallows the runtime permission
+   *                           "setDefaultUncaughtExceptionHandler".
+   * @since 1.5 
+   */
+  public static void 
+    setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler h)
+  {
+    SecurityManager sm = SecurityManager.current; // Be thread-safe.
+    if (sm != null)
+      sm.checkPermission(new RuntimePermission("setDefaultUncaughtExceptionHandler"));    
+    defaultHandler = h;
+  }
+
+  /** 
+   * Returns the handler used by default when a thread terminates
+   * unexpectedly due to an exception, or <code>null</code> if one doesn't
+   * exist.
+   *
+   * @return the default uncaught exception handler.
+   * @since 1.5 
+   */
+  public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler()
+  {
+    return defaultHandler;
+  }
+  
+  /** 
+   * Returns the unique identifier for this thread.  This ID is generated
+   * on thread creation, and may be re-used on its death.
+   *
+   * @return a positive long number representing the thread's ID.
+   * @since 1.5 
+   */
+  public long getId()
+  {
+    return threadId;
+  }
+
+  /**
+   * <p>
+   * This interface is used to handle uncaught exceptions
+   * which cause a <code>Thread</code> to terminate.  When
+   * a thread, t, is about to terminate due to an uncaught
+   * exception, the virtual machine looks for a class which
+   * implements this interface, in order to supply it with
+   * the dying thread and its uncaught exception.
+   * </p>
+   * <p>
+   * The virtual machine makes two attempts to find an
+   * appropriate handler for the uncaught exception, in
+   * the following order:
+   * </p>
+   * <ol>
+   * <li>
+   * <code>t.getUncaughtExceptionHandler()</code> --
+   * the dying thread is queried first for a handler
+   * specific to that thread.
+   * </li>
+   * <li>
+   * <code>t.getThreadGroup()</code> --
+   * the thread group of the dying thread is used to
+   * handle the exception.  If the thread group has
+   * no special requirements for handling the exception,
+   * it may simply forward it on to
+   * <code>Thread.getDefaultUncaughtExceptionHandler()</code>,
+   * the default handler, which is used as a last resort.
+   * </li>
+   * </ol>
+   * <p>
+   * The first handler found is the one used to handle
+   * the uncaught exception.
+   * </p>
+   *
+   * @author Tom Tromey <tromey at redhat.com>
+   * @author Andrew John Hughes <gnu_andrew at member.fsf.org>
+   * @since 1.5
+   * @see Thread#getUncaughtExceptionHandler()
+   * @see Thread#setUncaughtExceptionHander(java.lang.Thread.UncaughtExceptionHandler)
+   * @see Thread#getDefaultUncaughtExceptionHandler()
+   * @see
+   * Thread#setDefaultUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler)
+   */
+  public interface UncaughtExceptionHandler
+  {
+    /**
+     * Invoked by the virtual machine with the dying thread
+     * and the uncaught exception.  Any exceptions thrown
+     * by this method are simply ignored by the virtual
+     * machine.
+     *
+     * @param thr the dying thread.
+     * @param exc the uncaught exception.
+     */
+    void uncaughtException(Thread thr, Throwable exc);
+  }
+
+  /**
+   * Returns the current state of the thread.  This
+   * is designed for monitoring thread behaviour, rather
+   * than for synchronization control.
+   *
+   * @return the current thread state.
+   */
+  public String getState()
+  {
+    // FIXME - Provide real implementation.
+    return "NEW";
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/VMClassLoader.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/VMClassLoader.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/VMClassLoader.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/VMClassLoader.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,348 @@
+/* VMClassLoader.java -- Reference implementation of native interface
+   required by ClassLoader
+   Copyright (C) 1998, 2001, 2002, 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;
+
+import gnu.java.util.EmptyEnumeration;
+import java.lang.reflect.Constructor;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.AllPermission;
+import java.security.Permission;
+import java.security.Permissions;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.StringTokenizer;
+import gnu.gcj.runtime.BootClassLoader;
+
+/**
+ * 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 at klomp.org>
+ * @author Eric Blake <ebb9 at email.byu.edu>
+ */
+final class VMClassLoader
+{
+  // Protection Domain definitions 
+  // FIXME: should there be a special protection domain used for native code?
+  
+  // The permission required to check what a classes protection domain is.
+  static final Permission protectionDomainPermission
+    = new RuntimePermission("getProtectionDomain");
+  // The protection domain returned if we cannot determine it. 
+  static ProtectionDomain unknownProtectionDomain;
+
+  static
+  {
+    Permissions permissions = new Permissions();
+    permissions.add(new AllPermission());
+    unknownProtectionDomain = new ProtectionDomain(null, permissions);  
+  }
+
+  static final HashMap definedPackages = new HashMap();
+
+  // This is a helper for handling java.endorsed.dirs.  It is null
+  // until we've initialized the system, at which point it is created.
+  static BootClassLoader bootLoader;
+
+  // This keeps track of shared libraries we've already tried to load.
+  private static HashSet tried_libraries;
+
+  // Holds one of the LIB_* constants; used to determine how shared
+  // library loads are done.
+  private static int lib_control;
+
+  private static final int LIB_FULL = 0;
+  private static final int LIB_CACHE = 1;
+  private static final int LIB_NEVER = 2;
+
+  /**
+   * Helper to define a class using a string of bytes. This assumes that
+   * the security checks have already been performed, if necessary.
+   *
+   * <strong>For backward compatibility, this just ignores the protection
+   * domain; that is the wrong behavior, and you should directly implement
+   * this method natively if you can.</strong>
+   *
+   * @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 void resolveClass(Class clazz)
+  {
+    // There doesn't seem to be a need for this to do anything.
+    // Testing reveals that the JDK doesn't seem to do anything here,
+    // either.
+  }
+
+  /**
+   * 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.
+   *
+   * In libgcj, this does nothing, as the default system loader knows
+   * how to find resources that have been linked in.
+   *
+   * @param name the resource to find
+   * @return the URL to the resource
+   */
+  static URL getResource(String name)
+  {
+    if (bootLoader != null)
+      return bootLoader.bootGetResource(name);
+    return null;
+  }
+
+  /**
+   * Helper to get a list of resources from the bootstrap class loader.
+   *
+   * In libgcj, this does nothing, as the default system loader knows
+   * how to find resources that have been linked in.
+   *
+   * @param name the resource to find
+   * @return an enumeration of resources
+   * @throws IOException if one occurs
+   */
+  static Enumeration getResources(String name) throws IOException
+  {
+    if (bootLoader != null)
+      return bootLoader.bootGetResources(name);
+    return EmptyEnumeration.getInstance();
+  }
+
+  /**
+   * 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 synchronized Package getPackage(String name)
+  {
+    return (Package) definedPackages.get(name);
+  }
+
+  /**
+   * 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 synchronized Package[] getPackages()
+  {
+    Package[] packages = new Package[definedPackages.size()];
+    return (Package[]) definedPackages.values().toArray(packages);
+  }
+
+  // Define a package for something loaded natively.
+  static synchronized void definePackageForNative(String className)
+  {
+    int lastDot = className.lastIndexOf('.');
+    if (lastDot != -1)
+      {
+	String packageName = className.substring(0, lastDot);
+	if (getPackage(packageName) == null)
+	  {
+	    // FIXME: this assumes we're defining the core, which
+	    // isn't necessarily so.  We could detect this and set up
+	    // appropriately.  We could also look at a manifest file
+	    // compiled into the .so.
+	    Package p = new Package(packageName,
+				    "Java Platform API Specification",
+				    "GNU", "1.4", "gcj", "GNU",
+				    null, // FIXME: gcj version.
+				    null);
+	    definedPackages.put(packageName, p);
+	  }
+      }
+  }
+
+  /**
+   * 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 native ClassLoader getSystemClassLoaderInternal();
+
+  static native void initBootLoader(String libdir);
+
+  static void initialize(String libdir)
+  {
+    initBootLoader(libdir);
+
+    String p
+      = System.getProperty ("gnu.gcj.runtime.VMClassLoader.library_control",
+			    "");
+    if ("never".equals(p))
+      lib_control = LIB_NEVER;
+    else if ("cache".equals(p))
+      lib_control = LIB_CACHE;
+    else if ("full".equals(p))
+      lib_control = LIB_FULL;
+    else
+      lib_control = LIB_NEVER;
+
+    tried_libraries = new HashSet();
+  }
+
+  /**
+   * Possibly load a .so and search it for classes.
+   */
+  static native Class nativeFindClass(String name);
+
+  static ClassLoader getSystemClassLoader()
+  {
+    // This method is called as the initialization of systemClassLoader,
+    // so if there is a null value, this is the first call and we must check
+    // for java.system.class.loader.
+    String loader = System.getProperty("java.system.class.loader");
+    ClassLoader default_sys = getSystemClassLoaderInternal();
+    if (loader != null)
+      {
+	try
+	  {
+	    Class load_class = Class.forName(loader, true, default_sys);
+	    Constructor c
+	      = load_class.getConstructor(new Class[] { ClassLoader.class });
+	    default_sys
+	      = (ClassLoader) c.newInstance(new Object[] { default_sys });
+	  }
+	catch (Exception ex)
+	  {
+	    throw new Error("Failed to load requested system classloader "
+			       + loader, ex);
+	  }
+      }
+
+    return default_sys;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/VMCompiler.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/VMCompiler.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/VMCompiler.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/VMCompiler.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,360 @@
+/* VMClassLoader.java -- Reference implementation of compiler interface
+   Copyright (C) 2004, 2005, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.security.MessageDigest;
+import java.security.ProtectionDomain;
+import java.security.NoSuchAlgorithmException;
+import java.util.WeakHashMap;
+import java.util.HashSet;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import gnu.gcj.runtime.SharedLibHelper;
+import gnu.gcj.runtime.PersistentByteMap;
+import gnu.java.security.hash.MD5;
+
+/**
+ * This class is just a per-VM reflection of java.lang.Compiler.
+ * All methods are defined identically.
+ */
+final class VMCompiler
+{
+  // True if we want to use gcj-jit.
+  public static boolean useCompiler = true;
+
+  // True if we're able to use gcj-jit.
+  public static final boolean canUseCompiler;
+
+  // Compiler to use.
+  public static String gcjJitCompiler;
+
+  // Compiler options.
+  public static String gcjJitCompilerOptions;
+
+  // Temporary directory to use.
+  public static String gcjJitTmpdir;
+
+  // This maps a ClassLoader to a set of SharedLibHelper objects that
+  // it has used.  We do things this way to ensure that a
+  // SharedLibHelper is collected if and only if the ClassLoader is.
+  private static WeakHashMap sharedHelperMap = new WeakHashMap();
+
+  private static Vector precompiledMapFiles;
+
+  // We create a single MD5 engine and then clone it whenever we want
+  // a new one.
+
+  // We don't use 
+  //
+  // md5Digest = MessageDigest.getInstance("MD5");
+  //
+  // here because that loads a great deal of security provider code as
+  // interpreted bytecode -- before we're able to use this class to
+  // load precompiled classes.
+
+  private static final MD5 md5Digest
+    = new gnu.java.security.hash.MD5();
+
+  static
+  {
+    gcjJitCompiler = System.getProperty("gnu.gcj.jit.compiler");
+    if (gcjJitCompiler == null)
+      canUseCompiler = false;
+    else
+      {
+	gcjJitCompilerOptions = System.getProperty("gnu.gcj.jit.options",
+						   "-g");
+	gcjJitTmpdir = System.getProperty("gnu.gcj.jit.cachedir");
+	// Note that we *don't* choose java.io.tmpdir as a default --
+	// that would allow easy attacks against the VM.
+	if (gcjJitTmpdir == null)
+	  canUseCompiler = false;
+	else
+	  canUseCompiler = true;
+      }
+
+    String prop = System.getProperty ("gnu.gcj.precompiled.db.path");
+    if (prop != null)
+      {
+	precompiledMapFiles = new Vector();
+	// Add the 
+	StringTokenizer st
+	  = new StringTokenizer (prop,
+				 System.getProperty ("path.separator", ":"));
+	{
+	  while (st.hasMoreElements ()) 
+	    {  
+	      String e = st.nextToken ();
+	      try
+		{
+		  PersistentByteMap map 
+		    = new PersistentByteMap
+		    (e, PersistentByteMap.AccessMode.READ_ONLY);
+		  precompiledMapFiles.add(map);
+		}
+	      catch (IllegalArgumentException _)
+		{
+		  // Not a map file	      
+		}
+	      catch (java.io.IOException _)
+		{
+		}
+	      catch (java.nio.BufferUnderflowException _)
+		{
+		  // Invalid map file.
+		}
+	    }
+	}
+      }
+  }
+
+  /**
+   * Don't allow new `Compiler's to be made.
+   */
+  private VMCompiler()
+  {
+  }
+
+  private static Class loadSharedLibrary(ClassLoader loader,
+					 String fileName,
+					 ProtectionDomain domain,
+					 String className)
+  {
+    Class c = null;
+    SharedLibHelper helper 
+	= SharedLibHelper.findHelper (loader, fileName, domain.getCodeSource(), 
+				      domain, false);
+    c = helper.findClass (className);
+    if (c != null)
+      {
+	HashSet hs = (HashSet) sharedHelperMap.get(loader);
+	if (hs == null)
+	  {
+	    hs = new HashSet();
+	    sharedHelperMap.put(loader, hs);
+	  }
+	hs.add(helper);
+      }
+    return c;
+  }
+
+  /**
+   * Compile a class given the bytes for it.  Returns the Class, or
+   * null if compilation failed or otherwise could not be done.
+   */
+  public static Class compileClass(ClassLoader loader,
+				   String name, byte[] data,
+				   int offset, int len,
+				   ProtectionDomain domain)
+  {
+    if (precompiledMapFiles == null
+	&& (! useCompiler || ! canUseCompiler))
+      return null;
+
+    byte digest[];
+
+    try
+      {
+	MD5 md = (MD5) md5Digest.clone();
+	md.update(data);
+	digest = md.digest();
+      }
+    catch (NullPointerException _)
+      {
+	// If md5Digest==null -- but really this should never happen
+	// either, since the MD5 digest is in libgcj.
+	return null;
+      }
+
+    // We use lookaside cache files to determine whether these bytes
+    // correspond to a class file that is part of a precompiled DSO.
+    if (precompiledMapFiles != null)
+      {
+	try
+	  {
+	    Enumeration elements = precompiledMapFiles.elements();
+	    while (elements.hasMoreElements())
+	      {
+		PersistentByteMap map = (PersistentByteMap)elements.nextElement();
+		byte[] soName = map.get(digest);
+		if (soName != null)
+		  return loadSharedLibrary(loader, 
+					   new String(soName), 
+					   domain, name);
+	      }
+	  }
+	catch (Exception _)
+	  {
+	  }
+	catch (UnknownError _)
+	  {
+	    // SharedLibHelper will throw UnknownError if the dlopen
+	    // fails for some reason.  We ignore it and continue on.
+	  }
+      }
+ 
+    if (! useCompiler || ! canUseCompiler)
+      return null;
+
+    try
+      {
+	// FIXME: Make sure that the class represented by the
+	// bytes in DATA really is the class named in NAME.  Make
+	// sure it's not "java.*".
+	StringBuffer hexBytes = new StringBuffer(gcjJitTmpdir);
+	hexBytes.append(File.separatorChar);
+	int digestLength = digest.length;
+	for (int i = 0; i < digestLength; ++i)
+	  hexBytes.append(Integer.toHexString(digest[i] & 0xff));
+
+	// FIXME: use System.mapLibraryName?
+	// I'm thinking we should use that, plus a class specified
+	// via a property that determines lookup policy.
+	File soFile = new File(hexBytes + ".so");
+	if (soFile.isFile())
+          return loadSharedLibrary (loader, soFile.toString(), domain,
+				    name);
+
+	File classFile = new File(hexBytes + ".class");
+	classFile.delete();
+	if (classFile.createNewFile() != true)	  
+	  return null;
+
+	FileOutputStream f = new FileOutputStream (classFile);
+	// FIXME: race condition if bytes change... ?
+	f.write(data, offset, len);
+
+	// Invoke the compiler.
+	StringBuffer command = new StringBuffer(gcjJitCompiler);
+	command.append(" ");
+	command.append(classFile);
+	command.append(" ");
+	command.append(gcjJitCompilerOptions);
+	// These options are required.
+	command.append(" -findirect-dispatch -fjni -shared -fPIC -o ");
+	command.append(soFile);
+	Process p = Runtime.getRuntime().exec(command.toString());
+
+	// Read the process' stderr into a string.
+	StringBuffer err = new StringBuffer();
+	InputStreamReader stderr = new InputStreamReader (p.getErrorStream());
+	char[] inBuf = new char[500];
+	int bytesRead;
+	while ((bytesRead = stderr.read (inBuf)) != -1)
+	  err.append(inBuf, 0, bytesRead);
+
+	if (p.waitFor() != 0)
+	  {
+	    // FIXME: we could log err.toString() somewhere...
+	    return null;
+	  }
+
+	return loadSharedLibrary(loader, soFile.toString(), domain, name);
+      }
+    catch (Exception _)
+      {
+	return null;
+      }
+  }
+
+  /**
+   * 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()
+  {
+    useCompiler = true;
+  }
+
+  /**
+   * Calling <code>Compiler.disable()</code> will cause the compiler
+   * to be suspended; provided that a compiler even exists.
+   */
+  public static void disable()
+  {
+    useCompiler = false;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/VMDouble.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/VMDouble.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/VMDouble.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/VMDouble.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,111 @@
+/* VMDouble.java -- VM Specific Double methods
+   Copyright (C) 2003, 2005, 2006  Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import gnu.classpath.Configuration;
+
+/*
+ * 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 at us.ibm.com)
+ */
+final class VMDouble
+{
+  /**
+   * 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);
+
+  public static native double parseDouble(String str);
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/VMFloat.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/VMFloat.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/VMFloat.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/VMFloat.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,99 @@
+/* VMFloat.java -- VM Specific Float methods
+   Copyright (C) 2003, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import gnu.classpath.Configuration;
+
+/*
+ * 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 at us.ibm.com>
+ */
+final class VMFloat
+{
+  /**
+   * 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

Added: llvm-gcc-4.2/trunk/libjava/java/lang/VMSecurityManager.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/VMSecurityManager.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/VMSecurityManager.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/VMSecurityManager.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,68 @@
+/*
+ * java.lang.SecurityManager: part of the Java Class Libraries project.
+ * Copyright (C) 1998, 2001, 2002, 2005 Free Software Foundation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+package java.lang;
+
+import java.net.*;
+import java.util.*;
+import java.io.*;
+
+/**
+ ** VMSecurityManager is a helper class for SecurityManager the VM must
+ ** implement.
+ **
+ ** @author  John Keiser
+ ** @version 1.1.0, 31 May 1998
+ **/
+class VMSecurityManager
+{
+  /** Get a list of all the classes currently executing
+   ** methods on the Java stack.  getClassContext()[0] is
+   ** the currently executing method
+   ** <STRONG>Spec Note:</STRONG> does not say whether
+   ** the stack will include the getClassContext() call or
+   ** the one just before it.
+   **
+   ** @return an array containing all the methods on classes
+   **         on the Java execution stack.
+   **/
+  static native Class[] getClassContext(Class caller);
+
+  /** Get the current ClassLoader--the one nearest to the
+   ** top of the stack.
+   ** @return the current ClassLoader.
+   **/
+  static ClassLoader currentClassLoader(Class caller)
+  {
+    // The docs above are wrong.  See the online docs.
+    // FIXME this implementation is a bit wrong too -- the docs say we
+    // must also consider ancestors of the system class loader.
+    ClassLoader systemClassLoader = ClassLoader.systemClassLoader;
+    Class[] classStack = getClassContext (caller);
+    for (int i = 0; i < classStack.length; i++)
+      {
+	ClassLoader loader = classStack[i].getClassLoader();
+	if (loader != null && loader != systemClassLoader)
+	  return loader;
+      }
+
+    return null;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/VMThrowable.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/VMThrowable.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/VMThrowable.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/VMThrowable.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,82 @@
+/* java.lang.VMThrowable -- VM support methods for Throwable.
+   Copyright (C) 1998, 1999, 2002, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import gnu.gcj.RawDataManaged;
+
+/**
+ * VM dependent state and support methods Throwable.
+ * It is deliberately package local and final and should only be accessed
+ * by the Throwable class.
+ * <p>
+ * This is the version used by libgcj (http://gcc.gnu.org/java/).
+ *
+ * @author Mark Wielaard (mark at klomp.org)
+ */
+final class VMThrowable
+{
+  /**
+   * Private contructor, create VMThrowables with StackTrace();
+   */
+  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);
+  
+  // Native stack data.
+  private RawDataManaged data;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/Win32Process.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/Win32Process.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/Win32Process.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/Win32Process.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,90 @@
+// Win32Process.java - Subclass of Process for Win32 systems.
+
+/* Copyright (C) 2002, 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package java.lang;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * @author Adam Megacz
+ * @date Feb 24, 2002
+ */
+
+// This is entirely internal to our implementation.
+
+// This file is copied to `ConcreteProcess.java' before compilation.
+// Hence the class name apparently does not match the file name.
+final class ConcreteProcess extends Process
+{
+  public native void destroy ();
+
+  public int exitValue ()
+  {
+    if (! hasExited ())
+      throw new IllegalThreadStateException ("Process has not exited");
+
+    return exitCode;
+  }
+
+  public InputStream getErrorStream ()
+  {
+    return errorStream;
+  }
+
+  public InputStream getInputStream ()
+  {
+    return inputStream;
+  }
+
+  public OutputStream getOutputStream ()
+  {
+    return outputStream;
+  }
+
+  public native int waitFor () throws InterruptedException;
+
+  public ConcreteProcess (String[] progarray,
+                          String[] envp,
+                          File dir)
+    throws IOException
+  {
+    for (int i = 0; i < progarray.length; i++)
+      {
+        String s = progarray[i];
+
+        if ( (s.indexOf (' ') >= 0) || (s.indexOf ('\t') >= 0))
+          progarray[i] = "\"" + s + "\"";
+      }
+
+    startProcess (progarray, envp, dir);
+  }
+
+  // The standard streams (stdin, stdout and stderr, respectively)
+  // of the child as seen by the parent process.
+  private OutputStream outputStream;
+  private InputStream inputStream;
+  private InputStream errorStream;
+
+  // Handle to the child process - cast to HANDLE before use.
+  private int procHandle;
+
+  // Exit code of the child if it has exited.
+  private int exitCode;
+
+  private native boolean hasExited ();
+  private native void startProcess (String[] progarray,
+           String[] envp,
+           File dir)
+    throws IOException;
+  private native void cleanup ();
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/management/VMManagementFactory.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/management/VMManagementFactory.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/management/VMManagementFactory.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/management/VMManagementFactory.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,84 @@
+/* VMManagementFactory.java - VM interface for obtaining system beans.
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang.management;
+
+/**
+ * Provides lists of resources required by the
+ * {@link java.lang.management.ManagementFactory} for
+ * creating beans.
+ *
+ * @author Andrew John Hughes (gnu_andrew at member.fsf.org)
+ * @since 1.5
+ */
+final class VMManagementFactory
+{
+
+  /**
+   * Return a list of the names of the currently available
+   * memory pools within the virtual machine.
+   *
+   * @return a list of memory pool names.
+   */
+  static String[] getMemoryPoolNames()
+  {
+    return new String[0];
+  }
+
+  /**
+   * Return a list of the names of the currently available
+   * memory managers within the virtual machine.  This should
+   * not include the garbage collectors listed below.
+   *
+   * @return a list of memory manager names.
+   */
+  static String[] getMemoryManagerNames()
+  {
+    return new String[0];
+  }
+
+  /**
+   * Return a list of the names of the currently available
+   * garbage collectors within the virtual machine.
+   *
+   * @return a list of garbage collector names.
+   */
+  static String[] getGarbageCollectorNames()
+  {
+    return new String[0];
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natCharacter.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natCharacter.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natCharacter.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natCharacter.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,237 @@
+/* java.lang.Character -- Wrapper class for char, and Unicode subsets
+   Copyright (C) 1998, 1999, 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. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/lang/Character.h>
+
+#include <java-chartables.h>
+
+
+
+// These constants define the return values for characters that are unassigned
+// or reserved for private use.
+#define UNASSIGNED_TYPE 0
+#define UNASSIGNED_DIGIT -1
+#define UNASSIGNED_DIRECTION -1
+#define UNASSIGNED_NUMERIC_VALUE -1
+
+#define PRIVATE_TYPE 18
+#define PRIVATE_DIRECTION 0
+
+// The methods that take a char as an argument all have counterparts that 
+// take ints.  The ones that take chars only work for the BMP or plane 0 of the
+// Unicode standard but the ones that take ints work for all Unicode code
+// points.  However, the ones that take chars don't simply redirect the calls
+// because the BMP is by far the most used plane so saving a little time on
+// each call makes sense.
+
+jchar
+java::lang::Character::readChar(jchar ch)
+{
+  // Perform 16-bit addition to find the correct entry in data.
+  return data[0][(jchar) (blocks[0][ch >> shift[0]] + ch)];
+}
+
+jchar
+java::lang::Character::readCodePoint(jint codePoint)
+{
+  jint plane = codePoint >> 16;
+  jchar offset = (jchar)(codePoint & 0xffff);
+  // Be careful not to call this method with an unassigned character.  The only
+  // characters assigned as of Unicode 4.0.0 belong to planes 0, 1, 2, and 14.
+  return data[plane][(jchar) (blocks[plane][offset >> shift[plane]] + offset)];
+}
+
+jint
+java::lang::Character::getType(jchar ch)
+{
+  // Perform 16-bit addition to find the correct entry in data.
+  return (jint) (data[0][(jchar) (blocks[0][ch >> shift[0]] + ch)] & TYPE_MASK);
+}
+
+jint
+java::lang::Character::getType(jint codePoint)
+{
+  jint plane = codePoint >> 16;
+  if (plane > 2 && plane != 14)
+    {
+      if (plane > 14 && ((codePoint & 0xffff) < 0xfffe))
+        return (jint) PRIVATE_TYPE;
+      return (jint) UNASSIGNED_TYPE;
+    }
+  jint offset = codePoint & 0xffff;
+  return (jint) 
+    (data[plane]
+     [(jchar) (blocks[plane][offset >> shift[plane]] + offset)] & TYPE_MASK);
+}
+
+jchar
+java::lang::Character::toLowerCase(jchar ch)
+{
+  return (jchar) (ch + lower[0][readChar(ch) >> 7]);
+}
+
+jint
+java::lang::Character::toLowerCase(jint codePoint)
+{
+  jint plane = codePoint >> 16;
+  if (plane > 2 && plane != 14)
+    return codePoint;
+  return (lower[plane][readCodePoint(codePoint) >> 7]) + codePoint;
+}
+
+jchar
+java::lang::Character::toUpperCase(jchar ch)
+{
+  return (jchar) (ch + upper[0][readChar(ch) >> 7]);
+}
+
+jint
+java::lang::Character::toUpperCase(jint codePoint)
+{
+  jint plane = codePoint >> 16;
+  if (plane > 2 && plane != 14)
+    return codePoint;
+  return (upper[plane][readCodePoint(codePoint) >> 7]) + codePoint;
+}
+
+jchar
+java::lang::Character::toTitleCase(jchar ch)
+{
+  // As title is short, it doesn't hurt to exhaustively iterate over it.
+  for (int i = title_length - 2; i >= 0; i -= 2)
+    if (title[i] == ch)
+      return title[i + 1];
+  return toUpperCase(ch);
+}
+
+jint
+java::lang::Character::toTitleCase(jint codePoint)
+{
+  // As of Unicode 4.0.0 no characters outside of plane 0 have titlecase
+  // mappings that are different from their uppercase mapping.
+  if (codePoint < 0x10000)
+    return toTitleCase((jchar)codePoint);
+  return toUpperCase(codePoint);
+}
+
+jint
+java::lang::Character::digit(jchar ch, jint radix)
+{
+  if (radix < MIN_RADIX || radix > MAX_RADIX)
+    return (jint) -1;
+  jchar attr = readChar(ch);
+  if (((1 << (attr & TYPE_MASK))
+       & ((1 << UPPERCASE_LETTER)
+          | (1 << LOWERCASE_LETTER)
+          | (1 << DECIMAL_DIGIT_NUMBER))))
+    {
+      // Signedness doesn't matter; 0xffff vs. -1 are both rejected.
+      jint digit = (jint) numValue[0][attr >> 7];
+      return (digit >= 0 && digit < radix) ? digit : (jint) -1;
+    }
+  return (jint) -1;
+}
+
+jint
+java::lang::Character::digit(jint codePoint, jint radix)
+{
+  if (radix < MIN_RADIX || radix > MAX_RADIX)
+    return (jint) -1;
+
+  jint plane = codePoint >> 16;
+  if (plane > 2 && plane != 14)
+    return UNASSIGNED_DIGIT;
+
+  jchar attr = readCodePoint(codePoint);
+  if (((1 << (attr & TYPE_MASK))
+       & ((1 << UPPERCASE_LETTER)
+          | (1 << LOWERCASE_LETTER)
+          | (1 << DECIMAL_DIGIT_NUMBER))))
+    {
+      // Signedness doesn't matter; 0xffff vs. -1 are both rejected.
+      jint digit = (jint) numValue[plane][attr >> 7];
+      if (digit <= -3)
+        digit = largenums[-digit -3];
+      return (digit >= 0 && digit < radix) ? digit : (jint) -1;
+    }
+  return (jint) -1;
+
+}
+
+jint
+java::lang::Character::getNumericValue(jchar ch)
+{
+  // numValue is stored as an array of jshort, since 10000 is the maximum.
+  return (jint) numValue[0][readChar(ch) >> 7];
+}
+
+jint
+java::lang::Character::getNumericValue(jint codePoint)
+{
+  jint plane = codePoint >> 16;
+  if (plane > 2 && plane != 14)
+    return UNASSIGNED_NUMERIC_VALUE;
+  jshort num = numValue[plane][readCodePoint(codePoint) >> 7];
+  if (num <= -3)
+    return largenums[-num - 3];
+  return num;
+}
+
+jbyte
+java::lang::Character::getDirectionality(jchar ch)
+{
+  return direction[0][readChar(ch) >> 7];
+}
+
+jbyte
+java::lang::Character::getDirectionality(jint codePoint)
+{
+  jint plane = codePoint >> 16;
+  if (plane > 2 && plane != 14)
+    {
+      if (plane > 14 && ((codePoint & 0xffff) < 0xfffe))
+        return (jint) PRIVATE_DIRECTION;
+      return (jint) UNASSIGNED_DIRECTION;
+    }
+  return direction[plane][readCodePoint(codePoint) >> 7];
+}
+
+

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natClass.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natClass.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natClass.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natClass.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1269 @@
+// natClass.cc - Implementation of java.lang.Class native methods.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include <limits.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#pragma implementation "Class.h"
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-threads.h>
+
+#include <java/lang/Class.h>
+#include <java/lang/ClassLoader.h>
+#include <java/lang/String.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/reflect/Member.h>
+#include <java/lang/reflect/Method.h>
+#include <java/lang/reflect/Field.h>
+#include <java/lang/reflect/Constructor.h>
+#include <java/lang/AbstractMethodError.h>
+#include <java/lang/ArrayStoreException.h>
+#include <java/lang/ClassCastException.h>
+#include <java/lang/ClassNotFoundException.h>
+#include <java/lang/ExceptionInInitializerError.h>
+#include <java/lang/IllegalAccessException.h>
+#include <java/lang/IllegalAccessError.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/NoSuchFieldError.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/InstantiationException.h>
+#include <java/lang/NoClassDefFoundError.h>
+#include <java/lang/NoSuchFieldException.h>
+#include <java/lang/NoSuchMethodError.h>
+#include <java/lang/NoSuchMethodException.h>
+#include <java/lang/Thread.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/RuntimePermission.h>
+#include <java/lang/System.h>
+#include <java/lang/SecurityManager.h>
+#include <java/lang/StringBuffer.h>
+#include <java/lang/VMClassLoader.h>
+#include <gcj/method.h>
+#include <gnu/gcj/RawData.h>
+#include <java/lang/VerifyError.h>
+
+#include <java-cpool.h>
+#include <java-interp.h>
+#include <java-assert.h>
+#include <java-stack.h>
+#include <execution.h>
+
+
+
+using namespace gcj;
+
+jclass
+java::lang::Class::forName (jstring className, jboolean initialize,
+                            java::lang::ClassLoader *loader)
+{
+  if (! className)
+    throw new java::lang::NullPointerException;
+
+  jsize length = _Jv_GetStringUTFLength (className);
+  char buffer[length];
+  _Jv_GetStringUTFRegion (className, 0, className->length(), buffer);
+
+  _Jv_Utf8Const *name = _Jv_makeUtf8Const (buffer, length);
+
+  if (! _Jv_VerifyClassName (name))
+    throw new java::lang::ClassNotFoundException (className);
+
+  jclass klass = (buffer[0] == '[' 
+		  ? _Jv_FindClassFromSignature (name->chars(), loader)
+		  : _Jv_FindClass (name, loader));
+
+  if (klass == NULL)
+    throw new java::lang::ClassNotFoundException (className);
+
+  if (initialize)
+    _Jv_InitClass (klass);
+
+  return klass;
+}
+
+jclass
+java::lang::Class::forName (jstring className)
+{
+  java::lang::ClassLoader *loader = NULL;
+
+  jclass caller = _Jv_StackTrace::GetCallingClass (&Class::class$);
+  if (caller)
+    loader = caller->getClassLoaderInternal();
+
+  return forName (className, true, loader);
+}
+
+java::lang::ClassLoader *
+java::lang::Class::getClassLoader (void)
+{
+  java::lang::SecurityManager *s = java::lang::System::getSecurityManager();
+  if (s != NULL)
+    {
+      jclass caller = _Jv_StackTrace::GetCallingClass (&Class::class$);
+      return getClassLoader (caller);
+   }
+
+  return loader;
+}
+
+java::lang::ClassLoader *
+java::lang::Class::getClassLoader (jclass caller)
+{
+  java::lang::SecurityManager *s = java::lang::System::getSecurityManager();
+  if (s != NULL)
+    {
+      ClassLoader *caller_loader = caller->getClassLoaderInternal();
+
+      // If the caller has a non-null class loader, and that loader
+      // is not this class' loader or an ancestor thereof, then do a
+      // security check.
+      if (caller_loader != NULL && ! caller_loader->isAncestorOf(loader))
+	s->checkPermission (new RuntimePermission (JvNewStringLatin1 ("getClassLoader")));
+    }
+
+  return loader;
+}
+
+java::lang::reflect::Constructor *
+java::lang::Class::getConstructor (JArray<jclass> *param_types)
+{
+  memberAccessCheck(java::lang::reflect::Member::PUBLIC);
+
+  jstring partial_sig = getSignature (param_types, true);
+  jint hash = partial_sig->hashCode ();
+
+  int i = isPrimitive () ? 0 : method_count;
+  while (--i >= 0)
+    {
+      if (_Jv_equalUtf8Consts (methods[i].name, init_name)
+	  && _Jv_equal (methods[i].signature, partial_sig, hash))
+	{
+	  // Found it.  For getConstructor, the constructor must be
+	  // public.
+	  using namespace java::lang::reflect;
+	  if (! Modifier::isPublic(methods[i].accflags))
+	    break;
+	  Constructor *cons = new Constructor ();
+	  cons->offset = (char *) (&methods[i]) - (char *) methods;
+	  cons->declaringClass = this;
+	  return cons;
+	}
+    }
+  throw new java::lang::NoSuchMethodException (_Jv_NewStringUtf8Const (init_name));
+}
+
+JArray<java::lang::reflect::Constructor *> *
+java::lang::Class::getDeclaredConstructors (jboolean publicOnly)
+{
+  int numConstructors = 0;
+  int max = isPrimitive () ? 0 : method_count;
+  int i;
+  for (i = max; --i >= 0; )
+    {
+      _Jv_Method *method = &methods[i];
+      if (method->name == NULL
+	  || ! _Jv_equalUtf8Consts (method->name, init_name))
+	continue;
+      if (publicOnly
+	  && ! java::lang::reflect::Modifier::isPublic(method->accflags))
+	continue;
+      numConstructors++;
+    }
+  JArray<java::lang::reflect::Constructor *> *result
+    = (JArray<java::lang::reflect::Constructor *> *)
+    JvNewObjectArray (numConstructors,
+		      &java::lang::reflect::Constructor::class$,
+		      NULL);
+  java::lang::reflect::Constructor** cptr = elements (result);
+  for (i = 0;  i < max;  i++)
+    {
+      _Jv_Method *method = &methods[i];
+      if (method->name == NULL
+	  || ! _Jv_equalUtf8Consts (method->name, init_name))
+	continue;
+      if (publicOnly
+	  && ! java::lang::reflect::Modifier::isPublic(method->accflags))
+	continue;
+      java::lang::reflect::Constructor *cons
+	= new java::lang::reflect::Constructor ();
+      cons->offset = (char *) method - (char *) methods;
+      cons->declaringClass = this;
+      *cptr++ = cons;
+    }
+  return result;
+}
+
+java::lang::reflect::Constructor *
+java::lang::Class::getDeclaredConstructor (JArray<jclass> *param_types)
+{
+  memberAccessCheck(java::lang::reflect::Member::DECLARED);
+
+  jstring partial_sig = getSignature (param_types, true);
+  jint hash = partial_sig->hashCode ();
+
+  int i = isPrimitive () ? 0 : method_count;
+  while (--i >= 0)
+    {
+      if (_Jv_equalUtf8Consts (methods[i].name, init_name)
+	  && _Jv_equal (methods[i].signature, partial_sig, hash))
+	{
+	  // Found it.
+	  using namespace java::lang::reflect;
+	  Constructor *cons = new Constructor ();
+	  cons->offset = (char *) (&methods[i]) - (char *) methods;
+	  cons->declaringClass = this;
+	  return cons;
+	}
+    }
+  throw new java::lang::NoSuchMethodException (_Jv_NewStringUtf8Const (init_name));
+}
+
+java::lang::reflect::Field *
+java::lang::Class::getField (jstring name, jint hash)
+{
+  java::lang::reflect::Field* rfield;
+  for (int i = 0;  i < field_count;  i++)
+    {
+      _Jv_Field *field = &fields[i];
+      if (! _Jv_equal (field->name, name, hash))
+	continue;
+      if (! (field->getModifiers() & java::lang::reflect::Modifier::PUBLIC))
+	continue;
+      rfield = new java::lang::reflect::Field ();
+      rfield->offset = (char*) field - (char*) fields;
+      rfield->declaringClass = this;
+      rfield->name = name;
+      return rfield;
+    }
+  jclass superclass = getSuperclass();
+  if (superclass == NULL)
+    return NULL;
+  rfield = superclass->getField(name, hash);
+  for (int i = 0; i < interface_count && rfield == NULL; ++i)
+    rfield = interfaces[i]->getField (name, hash);
+  return rfield;
+}
+
+java::lang::reflect::Field *
+java::lang::Class::getDeclaredField (jstring name)
+{
+  memberAccessCheck(java::lang::reflect::Member::DECLARED);
+  int hash = name->hashCode();
+  for (int i = 0;  i < field_count;  i++)
+    {
+      _Jv_Field *field = &fields[i];
+      if (! _Jv_equal (field->name, name, hash))
+	continue;
+      java::lang::reflect::Field* rfield = new java::lang::reflect::Field ();
+      rfield->offset = (char*) field - (char*) fields;
+      rfield->declaringClass = this;
+      rfield->name = name;
+      return rfield;
+    }
+  throw new java::lang::NoSuchFieldException (name);
+}
+
+JArray<java::lang::reflect::Field *> *
+java::lang::Class::getDeclaredFields (jboolean public_only)
+{
+  int size;
+  if (public_only)
+    {
+      size = 0;
+      for (int i = 0; i < field_count; ++i)
+	{
+	  _Jv_Field *field = &fields[i];
+	  if ((field->flags & java::lang::reflect::Modifier::PUBLIC))
+	    ++size;
+	}
+    }
+  else
+    size = field_count;
+
+  JArray<java::lang::reflect::Field *> *result
+    = (JArray<java::lang::reflect::Field *> *)
+    JvNewObjectArray (size, &java::lang::reflect::Field::class$, NULL);
+  java::lang::reflect::Field** fptr = elements (result);
+  for (int i = 0;  i < field_count;  i++)
+    {
+      _Jv_Field *field = &fields[i];
+      if (public_only
+	  && ! (field->flags & java::lang::reflect::Modifier::PUBLIC))
+	continue;
+      java::lang::reflect::Field* rfield = new java::lang::reflect::Field ();
+      rfield->offset = (char*) field - (char*) fields;
+      rfield->declaringClass = this;
+      *fptr++ = rfield;
+    }
+  return result;
+}
+
+void
+java::lang::Class::getSignature (java::lang::StringBuffer *buffer)
+{
+  if (isPrimitive())
+    buffer->append((jchar) method_count);
+  else
+    {
+      jstring name = getName();
+      if (name->charAt(0) != '[')
+	buffer->append((jchar) 'L');
+      buffer->append(name);
+      if (name->charAt(0) != '[')
+	buffer->append((jchar) ';');
+    }
+}
+
+// This doesn't have to be native.  It is an implementation detail
+// only called from the C++ code, though, so maybe this is clearer.
+jstring
+java::lang::Class::getSignature (JArray<jclass> *param_types,
+				 jboolean is_constructor)
+{
+  java::lang::StringBuffer *buf = new java::lang::StringBuffer ();
+  buf->append((jchar) '(');
+  // A NULL param_types means "no parameters".
+  if (param_types != NULL)
+    {
+      jclass *v = elements (param_types);
+      for (int i = 0; i < param_types->length; ++i)
+	v[i]->getSignature(buf);
+    }
+  buf->append((jchar) ')');
+  if (is_constructor)
+    buf->append((jchar) 'V');
+  return buf->toString();
+}
+
+java::lang::reflect::Method *
+java::lang::Class::_getDeclaredMethod (jstring name,
+				       JArray<jclass> *param_types)
+{
+  jstring partial_sig = getSignature (param_types, false);
+  jint p_len = partial_sig->length();
+  _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
+  int i = isPrimitive () ? 0 : method_count;
+  while (--i >= 0)
+    {
+      if (_Jv_equalUtf8Consts (methods[i].name, utf_name)
+	  && _Jv_equaln (methods[i].signature, partial_sig, p_len)
+	  && (methods[i].accflags
+	      & java::lang::reflect::Modifier::INVISIBLE) == 0)
+	{
+	  // Found it.
+	  using namespace java::lang::reflect;
+	  Method *rmethod = new Method ();
+	  rmethod->offset = (char*) (&methods[i]) - (char*) methods;
+	  rmethod->declaringClass = this;
+	  return rmethod;
+	}
+    }
+  return NULL;
+}
+
+JArray<java::lang::reflect::Method *> *
+java::lang::Class::getDeclaredMethods (void)
+{
+  memberAccessCheck(java::lang::reflect::Member::DECLARED);
+
+  int numMethods = 0;
+  int max = isPrimitive () ? 0 : method_count;
+  int i;
+  for (i = max; --i >= 0; )
+    {
+      _Jv_Method *method = &methods[i];
+      if (method->name == NULL
+	  || _Jv_equalUtf8Consts (method->name, clinit_name)
+	  || _Jv_equalUtf8Consts (method->name, init_name)
+	  || _Jv_equalUtf8Consts (method->name, finit_name)
+	  || (methods[i].accflags
+	      & java::lang::reflect::Modifier::INVISIBLE) != 0)
+	continue;
+      numMethods++;
+    }
+  JArray<java::lang::reflect::Method *> *result
+    = (JArray<java::lang::reflect::Method *> *)
+    JvNewObjectArray (numMethods, &java::lang::reflect::Method::class$, NULL);
+  java::lang::reflect::Method** mptr = elements (result);
+  for (i = 0;  i < max;  i++)
+    {
+      _Jv_Method *method = &methods[i];
+      if (method->name == NULL
+	  || _Jv_equalUtf8Consts (method->name, clinit_name)
+	  || _Jv_equalUtf8Consts (method->name, init_name)
+	  || _Jv_equalUtf8Consts (method->name, finit_name)
+	  || (methods[i].accflags
+	      & java::lang::reflect::Modifier::INVISIBLE) != 0)
+	continue;
+      java::lang::reflect::Method* rmethod
+	= new java::lang::reflect::Method ();
+      rmethod->offset = (char*) method - (char*) methods;
+      rmethod->declaringClass = this;
+      *mptr++ = rmethod;
+    }
+  return result;
+}
+
+jstring
+java::lang::Class::getName (void)
+{
+  return name->toString();
+}
+
+JArray<jclass> *
+java::lang::Class::getDeclaredClasses (jboolean /*publicOnly*/)
+{
+  // Until we have inner classes, it always makes sense to return an
+  // empty array.
+  JArray<jclass> *result
+    = (JArray<jclass> *) JvNewObjectArray (0, &java::lang::Class::class$,
+					   NULL);
+  return result;
+}
+
+jclass
+java::lang::Class::getDeclaringClass (void)
+{
+  // Until we have inner classes, it makes sense to always return
+  // NULL.
+  return NULL;
+}
+
+JArray<jclass> *
+java::lang::Class::getInterfaces (void)
+{
+  jobjectArray r = JvNewObjectArray (interface_count, getClass (), NULL);
+  jobject *data = elements (r);
+  for (int i = 0; i < interface_count; ++i)
+    {
+      typedef unsigned int uaddr __attribute__ ((mode (pointer)));
+      data[i] = interfaces[i];
+      if ((uaddr)data[i] < (uaddr)constants.size)
+	fprintf (stderr, "ERROR !!!\n");
+    }
+  return reinterpret_cast<JArray<jclass> *> (r);
+}
+
+java::lang::reflect::Method *
+java::lang::Class::_getMethod (jstring name, JArray<jclass> *param_types)
+{
+  jstring partial_sig = getSignature (param_types, false);
+  jint p_len = partial_sig->length();
+  _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
+
+   for (Class *klass = this; klass; klass = klass->getSuperclass())
+    {
+      int i = klass->isPrimitive () ? 0 : klass->method_count;
+      while (--i >= 0)
+	{
+	  if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
+	      && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len)
+	      && (klass->methods[i].accflags
+		  & java::lang::reflect::Modifier::INVISIBLE) == 0)
+	    {
+	      // Found it.
+	      using namespace java::lang::reflect;
+
+	      // Method must be public.
+	      if (! Modifier::isPublic (klass->methods[i].accflags))
+		break;
+
+	      Method *rmethod = new Method ();
+	      rmethod->offset = ((char *) (&klass->methods[i])
+				 - (char *) klass->methods);
+	      rmethod->declaringClass = klass;
+	      return rmethod;
+	    }
+	}
+    }
+
+  // If we haven't found a match, and this class is an interface, then
+  // check all the superinterfaces.
+  if (isInterface())
+    {
+      for (int i = 0; i < interface_count; ++i)
+	{
+	  using namespace java::lang::reflect;
+	  Method *rmethod = interfaces[i]->_getMethod (name, param_types);
+	  if (rmethod != NULL)
+	    return rmethod;
+	}
+    }
+
+  return NULL;
+}
+
+// This is a very slow implementation, since it re-scans all the
+// methods we've already listed to make sure we haven't duplicated a
+// method.  It also over-estimates the required size, so we have to
+// shrink the result array later.
+jint
+java::lang::Class::_getMethods (JArray<java::lang::reflect::Method *> *result,
+				jint offset)
+{
+  jint count = 0;
+
+  // First examine all local methods
+  for (int i = isPrimitive () ? 0 : method_count; --i >= 0; )
+    {
+      _Jv_Method *method = &methods[i];
+      if (method->name == NULL
+	  || _Jv_equalUtf8Consts (method->name, clinit_name)
+	  || _Jv_equalUtf8Consts (method->name, init_name)
+	  || _Jv_equalUtf8Consts (method->name, finit_name)
+	  || (method->accflags
+	      & java::lang::reflect::Modifier::INVISIBLE) != 0)
+	continue;
+      // Only want public methods.
+      if (! java::lang::reflect::Modifier::isPublic (method->accflags))
+	continue;
+
+      // This is where we over-count the slots required if we aren't
+      // filling the result for real.
+      if (result != NULL)
+	{
+	  jboolean add = true;
+	  java::lang::reflect::Method **mp = elements (result);
+	  // If we already have a method with this name and signature,
+	  // then ignore this one.  This can happen with virtual
+	  // methods.
+	  for (int j = 0; j < offset; ++j)
+	    {
+	      _Jv_Method *meth_2 = _Jv_FromReflectedMethod (mp[j]);
+	      if (_Jv_equalUtf8Consts (method->name, meth_2->name)
+		  && _Jv_equalUtf8Consts (method->signature,
+					  meth_2->signature))
+		{
+		  add = false;
+		  break;
+		}
+	    }
+	  if (! add)
+	    continue;
+	}
+
+      if (result != NULL)
+	{
+	  using namespace java::lang::reflect;
+	  Method *rmethod = new Method ();
+	  rmethod->offset = (char *) method - (char *) methods;
+	  rmethod->declaringClass = this;
+	  Method **mp = elements (result);
+	  mp[offset + count] = rmethod;
+	}
+      ++count;
+    }
+  offset += count;
+
+  // Now examine superclasses.
+  if (getSuperclass () != NULL)
+    {
+      jint s_count = getSuperclass()->_getMethods (result, offset);
+      offset += s_count;
+      count += s_count;
+    }
+
+  // Finally, examine interfaces.
+  for (int i = 0; i < interface_count; ++i)
+    {
+      int f_count = interfaces[i]->_getMethods (result, offset);
+      count += f_count;
+      offset += f_count;
+    }
+
+  return count;
+}
+
+JArray<java::lang::reflect::Method *> *
+java::lang::Class::getMethods (void)
+{
+  using namespace java::lang::reflect;
+
+  memberAccessCheck(Member::PUBLIC);
+
+  // This will overestimate the size we need.
+  jint count = _getMethods (NULL, 0);
+
+  JArray<Method *> *result
+    = ((JArray<Method *> *) JvNewObjectArray (count,
+					      &Method::class$,
+					      NULL));
+
+  // When filling the array for real, we get the actual count.  Then
+  // we resize the array.
+  jint real_count = _getMethods (result, 0);
+
+  if (real_count != count)
+    {
+      JArray<Method *> *r2
+	= ((JArray<Method *> *) JvNewObjectArray (real_count,
+						  &Method::class$,
+						  NULL));
+      
+      Method **destp = elements (r2);
+      Method **srcp = elements (result);
+
+      for (int i = 0; i < real_count; ++i)
+	*destp++ = *srcp++;
+
+      result = r2;
+    }
+
+  return result;
+}
+
+jboolean
+java::lang::Class::isAssignableFrom (jclass klass)
+{
+  // Arguments may not have been initialized, given ".class" syntax.
+  // This ensures we can at least look at their superclasses.
+  _Jv_Linker::wait_for_state (this, JV_STATE_LOADING);
+  _Jv_Linker::wait_for_state (klass, JV_STATE_LOADING);
+  return _Jv_IsAssignableFrom (klass, this);
+}
+
+jboolean
+java::lang::Class::isInstance (jobject obj)
+{
+  if (! obj)
+    return false;
+  return _Jv_IsAssignableFrom (JV_CLASS (obj), this);
+}
+
+jobject
+java::lang::Class::newInstance (void)
+{
+  memberAccessCheck(java::lang::reflect::Member::PUBLIC);
+
+  if (isPrimitive ()
+      || isInterface ()
+      || isArray ()
+      || java::lang::reflect::Modifier::isAbstract(accflags))
+    throw new java::lang::InstantiationException (getName ());
+
+  _Jv_InitClass (this);
+
+  _Jv_Method *meth = _Jv_GetMethodLocal (this, init_name, void_signature);
+  if (! meth)
+    throw new java::lang::InstantiationException (getName());
+
+  jobject r = _Jv_AllocObject (this);
+  ((void (*) (jobject)) meth->ncode) (r);
+  return r;
+}
+
+void
+java::lang::Class::finalize (void)
+{
+  engine->unregister(this);
+}
+
+// This implements the initialization process for a class.  From Spec
+// section 12.4.2.
+void
+java::lang::Class::initializeClass (void)
+{
+  // Short-circuit to avoid needless locking (expression includes
+  // JV_STATE_PHANTOM and JV_STATE_DONE).
+  if (state >= JV_STATE_PHANTOM)
+    return;
+
+  // Step 1.  We introduce a new scope so we can synchronize more
+  // easily.
+  {
+    JvSynchronize sync (this);
+
+    if (state < JV_STATE_LINKED)
+      {
+	try
+	  {
+	    _Jv_Linker::wait_for_state(this, JV_STATE_LINKED);
+	  }
+	catch (java::lang::Throwable *x)
+	  {
+	    // Turn into a NoClassDefFoundError.
+	    java::lang::NoClassDefFoundError *result
+	      = new java::lang::NoClassDefFoundError(getName());
+	    result->initCause(x);
+	    throw result;
+	  }
+      }
+
+    // Step 2.
+    java::lang::Thread *self = java::lang::Thread::currentThread();
+    self = (java::lang::Thread *) ((long) self | 1);
+    while (state == JV_STATE_IN_PROGRESS && thread && thread != self)
+      wait ();
+
+    // Steps 3 &  4.
+    if (state == JV_STATE_DONE || state == JV_STATE_IN_PROGRESS)
+      return;
+
+    // Step 5.
+    if (state == JV_STATE_ERROR)
+      throw new java::lang::NoClassDefFoundError (getName());
+
+    // Step 6.
+    thread = self;
+    _Jv_Linker::wait_for_state (this, JV_STATE_LINKED);
+    state = JV_STATE_IN_PROGRESS;
+  }
+
+  // Step 7.
+  if (! isInterface () && superclass)
+    {
+      try
+	{
+	  _Jv_InitClass (superclass);
+	}
+      catch (java::lang::Throwable *except)
+	{
+	  // Caught an exception.
+	  JvSynchronize sync (this);
+	  state = JV_STATE_ERROR;
+	  notifyAll ();
+	  throw except;
+	}
+    }
+
+  // Steps 8, 9, 10, 11.
+  try
+    {
+      _Jv_Method *meth = _Jv_GetMethodLocal (this, clinit_name,
+					     void_signature);
+      if (meth)
+	((void (*) (void)) meth->ncode) ();
+    }
+  catch (java::lang::Throwable *except)
+    {
+      if (! java::lang::Error::class$.isInstance(except))
+	{
+	  try
+	    {
+	      except = new ExceptionInInitializerError (except);
+	    }
+	  catch (java::lang::Throwable *t)
+	    {
+	      except = t;
+	    }
+	}
+
+      JvSynchronize sync (this);
+      state = JV_STATE_ERROR;
+      notifyAll ();
+      throw except;
+    }
+
+  JvSynchronize sync (this);
+  state = JV_STATE_DONE;
+  notifyAll ();
+}
+
+// Only used by serialization
+java::lang::reflect::Field *
+java::lang::Class::getPrivateField (jstring name)
+{
+  int hash = name->hashCode ();
+
+  java::lang::reflect::Field* rfield;
+  for (int i = 0;  i < field_count;  i++)
+    {
+      _Jv_Field *field = &fields[i];
+      if (! _Jv_equal (field->name, name, hash))
+	continue;
+      rfield = new java::lang::reflect::Field ();
+      rfield->offset = (char*) field - (char*) fields;
+      rfield->declaringClass = this;
+      rfield->name = name;
+      return rfield;
+    }
+  jclass superclass = getSuperclass();
+  if (superclass == NULL)
+    return NULL;
+  rfield = superclass->getPrivateField(name);
+  for (int i = 0; i < interface_count && rfield == NULL; ++i)
+    rfield = interfaces[i]->getPrivateField (name);
+  return rfield;
+}
+
+// Only used by serialization
+java::lang::reflect::Method *
+java::lang::Class::getPrivateMethod (jstring name, JArray<jclass> *param_types)
+{
+  jstring partial_sig = getSignature (param_types, false);
+  jint p_len = partial_sig->length();
+  _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
+  for (Class *klass = this; klass; klass = klass->getSuperclass())
+    {
+      int i = klass->isPrimitive () ? 0 : klass->method_count;
+      while (--i >= 0)
+	{
+	  if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
+	      && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len))
+	    {
+	      // Found it.
+	      using namespace java::lang::reflect;
+
+	      Method *rmethod = new Method ();
+	      rmethod->offset = ((char *) (&klass->methods[i])
+				 - (char *) klass->methods);
+	      rmethod->declaringClass = klass;
+	      return rmethod;
+	    }
+	}
+    }
+  throw new java::lang::NoSuchMethodException (name);
+}
+
+// Private accessor method for Java code to retrieve the protection domain.
+java::security::ProtectionDomain *
+java::lang::Class::getProtectionDomain0 ()
+{
+  return protectionDomain;
+}
+
+JArray<jobject> *
+java::lang::Class::getSigners()
+{
+  return hack_signers;
+}
+
+void
+java::lang::Class::setSigners(JArray<jobject> *s)
+{
+  hack_signers = s;
+}
+
+
+
+//
+// Some class-related convenience functions.
+//
+
+// Find a method declared in the class.  If it is not declared locally
+// (or if it is inherited), return NULL.
+_Jv_Method *
+_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
+		    _Jv_Utf8Const *signature)
+{
+  for (int i = 0; i < klass->method_count; ++i)
+    {
+      if (_Jv_equalUtf8Consts (name, klass->methods[i].name)
+	  && _Jv_equalUtf8Consts (signature, klass->methods[i].signature))
+	return &klass->methods[i];
+    }
+  return NULL;
+}
+
+_Jv_Method *
+_Jv_LookupDeclaredMethod (jclass klass, _Jv_Utf8Const *name,
+                          _Jv_Utf8Const *signature,
+			  jclass *declarer_result)
+{
+  for (; klass; klass = klass->getSuperclass())
+    {
+      _Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
+
+      if (meth)
+	{
+	  if (declarer_result)
+	    *declarer_result = klass;
+	  return meth;
+	}
+    }
+
+  return NULL;
+}
+
+#ifdef HAVE_TLS
+
+// NOTE: MCACHE_SIZE should be a power of 2 minus one.
+#define MCACHE_SIZE 31
+
+struct _Jv_mcache
+{
+  jclass klass;
+  _Jv_Method *method;
+};
+
+static __thread _Jv_mcache *method_cache;
+#endif // HAVE_TLS
+
+static void *
+_Jv_FindMethodInCache (jclass klass MAYBE_UNUSED,
+		       _Jv_Utf8Const *name MAYBE_UNUSED,
+		       _Jv_Utf8Const *signature MAYBE_UNUSED)
+{
+#ifdef HAVE_TLS
+  _Jv_mcache *cache = method_cache;
+  if (cache)
+    {
+      int index = name->hash16 () & MCACHE_SIZE;
+      _Jv_mcache *mc = &cache[index];
+      _Jv_Method *m = mc->method;
+
+      if (mc->klass == klass
+	  && _Jv_equalUtf8Consts (m->name, name)
+	  && _Jv_equalUtf8Consts (m->signature, signature))
+	return mc->method->ncode;
+    }
+#endif // HAVE_TLS
+  return NULL;
+}
+
+static void
+_Jv_AddMethodToCache (jclass klass MAYBE_UNUSED,
+		      _Jv_Method *method MAYBE_UNUSED)
+{
+#ifdef HAVE_TLS
+  if (method_cache == NULL)
+    method_cache = (_Jv_mcache *) _Jv_MallocUnchecked((MCACHE_SIZE + 1)
+						      * sizeof (_Jv_mcache));
+  // If the allocation failed, just keep going.
+  if (method_cache != NULL)
+    {
+      int index = method->name->hash16 () & MCACHE_SIZE;
+      method_cache[index].method = method;
+      method_cache[index].klass = klass;
+    }
+#endif // HAVE_TLS
+}
+
+// Free this thread's method cache.  We explicitly manage this memory
+// as the GC does not yet know how to scan TLS on all platforms.
+void
+_Jv_FreeMethodCache ()
+{
+#ifdef HAVE_TLS
+  if (method_cache != NULL)
+    {
+      _Jv_Free(method_cache);
+      method_cache = NULL;
+    }
+#endif // HAVE_TLS
+}
+
+void *
+_Jv_LookupInterfaceMethod (jclass klass, _Jv_Utf8Const *name,
+                           _Jv_Utf8Const *signature)
+{
+  using namespace java::lang::reflect;
+
+  void *ncode = _Jv_FindMethodInCache (klass, name, signature);
+  if (ncode != 0)
+    return ncode;
+
+  for (; klass; klass = klass->getSuperclass())
+    {
+      _Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
+      if (! meth)
+        continue;
+
+      if (Modifier::isStatic(meth->accflags))
+	throw new java::lang::IncompatibleClassChangeError
+	  (_Jv_GetMethodString (klass, meth));
+      if (Modifier::isAbstract(meth->accflags))
+	throw new java::lang::AbstractMethodError
+	  (_Jv_GetMethodString (klass, meth));
+      if (! Modifier::isPublic(meth->accflags))
+	throw new java::lang::IllegalAccessError
+	  (_Jv_GetMethodString (klass, meth));
+
+      _Jv_AddMethodToCache (klass, meth);
+
+      return meth->ncode;
+    }
+  throw new java::lang::IncompatibleClassChangeError;
+}
+
+// Fast interface method lookup by index.
+void *
+_Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface, int method_idx)
+{
+  _Jv_IDispatchTable *cldt = klass->idt;
+  int idx = iface->ioffsets[cldt->iindex] + method_idx;
+  return cldt->itable[idx];
+}
+
+jboolean
+_Jv_IsAssignableFrom (jclass source, jclass target)
+{
+  if (source == target)
+    return true;
+
+  // If target is array, so must source be.  
+  while (target->isArray ())
+    {
+      if (! source->isArray())
+	return false;
+      target = target->getComponentType();
+      source = source->getComponentType();
+    }
+
+  if (target->isInterface())
+    {
+      // Abstract classes have no IDT, and IDTs provide no way to check
+      // two interfaces for assignability.
+      if (__builtin_expect 
+          (source->idt == NULL || source->isInterface(), false))
+        return _Jv_InterfaceAssignableFrom (source, target);
+
+      _Jv_IDispatchTable *cl_idt = source->idt;
+
+      if (__builtin_expect ((target->ioffsets == NULL), false))
+	return false; // No class implementing TARGET has been loaded.    
+      jshort cl_iindex = cl_idt->iindex;
+      if (cl_iindex < target->ioffsets[0])
+        {
+	  jshort offset = target->ioffsets[cl_iindex];
+	  if (offset != -1 && offset < cl_idt->itable_length
+	      && cl_idt->itable[offset] == target)
+	    return true;
+	}
+      return false;
+    }
+
+  // Primitive TYPE classes are only assignable to themselves.
+  if (__builtin_expect (target->isPrimitive() || source->isPrimitive(), false))
+    return false;
+
+  if (target == &java::lang::Object::class$)
+    return true;
+  else if (source->ancestors == NULL || target->ancestors == NULL)
+    {
+      // We need this case when either SOURCE or TARGET has not has
+      // its constant-time tables prepared.
+
+      // At this point we know that TARGET can't be Object, so it is
+      // safe to use that as the termination point.
+      while (source && source != &java::lang::Object::class$)
+	{
+	  if (source == target)
+	    return true;
+	  source = source->getSuperclass();
+	}
+    }
+  else if (source->depth >= target->depth
+	   && source->ancestors[source->depth - target->depth] == target)
+    return true;
+
+  return false;
+}
+
+// Interface type checking, the slow way. Returns TRUE if IFACE is a 
+// superinterface of SOURCE. This is used when SOURCE is also an interface,
+// or a class with no interface dispatch table.
+jboolean
+_Jv_InterfaceAssignableFrom (jclass source, jclass iface)
+{
+  for (int i = 0; i < source->interface_count; i++)
+    {
+      jclass interface = source->interfaces[i];
+      if (iface == interface
+          || _Jv_InterfaceAssignableFrom (interface, iface))
+        return true;      
+    }
+    
+  if (!source->isInterface()
+      && source->superclass 
+      && _Jv_InterfaceAssignableFrom (source->superclass, iface))
+    return true;
+        
+  return false;
+}
+
+jboolean
+_Jv_IsInstanceOf(jobject obj, jclass cl)
+{
+  if (__builtin_expect (!obj, false))
+    return false;
+  return _Jv_IsAssignableFrom (JV_CLASS (obj), cl);
+}
+
+void *
+_Jv_CheckCast (jclass c, jobject obj)
+{
+  if (__builtin_expect 
+      (obj != NULL && ! _Jv_IsAssignableFrom(JV_CLASS (obj), c), false))
+    throw new java::lang::ClassCastException
+      ((new java::lang::StringBuffer
+	(obj->getClass()->getName()))->append
+       (JvNewStringUTF(" cannot be cast to "))->append
+       (c->getName())->toString());
+
+  return obj;
+}
+
+void
+_Jv_CheckArrayStore (jobject arr, jobject obj)
+{
+  if (obj)
+    {
+      JvAssert (arr != NULL);
+      jclass elt_class = (JV_CLASS (arr))->getComponentType();
+      if (elt_class == &java::lang::Object::class$)
+	return;
+      jclass obj_class = JV_CLASS (obj);
+      if (__builtin_expect 
+          (! _Jv_IsAssignableFrom (obj_class, elt_class), false))
+	throw new java::lang::ArrayStoreException
+		((new java::lang::StringBuffer
+		 (JvNewStringUTF("Cannot store ")))->append
+		 (obj_class->getName())->append
+		 (JvNewStringUTF(" in array of type "))->append
+		 (elt_class->getName())->toString());
+    }
+}
+
+jboolean
+_Jv_IsAssignableFromSlow (jclass source, jclass target)
+{
+  // First, strip arrays.
+  while (target->isArray ())
+    {
+      // If target is array, source must be as well.
+      if (! source->isArray ())
+       return false;
+      target = target->getComponentType ();
+      source = source->getComponentType ();
+    }
+
+  // Quick success.
+  if (target == &java::lang::Object::class$)
+    return true;
+
+  // Ensure that the classes have their supers installed.
+  _Jv_Linker::wait_for_state (source, JV_STATE_LOADING);
+  _Jv_Linker::wait_for_state (target, JV_STATE_LOADING);
+
+  do
+    {
+      if (source == target)
+       return true;
+
+      if (target->isPrimitive () || source->isPrimitive ())
+       return false;
+
+      if (target->isInterface ())
+       {
+         for (int i = 0; i < source->interface_count; ++i)
+           {
+             // We use a recursive call because we also need to
+             // check superinterfaces.
+             if (_Jv_IsAssignableFromSlow (source->getInterface (i), target))
+               return true;
+           }
+       }
+      source = source->getSuperclass ();
+    }
+  while (source != NULL);
+
+  return false;
+}
+
+// Lookup an interface method by name.  This is very similar to
+// purpose to _getMethod, but the interfaces are quite different.  It
+// might be a good idea for _getMethod to call this function.
+//
+// Return true of the method is found, with the class in FOUND_CLASS
+// and the index in INDEX.
+bool
+_Jv_getInterfaceMethod (jclass search_class, jclass &found_class, int &index,
+			const _Jv_Utf8Const *utf_name,  
+			const _Jv_Utf8Const *utf_sig)
+{
+   for (jclass klass = search_class; klass; klass = klass->getSuperclass())
+    {
+      // FIXME: Throw an exception?
+      if (!klass->isInterface ())
+	return false;
+      
+      int max = klass->method_count;
+      int offset = 0;
+      for (int i = 0; i < max; ++i)
+	{
+	  // Skip <clinit> here, as it will not be in the IDT.
+	  if (klass->methods[i].name->first() == '<')
+	    continue;
+
+	  if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
+	      && _Jv_equalUtf8Consts (klass->methods[i].signature, utf_sig))
+	    {
+	      // Found it.
+	      using namespace java::lang::reflect;
+
+	      // FIXME: Method must be public.  Throw an exception?
+	      if (! Modifier::isPublic (klass->methods[i].accflags))
+		break;
+
+	      found_class = klass;
+	      // Interface method indexes count from 1.
+	      index = offset + 1;
+	      return true;
+	    }
+
+	  ++offset;
+	}
+    }
+
+  // If we haven't found a match, and this class is an interface, then
+  // check all the superinterfaces.
+  if (search_class->isInterface())
+    {
+      for (int i = 0; i < search_class->interface_count; ++i)
+	{
+	  using namespace java::lang::reflect;
+	  bool found = _Jv_getInterfaceMethod (search_class->interfaces[i], 
+					       found_class, index,
+					       utf_name, utf_sig);
+	  if (found)
+	    return true;
+	}
+    }
+
+  return false;
+}
+
+#ifdef INTERPRETER
+_Jv_MethodBase *
+_Jv_FindInterpreterMethod (jclass klass, jmethodID desired_method)
+{
+  using namespace java::lang::reflect;
+
+  _Jv_InterpClass *iclass
+    = reinterpret_cast<_Jv_InterpClass *> (klass->aux_info);
+  _Jv_MethodBase **imethods = _Jv_GetFirstMethod (iclass);
+
+  for (int i = 0; i < JvNumMethods (klass); ++i)
+    {
+      _Jv_MethodBase *imeth = imethods[i];
+      if (imeth->get_method () == desired_method)
+	return imeth;
+    }
+
+  return NULL;
+}
+#endif
+
+// Return Utf8 name of a class. This function is here for code that
+// can't access klass->name directly.
+_Jv_Utf8Const*
+_Jv_GetClassNameUtf8 (jclass klass)
+{
+  return klass->name;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natClassLoader.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natClassLoader.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natClassLoader.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natClassLoader.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,624 @@
+// natClassLoader.cc - Implementation of java.lang.ClassLoader native methods.
+
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+/* Author: Kresten Krab Thorup <krab at gnu.org>  */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <execution.h>
+
+#include <java-threads.h>
+#include <java-interp.h>
+
+#include <java/lang/Character.h>
+#include <java/lang/Thread.h>
+#include <java/lang/ClassLoader.h>
+#include <java/lang/InternalError.h>
+#include <java/lang/IllegalAccessError.h>
+#include <java/lang/LinkageError.h>
+#include <java/lang/NoClassDefFoundError.h>
+#include <java/lang/ClassNotFoundException.h>
+#include <java/lang/ClassCircularityError.h>
+#include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/ClassFormatError.h>
+#include <java/lang/VirtualMachineError.h>
+#include <java/lang/VMClassLoader.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/Runtime.h>
+#include <java/lang/StringBuffer.h>
+#include <java/io/Serializable.h>
+#include <java/lang/Cloneable.h>
+#include <java/util/HashMap.h>
+#include <gnu/gcj/runtime/BootClassLoader.h>
+#include <gnu/gcj/runtime/SystemClassLoader.h>
+
+// Size of local hash table.
+#define HASH_LEN 1013
+
+// Hash function for Utf8Consts.
+#define HASH_UTF(Utf) ((Utf)->hash16() % HASH_LEN)
+
+// This records classes which will be registered with the system class
+// loader when it is initialized.
+static jclass system_class_list;
+
+// This is used as the value of system_class_list after we have
+// initialized the system class loader; it lets us know that we should
+// no longer pay attention to the system abi flag.
+#define SYSTEM_LOADER_INITIALIZED ((jclass) -1)
+
+static jclass loaded_classes[HASH_LEN];
+
+// This is the root of a linked list of classes
+static jclass stack_head;
+
+// While bootstrapping we keep a list of classes we found, so that we
+// can register their packages.  There aren't many of these so we
+// just keep a small buffer here and abort if we overflow.
+#define BOOTSTRAP_CLASS_LIST_SIZE 20
+static jclass bootstrap_class_list[BOOTSTRAP_CLASS_LIST_SIZE];
+static int bootstrap_index;
+
+
+
+
+jclass
+java::lang::ClassLoader::loadClassFromSig(jstring name)
+{
+  int len = _Jv_GetStringUTFLength (name);
+  char sig[len + 1];
+  _Jv_GetStringUTFRegion (name, 0, name->length(), sig);
+  jclass result = _Jv_FindClassFromSignature(sig, this);
+  if (result == NULL)
+    throw new ClassNotFoundException(name);
+  return result;
+}
+
+
+
+// This tries to find a class in our built-in cache.  This cache is
+// used only for classes which are linked in to the executable or
+// loaded via dlopen().
+jclass
+_Jv_FindClassInCache (_Jv_Utf8Const *name)
+{
+  JvSynchronize sync (&java::lang::Class::class$);
+  jint hash = HASH_UTF (name);
+
+  jclass klass;
+  for (klass = loaded_classes[hash]; klass; klass = klass->next_or_version)
+    {
+      if (_Jv_equalUtf8Consts (name, klass->name))
+	break;
+    }
+
+  return klass;
+}
+
+void
+_Jv_UnregisterClass (jclass the_class)
+{
+  // This can happen if the class could not be defined properly.
+  if (! the_class->name)
+    return;
+
+  JvSynchronize sync (&java::lang::Class::class$);
+  jint hash = HASH_UTF(the_class->name);
+
+  jclass *klass = &(loaded_classes[hash]);
+  for ( ; *klass; klass = &((*klass)->next_or_version))
+    {
+      if (*klass == the_class)
+	{
+	  *klass = (*klass)->next_or_version;
+	  break;
+	}
+    }
+}
+
+// Register an initiating class loader for a given class.
+void
+_Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
+{
+  if (! loader)
+    loader = java::lang::VMClassLoader::bootLoader;
+  if (! loader)
+    {
+      // Very early in the bootstrap process, the Bootstrap classloader may 
+      // not exist yet.
+      // FIXME: We could maintain a list of these and come back and register
+      // them later.
+      return;
+    }
+  loader->loadedClasses->put(klass->name->toString(), klass);
+}
+
+// If we found an error while defining an interpreted class, we must
+// go back and unregister it.
+void
+_Jv_UnregisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
+{
+  if (! loader)
+    loader = java::lang::VMClassLoader::bootLoader;
+  loader->loadedClasses->remove(klass->name->toString());
+}
+
+
+// Class registration.
+//
+// There are two kinds of functions that register classes.  
+//
+// Type 1:
+//
+// These take the address of a class that is in an object file.
+// Because these classes are not allocated on the heap, It is also
+// necessary to register the address of the object for garbage
+// collection.  This is used with the "old" C++ ABI and with
+// -findirect-dispatch -fno-indirect-classes.
+//
+// Type 2:
+//
+// These take an initializer struct, create the class, and return the
+// address of the newly created class to their caller.  These are used
+// with -findirect-dispatch.
+//
+// _Jv_RegisterClasses() and _Jv_RegisterClasses_Counted() are
+// functions of Type 1, and _Jv_NewClassFromInitializer() and
+// _Jv_RegisterNewClasses() are of Type 2.
+
+
+// This function is called many times during startup, before main() is
+// run.  At that point in time we know for certain we are running 
+// single-threaded, so we don't need to lock when adding classes to the 
+// class chain.  At all other times, the caller should synchronize on
+// Class::class$.
+void
+_Jv_RegisterClasses (const jclass *classes)
+{
+  _Jv_RegisterLibForGc (classes);
+
+  for (; *classes; ++classes)
+    {
+      jclass klass = *classes;
+
+      if (_Jv_CheckABIVersion ((unsigned long) klass->next_or_version))
+	(*_Jv_RegisterClassHook) (klass);
+    }
+}
+
+// This is a version of _Jv_RegisterClasses that takes a count.
+void
+_Jv_RegisterClasses_Counted (const jclass * classes, size_t count)
+{
+  size_t i;
+
+  _Jv_RegisterLibForGc (classes);
+
+  for (i = 0; i < count; i++)
+    {
+      jclass klass = classes[i];
+
+      if (_Jv_CheckABIVersion ((unsigned long) klass->next_or_version))
+	(*_Jv_RegisterClassHook) (klass);
+    }
+}
+
+// Create a class on the heap from an initializer struct.
+jclass
+_Jv_NewClassFromInitializer (const char *class_initializer)
+{
+  /* We create an instance of java::lang::Class and copy all of its
+     fields except the first word (the vtable pointer) from
+     CLASS_INITIALIZER.  This first word is pre-initialized by
+     _Jv_AllocObj, and we don't want to overwrite it.  */
+
+  jclass new_class
+    = (jclass)_Jv_AllocObj (sizeof (java::lang::Class),
+			    &java::lang::Class::class$);
+  const char *src = class_initializer + sizeof (void*);
+  char *dst = (char*)new_class + sizeof (void*);
+  size_t len = sizeof (*new_class) - sizeof (void*);
+  memcpy (dst, src, len);
+
+  new_class->engine = &_Jv_soleIndirectCompiledEngine;
+
+  /* FIXME:  Way back before the dawn of time, we overloaded the
+     SYNTHETIC class access modifier to mean INTERPRETED.  This was a
+     Bad Thing, but it didn't matter then because classes were never
+     marked synthetic.  However, it is possible to redeem the
+     situation: _Jv_NewClassFromInitializer is only called from
+     compiled classes, so we clear the INTERPRETED flag.  This is a
+     kludge!  */
+  new_class->accflags &= ~java::lang::reflect::Modifier::INTERPRETED;
+
+  if (_Jv_CheckABIVersion ((unsigned long) new_class->next_or_version))
+    (*_Jv_RegisterClassHook) (new_class);
+  
+  return new_class;
+}
+
+// Called by compiler-generated code at DSO initialization.  CLASSES
+// is an array of pairs: the first item of each pair is a pointer to
+// the initialized data that is a class initializer in a DSO, and the
+// second is a pointer to a class reference.
+// _Jv_NewClassFromInitializer() creates the new class (on the Java
+// heap) and we write the address of the new class into the address
+// pointed to by the second word.
+void
+_Jv_RegisterNewClasses (char **classes)
+{
+  _Jv_InitGC ();
+
+  const char *initializer;
+
+  while ((initializer = *classes++))
+    {
+      jclass *class_ptr = (jclass *)*classes++;
+      *class_ptr = _Jv_NewClassFromInitializer (initializer);
+    }      
+}
+  
+void
+_Jv_RegisterClassHookDefault (jclass klass)
+{
+  // This is bogus, but there doesn't seem to be a better place to do
+  // it.
+  if (! klass->engine)
+    klass->engine = &_Jv_soleCompiledEngine;
+
+  if (system_class_list != SYSTEM_LOADER_INITIALIZED)
+    {
+      unsigned long abi = (unsigned long) klass->next_or_version;
+      if (! _Jv_ClassForBootstrapLoader (abi))
+	{
+	  klass->next_or_version = system_class_list;
+	  system_class_list = klass;
+	  return;
+	}
+    }
+
+  jint hash = HASH_UTF (klass->name);
+
+  // If the class is already registered, don't re-register it.
+  for (jclass check_class = loaded_classes[hash];
+       check_class != NULL;
+       check_class = check_class->next_or_version)
+    {
+      if (check_class == klass)
+	{
+	  // If you get this, it means you have the same class in two
+	  // different libraries.
+#define TEXT "Duplicate class registration: "
+	  // We size-limit MESSAGE so that you can't trash the stack.
+	  char message[200];
+	  strcpy (message, TEXT);
+	  strncpy (message + sizeof (TEXT) - 1, klass->name->chars(),
+		   sizeof (message) - sizeof (TEXT));
+	  message[sizeof (message) - 1] = '\0';
+	  if (! gcj::runtimeInitialized)
+	    JvFail (message);
+	  else
+	    {
+	      java::lang::String *str = JvNewStringLatin1 (message);
+	      throw new java::lang::VirtualMachineError (str);
+	    }
+	}
+    }
+
+  klass->next_or_version = loaded_classes[hash];
+  loaded_classes[hash] = klass;
+}
+
+// A pointer to a function that actually registers a class.
+// Normally _Jv_RegisterClassHookDefault, but could be some other function
+// that registers the class in e.g. a ClassLoader-local table.
+// Should synchronize on Class:class$ while setting/restore this variable.
+
+void (*_Jv_RegisterClassHook) (jclass cl) = _Jv_RegisterClassHookDefault;
+
+void
+_Jv_RegisterClass (jclass klass)
+{
+  jclass classes[2];
+  classes[0] = klass;
+  classes[1] = NULL;
+  _Jv_RegisterClasses (classes);
+}
+
+// This is used during initialization to register all compiled-in
+// classes that are not part of the core with the system class loader.
+void
+_Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::SystemClassLoader *loader)
+{
+  for (jclass klass = system_class_list;
+       klass;
+       klass = klass->next_or_version)
+    {
+      klass->loader = loader;
+      loader->addClass(klass);
+    }
+  system_class_list = SYSTEM_LOADER_INITIALIZED;
+}
+
+// An internal variant of _Jv_FindClass which simply swallows a
+// NoClassDefFoundError or a ClassNotFoundException. This gives the
+// caller a chance to evaluate the situation and behave accordingly.
+jclass
+_Jv_FindClassNoException (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
+{
+  jclass klass;
+
+  try
+    {
+      klass = _Jv_FindClass(name, loader);
+    }
+  catch ( java::lang::NoClassDefFoundError *ncdfe )
+    {
+      return NULL;
+    }
+  catch ( java::lang::ClassNotFoundException *cnfe )
+    {
+      return NULL;
+    }
+
+  return klass;
+}
+
+jclass
+_Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
+{
+  // See if the class was already loaded by this loader.  This handles
+  // initiating loader checks, as we register classes with their
+  // initiating loaders.
+
+  java::lang::ClassLoader *boot = java::lang::VMClassLoader::bootLoader;
+  java::lang::ClassLoader *real = loader;
+  if (! real)
+    real = boot;
+  jstring sname = name->toString();
+  // We might still be bootstrapping the VM, in which case there
+  // won't be a bootstrap class loader yet.
+  jclass klass = real ? real->findLoadedClass (sname) : NULL;
+
+  if (! klass)
+    {
+      if (loader)
+	{
+	  // Load using a user-defined loader, jvmspec 5.3.2.
+	  // Note that we explicitly must call the single-argument form.
+	  klass = loader->loadClass(sname);
+
+	  // If "loader" delegated the loadClass operation to another
+	  // loader, explicitly register that it is also an initiating
+	  // loader of the given class.
+	  java::lang::ClassLoader *delegate = (loader == boot
+					       ? NULL
+					       : loader);
+	  if (klass && klass->getClassLoaderInternal () != delegate)
+	    _Jv_RegisterInitiatingLoader (klass, loader);
+	}
+      else if (boot)
+	{
+	  // Load using the bootstrap loader jvmspec 5.3.1.
+	  klass = java::lang::VMClassLoader::loadClass (sname, false); 
+
+	  // Register that we're an initiating loader.
+	  if (klass)
+	    _Jv_RegisterInitiatingLoader (klass, 0);
+	}
+      else
+	{
+	  // Not even a bootstrap loader, try the built-in cache.
+	  klass = _Jv_FindClassInCache (name);
+
+	  if (klass)
+	    {
+	      bool found = false;
+	      for (int i = 0; i < bootstrap_index; ++i)
+		{
+		  if (bootstrap_class_list[i] == klass)
+		    {
+		      found = true;
+		      break;
+		    }
+		}
+	      if (! found)
+		{
+		  if (bootstrap_index == BOOTSTRAP_CLASS_LIST_SIZE)
+		    abort ();
+		  bootstrap_class_list[bootstrap_index++] = klass;
+		}
+	    }
+	}
+    }
+
+  return klass;
+}
+
+void
+_Jv_RegisterBootstrapPackages ()
+{
+  for (int i = 0; i < bootstrap_index; ++i)
+    java::lang::VMClassLoader::definePackageForNative(bootstrap_class_list[i]->getName());
+}
+
+jclass
+_Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
+	      java::lang::ClassLoader *loader)
+{
+  jclass ret = (jclass) _Jv_AllocObject (&java::lang::Class::class$);
+  ret->name = name;
+  ret->superclass = superclass;
+  ret->loader = loader;
+
+  _Jv_RegisterInitiatingLoader (ret, loader);
+
+  return ret;
+}
+
+static _Jv_IDispatchTable *array_idt = NULL;
+static jshort array_depth = 0;
+static jclass *array_ancestors = NULL;
+
+static jclass interfaces[] =
+{
+  &java::lang::Cloneable::class$,
+  &java::io::Serializable::class$
+};
+
+// Create a class representing an array of ELEMENT and store a pointer to it
+// in element->arrayclass. LOADER is the ClassLoader which _initiated_ the 
+// instantiation of this array. ARRAY_VTABLE is the vtable to use for the new 
+// array class. This parameter is optional.
+void
+_Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader,
+		   _Jv_VTable *array_vtable)
+{
+  JvSynchronize sync (element);
+
+  _Jv_Utf8Const *array_name;
+  int len;
+
+  if (element->arrayclass)
+    return;
+
+  if (element->isPrimitive())
+    {
+      if (element == JvPrimClass (void))
+	throw new java::lang::ClassNotFoundException ();
+      len = 3;
+    }
+  else
+    len = element->name->len() + 5;
+
+  {
+    char signature[len];
+    int index = 0;
+    signature[index++] = '[';
+    // Compute name of array class.
+    if (element->isPrimitive())
+      {
+	signature[index++] = (char) element->method_count;
+      }
+    else
+      {
+	size_t length = element->name->len();
+	const char *const name = element->name->chars();
+	if (name[0] != '[')
+	  signature[index++] = 'L';
+	memcpy (&signature[index], name, length);
+	index += length;
+	if (name[0] != '[')
+	  signature[index++] = ';';
+      }      
+    array_name = _Jv_makeUtf8Const (signature, index);
+  }
+
+  // Create new array class.
+  jclass array_class = _Jv_NewClass (array_name, &java::lang::Object::class$,
+  				     element->loader);
+
+  // Note that `vtable_method_count' doesn't include the initial
+  // gc_descr slot.
+  int dm_count = java::lang::Object::class$.vtable_method_count;
+
+  // Create a new vtable by copying Object's vtable.
+  _Jv_VTable *vtable;
+  if (array_vtable)
+    vtable = array_vtable;
+  else
+    vtable = _Jv_VTable::new_vtable (dm_count);
+  vtable->clas = array_class;
+  vtable->gc_descr = java::lang::Object::class$.vtable->gc_descr;
+  for (int i = 0; i < dm_count; ++i)
+    vtable->set_method (i, java::lang::Object::class$.vtable->get_method (i));
+
+  array_class->vtable = vtable;
+  array_class->vtable_method_count
+    = java::lang::Object::class$.vtable_method_count;
+
+  // Stash the pointer to the element type.
+  array_class->element_type = element;
+
+  // Register our interfaces.
+  array_class->interfaces = interfaces;
+  array_class->interface_count = sizeof interfaces / sizeof interfaces[0];
+
+  // Since all array classes have the same interface dispatch table, we can 
+  // cache one and reuse it. It is not necessary to synchronize this.
+  if (!array_idt)
+    {
+      _Jv_Linker::wait_for_state(array_class, JV_STATE_PREPARED);
+      array_idt = array_class->idt;
+      array_depth = array_class->depth;
+      array_ancestors = array_class->ancestors;
+    }
+  else
+    {
+      array_class->idt = array_idt;
+      array_class->depth = array_depth;
+      array_class->ancestors = array_ancestors;
+    }
+
+  using namespace java::lang::reflect;
+  {
+    // Array classes are "abstract final" and inherit accessibility
+    // from element type, per vmspec 5.3.3.2
+    _Jv_ushort accflags = (Modifier::FINAL | Modifier::ABSTRACT
+			   | (element->accflags
+			      & (Modifier::PUBLIC | Modifier::PROTECTED
+				 | Modifier::PRIVATE)));
+    array_class->accflags = accflags;
+  }
+
+  // An array class has no visible instance fields. "length" is invisible to 
+  // reflection.
+
+  // Say this class is initialized and ready to go!
+  array_class->state = JV_STATE_DONE;
+
+  // vmspec, section 5.3.3 describes this
+  if (element->loader != loader)
+    _Jv_RegisterInitiatingLoader (array_class, loader);
+
+  element->arrayclass = array_class;
+}
+
+// These two functions form a stack of classes.   When a class is loaded
+// it is pushed onto the stack by the class loader; this is so that
+// StackTrace can quickly determine which classes have been loaded.
+
+jclass
+_Jv_PopClass (void)
+{
+  JvSynchronize sync (&java::lang::Class::class$);
+  if (stack_head)
+    {
+      jclass tmp = stack_head;
+      stack_head = tmp->chain;
+      return tmp;
+    }
+  return NULL;
+}
+
+void
+_Jv_PushClass (jclass k)
+{
+  JvSynchronize sync (&java::lang::Class::class$);
+  jclass tmp = stack_head;
+  stack_head = k;
+  k->chain = tmp;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natDouble.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natDouble.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natDouble.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natDouble.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,214 @@
+// natDouble.cc - Implementation of java.lang.VMDouble native methods.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005, 2006  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <java/lang/String.h>
+#include <java/lang/Double.h>
+#include <java/lang/VMDouble.h>
+#include <java/lang/Character.h>
+#include <java/lang/NumberFormatException.h>
+#include <jvm.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "fdlibm.h"
+
+union u
+{
+  jlong l;
+  jdouble d;
+};
+
+jlong 
+java::lang::VMDouble::doubleToLongBits(jdouble value)
+{
+  union u u;
+  u.d = value;
+  
+  jlong e = u.l & 0x7ff0000000000000LL;
+  jlong f = u.l & 0x000fffffffffffffLL;
+
+  if (e == 0x7ff0000000000000LL && f != 0L)
+    u.l = 0x7ff8000000000000LL;
+
+  return u.l;
+}
+
+jlong 
+java::lang::VMDouble::doubleToRawLongBits(jdouble value)
+{
+  union u u;
+  u.d = value;
+  return u.l;
+}
+
+jdouble 
+java::lang::VMDouble::longBitsToDouble(jlong bits)
+{
+  union u u;
+  u.l = bits;
+  return u.d;
+}
+
+jstring 
+java::lang::VMDouble::toString(jdouble value, jboolean isFloat)
+{
+  if (Double::isNaN (value))
+    return JvNewStringLatin1 ("NaN", sizeof ("NaN") - 1);
+    
+  if (value == Double::POSITIVE_INFINITY)
+    return JvNewStringLatin1 ("Infinity", sizeof ("Infinity") - 1);
+    
+  if (value == Double::NEGATIVE_INFINITY)
+    return JvNewStringLatin1 ("-Infinity", sizeof ("-Infinity") - 1);
+    
+  char buffer[50], result[50];
+  int decpt, sign;
+
+  _dtoa (value, 0, 20, &decpt, &sign, NULL, buffer, (int)isFloat);
+
+  value = fabs (value);
+
+  char *s = buffer;
+  char *d = result;
+
+  if (sign)
+    *d++ = '-';
+
+  if (value >= 1e-3 && value < 1e7 || value == 0)
+    {
+      if (decpt <= 0)
+	*d++ = '0';
+      else
+	{
+	  for (int i = 0; i < decpt; i++)
+	    if (*s)
+	      *d++ = *s++;
+	    else
+	      *d++ = '0';
+	}
+
+      *d++ = '.';
+
+      if (*s == 0)
+	{
+	  *d++ = '0';
+	  decpt++;
+	}
+	  
+      while (decpt++ < 0)
+	*d++ = '0';      
+      
+      while (*s)
+	*d++ = *s++;
+
+      *d = 0;
+
+      return JvNewStringLatin1 (result, strlen (result));
+    }
+
+  *d++ = *s++;
+  decpt--;
+  *d++ = '.';
+  
+  if (*s == 0)
+    *d++ = '0';
+
+  while (*s)
+    *d++ = *s++;
+
+  *d++ = 'E';
+  
+  if (decpt < 0)
+    {
+      *d++ = '-';
+      decpt = -decpt;
+    }
+
+  {
+    char exp[4];
+    char *e = exp + sizeof exp;
+    
+    *--e = 0;
+    do
+      {
+	*--e = '0' + decpt % 10;
+	decpt /= 10;
+      }
+    while (decpt > 0);
+
+    while (*e)
+      *d++ = *e++;
+  }
+  
+  *d = 0;
+
+  return JvNewStringLatin1 (result, strlen (result));
+}
+
+jdouble 
+java::lang::VMDouble::parseDouble(jstring str)
+{
+  int length = str->length();
+
+  while (length > 0
+	 && Character::isWhitespace(str->charAt(length - 1)))
+    length--;
+
+  // The String could end with a f/F/d/D which is valid but we don't need.
+  bool saw_trailer = false;
+  if (length > 0)
+    {
+      jchar last = str->charAt(length-1);
+      if (last == 'f' || last == 'F' || last == 'd' || last == 'D')
+	{
+	  length--;
+	  saw_trailer = true;
+	}
+    }
+
+  jsize start = 0;
+  while (length > 0
+	 && Character::isWhitespace(str->charAt(start)))
+    start++, length--;
+
+  if (length > 0)
+    {
+      // Note that UTF can expand 3x.
+      char *data = (char *) __builtin_alloca (3 * length + 1);
+      jsize blength = _Jv_GetStringUTFRegion (str, start, length, data);
+      data[blength] = 0; 
+
+      if (! saw_trailer)
+	{
+	  if (! strcmp (data, "NaN") || ! strcmp (data, "+NaN")
+	      || ! strcmp (data, "-NaN"))
+	    return Double::NaN;
+	  else if (! strcmp (data, "Infinity") || ! strcmp (data, "+Infinity"))
+	    return Double::POSITIVE_INFINITY;
+	  else if (! strcmp (data, "-Infinity"))
+	    return Double::NEGATIVE_INFINITY;
+	}
+
+      struct _Jv_reent reent;  
+      memset (&reent, 0, sizeof reent);
+
+      char *endptr;
+      double val = _strtod_r (&reent, data, &endptr);
+      if (endptr == data + blength)
+	return val;
+    }
+  throw new NumberFormatException(str);
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natEcosProcess.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natEcosProcess.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natEcosProcess.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natEcosProcess.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,25 @@
+// natEcosProcess.cc - Native side of eCos processes.
+
+/* Copyright (C) 1998, 1999  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+// The configury system needs this file to exist, since we can't
+// really conditionally link files (an autoconf bug).  To avoid having
+// an empty translation unit, we make a single method native.  FIXME.
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/lang/ConcreteProcess.h>
+
+void
+java::lang::ConcreteProcess::destroy (void)
+{
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natFloat.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natFloat.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natFloat.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natFloat.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,52 @@
+// natFloat.cc - Implementation of java.lang.VMFloat native methods.
+
+/* Copyright (C) 1998, 1999, 2001, 2006  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include <java/lang/Float.h>
+#include <java/lang/VMFloat.h>
+#include <jvm.h>
+
+union u
+{
+  jint l;
+  jfloat d;
+};
+
+jint 
+java::lang::VMFloat::floatToIntBits(jfloat value)
+{
+  union u u;
+  u.d = value;
+  jint e = u.l & 0x7f800000;
+  jint f = u.l & 0x007fffff;
+
+  if (e == 0x7f800000 && f != 0)
+    u.l = 0x7fc00000;
+
+  return u.l;
+}
+
+jint 
+java::lang::VMFloat::floatToRawIntBits(jfloat value)
+{
+  union u u;
+  u.d = value;  
+  return u.l;
+}
+
+jfloat 
+java::lang::VMFloat::intBitsToFloat(jint bits)
+{
+  union u u;
+  u.l = bits;
+  return u.d;
+}
+

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natMath.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natMath.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natMath.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natMath.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,184 @@
+/* Copyright (C) 1998, 1999, 2000, 2002, 2006  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+ 
+/**
+ * @author Andrew Haley <aph at cygnus.com>
+ * @date Tue Sep 22 1998 */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status:  Believed complete and correct.
+ */
+ 
+#include <config.h>
+
+#include <java/lang/String.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Math.h>
+#include <gcj/array.h>
+
+#include "fdlibm.h"
+
+jdouble java::lang::Math::cos(jdouble x)
+{
+  return (jdouble)::cos((double)x);
+}  
+
+jdouble java::lang::Math::sin(jdouble x)
+{
+  return (jdouble)::sin((double)x);
+}  
+
+jdouble java::lang::Math::tan(jdouble x)
+{
+  return (jdouble)::tan((double)x);
+}  
+
+jdouble java::lang::Math::asin(jdouble x)
+{
+  return (jdouble)::asin((double)x);
+}  
+
+jdouble java::lang::Math::acos(jdouble x)
+{
+  return (jdouble)::acos((double)x);
+}  
+
+jdouble java::lang::Math::atan(jdouble x)
+{
+  return (jdouble)::atan((double)x);
+}  
+
+jdouble java::lang::Math::atan2(jdouble y, jdouble x)
+{
+  return (jdouble)::atan2((double)y, (double)x);
+}  
+
+jdouble java::lang::Math::log(jdouble x)
+{
+  return (jdouble)::log((double)x);
+}  
+
+jdouble java::lang::Math::exp(jdouble x)
+{
+  return (jdouble)::exp((double)x);
+}  
+
+jdouble java::lang::Math::sqrt(jdouble x)
+{
+  return (jdouble)::sqrt((double)x);
+}  
+
+jdouble java::lang::Math::pow(jdouble y, jdouble x)
+{
+  return (jdouble)::pow((double)y, (double)x);
+}  
+
+jdouble java::lang::Math::IEEEremainder(jdouble y, jdouble x)
+{
+  return (jdouble)::__ieee754_remainder((double)y, (double)x);
+}  
+
+jdouble java::lang::Math::rint(jdouble x)
+{
+  return (jdouble)::rint((double)x);
+}  
+
+jdouble java::lang::Math::floor(jdouble x)
+{
+  return (jdouble)::floor((double)x);
+}  
+
+jdouble java::lang::Math::ceil(jdouble x)
+{
+  return (jdouble)::ceil((double)x);
+}  
+
+jdouble java::lang::Math::log10(jdouble x)
+{
+  return (jdouble)::log10((double)x);
+}  
+
+jdouble java::lang::Math::cbrt(jdouble x)
+{
+  return (jdouble)::cbrt((double)x);
+}
+
+jdouble java::lang::Math::cosh(jdouble x)
+{
+  return (jdouble)::cosh((double)x);
+}
+
+jdouble java::lang::Math::expm1(jdouble x)
+{
+  return (jdouble)::expm1((double)x);
+}
+
+jdouble java::lang::Math::hypot(jdouble x, jdouble y)
+{
+  return (jdouble)::hypot((double)x, (double)y);
+}
+
+jdouble java::lang::Math::log1p(jdouble x)
+{
+  return (jdouble)::log1p((double)x);
+}
+
+jdouble java::lang::Math::sinh(jdouble x)
+{
+  return (jdouble)::sinh((double)x);
+}
+
+jdouble java::lang::Math::tanh(jdouble x)
+{
+  return (jdouble)::tanh((double)x);
+}
+
+static inline int
+floatToIntBits (jfloat value)
+{
+  union {
+    jint l;
+    jfloat d;
+  } u;
+  u.d = value;
+  return u.l;
+}
+
+static inline bool
+isNaN (jint bits)
+{
+  jint e = bits & 0x7f800000;
+  jint f = bits & 0x007fffff;
+
+  return e == 0x7f800000 && f != 0;
+}
+
+static inline jlong
+doubleToLongBits (jdouble value)
+{
+  union {
+    jlong l;
+    jdouble d;
+  } u;
+  u.d = value;
+  return u.l;
+}
+
+static inline bool 
+isNaN (jlong bits)
+{
+  jlong e = bits & 0x7ff0000000000000LL;
+  jlong f = bits & 0x000fffffffffffffLL;
+  
+  return e == 0x7ff0000000000000LL && f != 0LL;
+}
+

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natObject.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natObject.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natObject.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natObject.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1457 @@
+// natObject.cc - Implementation of the Object class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#include <string.h>
+
+#pragma implementation "Object.h"
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/lang/Object.h>
+#include <java-threads.h>
+#include <java-signal.h>
+#include <java/lang/CloneNotSupportedException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IllegalMonitorStateException.h>
+#include <java/lang/InterruptedException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Class.h>
+#include <java/lang/Cloneable.h>
+#include <java/lang/Thread.h>
+
+#ifdef LOCK_DEBUG
+#  include <stdio.h>
+#endif
+
+
+
+using namespace java::lang;
+
+// This is used to represent synchronization information.
+struct _Jv_SyncInfo
+{
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+  // We only need to keep track of initialization state if we can
+  // possibly finalize this object.
+  bool init;
+#endif
+  _Jv_ConditionVariable_t condition;
+  _Jv_Mutex_t mutex;
+};
+
+
+
+jclass
+java::lang::Object::getClass (void)
+{
+  _Jv_VTable **dt = (_Jv_VTable **) this;
+  return (*dt)->clas;
+}
+
+jint
+java::lang::Object::hashCode (void)
+{
+  return _Jv_HashCode (this);
+}
+
+jobject
+java::lang::Object::clone (void)
+{
+  jclass klass = getClass ();
+  jobject r;
+  jint size;
+
+  // We also clone arrays here.  If we put the array code into
+  // __JArray, then we'd have to figure out a way to find the array
+  // vtbl when creating a new array class.  This is easier, if uglier.
+  if (klass->isArray())
+    {
+      __JArray *array = (__JArray *) this;
+      jclass comp = getClass()->getComponentType();
+      jint eltsize;
+      if (comp->isPrimitive())
+	{
+	  r = _Jv_NewPrimArray (comp, array->length);
+	  eltsize = comp->size();
+	}
+      else
+	{
+	  r = _Jv_NewObjectArray (array->length, comp, NULL);
+	  eltsize = sizeof (jobject);
+	}
+      // We can't use sizeof on __JArray because we must account for
+      // alignment of the element type.
+      size = (_Jv_GetArrayElementFromElementType (array, comp) - (char *) array
+	      + array->length * eltsize);
+    }
+  else
+    {
+      if (! java::lang::Cloneable::class$.isAssignableFrom(klass))
+	throw new CloneNotSupportedException;
+
+      size = klass->size();
+      r = _Jv_AllocObject (klass);
+    }
+
+  memcpy ((void *) r, (void *) this, size);
+#ifndef JV_HASH_SYNCHRONIZATION
+  // Guarantee that the locks associated to the two objects are
+  // distinct.
+  r->sync_info = NULL;
+#endif
+  return r;
+}
+
+void
+_Jv_FinalizeObject (jobject obj)
+{
+  // Ignore exceptions.  From section 12.6 of the Java Language Spec.
+  try
+    {
+      obj->finalize ();
+    }
+  catch (java::lang::Throwable *t)
+    {
+      // Ignore.
+    }
+}
+
+
+//
+// Synchronization code.
+//
+
+#ifndef JV_HASH_SYNCHRONIZATION
+// This global is used to make sure that only one thread sets an
+// object's `sync_info' field.
+static _Jv_Mutex_t sync_mutex;
+
+// This macro is used to see if synchronization initialization is
+// needed.
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+#  define INIT_NEEDED(Obj) (! (Obj)->sync_info \
+			    || ! ((_Jv_SyncInfo *) ((Obj)->sync_info))->init)
+#else
+#  define INIT_NEEDED(Obj) (! (Obj)->sync_info)
+#endif
+
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+// If we have to run a destructor for a sync_info member, then this
+// function is registered as a finalizer for the sync_info.
+static void
+finalize_sync_info (jobject obj)
+{
+  _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj;
+#if defined (_Jv_HaveCondDestroy)
+  _Jv_CondDestroy (&si->condition);
+#endif
+#if defined (_Jv_HaveMutexDestroy)
+  _Jv_MutexDestroy (&si->mutex);
+#endif
+  si->init = false;
+}
+#endif
+
+// This is called to initialize the sync_info element of an object.
+void
+java::lang::Object::sync_init (void)
+{
+  _Jv_MutexLock (&sync_mutex);
+  // Check again to see if initialization is needed now that we have
+  // the lock.
+  if (INIT_NEEDED (this))
+    {
+      // We assume there are no pointers in the sync_info
+      // representation.
+      _Jv_SyncInfo *si;
+      // We always create a new sync_info, even if there is already
+      // one available.  Any given object can only be finalized once.
+      // If we get here and sync_info is not null, then it has already
+      // been finalized.  So if we just reinitialize the old one,
+      // we'll never be able to (re-)destroy the mutex and/or
+      // condition variable.
+      si = (_Jv_SyncInfo *) _Jv_AllocBytes (sizeof (_Jv_SyncInfo));
+      _Jv_MutexInit (&si->mutex);
+      _Jv_CondInit (&si->condition);
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+      // Register a finalizer.
+      si->init = true;
+      _Jv_RegisterFinalizer (si, finalize_sync_info);
+#endif
+      sync_info = (jobject) si;
+    }
+  _Jv_MutexUnlock (&sync_mutex);
+}
+
+void
+java::lang::Object::notify (void)
+{
+  if (__builtin_expect (INIT_NEEDED (this), false))
+    sync_init ();
+  _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
+  if (__builtin_expect (_Jv_CondNotify (&si->condition, &si->mutex), false))
+    throw new IllegalMonitorStateException(JvNewStringLatin1 
+					   ("current thread not owner"));
+}
+
+void
+java::lang::Object::notifyAll (void)
+{
+  if (__builtin_expect (INIT_NEEDED (this), false))
+    sync_init ();
+  _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
+  if (__builtin_expect (_Jv_CondNotifyAll (&si->condition, &si->mutex), false))
+    throw new IllegalMonitorStateException(JvNewStringLatin1 
+					   ("current thread not owner"));
+}
+
+void
+java::lang::Object::wait (jlong timeout, jint nanos)
+{
+  if (__builtin_expect (INIT_NEEDED (this), false))
+    sync_init ();
+  if (__builtin_expect (timeout < 0 || nanos < 0 || nanos > 999999, false))
+    throw new IllegalArgumentException;
+  _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
+  switch (_Jv_CondWait (&si->condition, &si->mutex, timeout, nanos))
+    {
+      case _JV_NOT_OWNER:
+	throw new IllegalMonitorStateException (JvNewStringLatin1 
+						("current thread not owner"));
+      case _JV_INTERRUPTED:
+	if (Thread::interrupted ())
+	  throw new InterruptedException;
+    }
+}
+
+//
+// Some runtime code.
+//
+
+// This function is called at system startup to initialize the
+// `sync_mutex'.
+void
+_Jv_InitializeSyncMutex (void)
+{
+  _Jv_MutexInit (&sync_mutex);
+}
+
+void
+_Jv_MonitorEnter (jobject obj)
+{
+#ifndef HANDLE_SEGV
+  if (__builtin_expect (! obj, false))
+    throw new java::lang::NullPointerException;
+#endif
+  if (__builtin_expect (INIT_NEEDED (obj), false))
+    obj->sync_init ();
+  _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
+  _Jv_MutexLock (&si->mutex);
+  // FIXME: In the Windows case, this can return a nonzero error code.
+  // We should turn that into some exception ...
+}
+
+void
+_Jv_MonitorExit (jobject obj)
+{
+  JvAssert (obj);
+  JvAssert (! INIT_NEEDED (obj));
+  _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
+  if (__builtin_expect (_Jv_MutexUnlock (&si->mutex), false))
+    throw new java::lang::IllegalMonitorStateException;
+}
+
+bool
+_Jv_ObjectCheckMonitor (jobject obj)
+{
+  if (__builtin_expect (INIT_NEEDED (obj), false))
+    obj->sync_init ();
+  _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
+  return _Jv_MutexCheckMonitor (&si->mutex);
+}
+
+#else /* JV_HASH_SYNCHRONIZATION */
+
+// FIXME: We shouldn't be calling GC_register_finalizer directly.
+#ifndef HAVE_BOEHM_GC
+# error Hash synchronization currently requires boehm-gc
+// That's actually a bit of a lie: It should also work with the null GC,
+// probably even better than the alternative.
+// To really support alternate GCs here, we would need to widen the
+// interface to finalization, since we sometimes have to register a
+// second finalizer for an object that already has one.
+// We might also want to move the GC interface to a .h file, since
+// the number of procedure call levels involved in some of these
+// operations is already ridiculous, and would become worse if we
+// went through the proper intermediaries.
+#else
+# ifdef LIBGCJ_GC_DEBUG
+#   define GC_DEBUG
+# endif
+# include "gc.h"
+#endif
+
+// What follows currenly assumes a Linux-like platform.
+// Some of it specifically assumes X86 or IA64 Linux, though that
+// should be easily fixable.
+
+// A Java monitor implemention based on a table of locks.
+// Each entry in the table describes
+// locks held for objects that hash to that location.
+// This started out as a reimplementation of the technique used in SGIs JVM,
+// for which we obtained permission from SGI.
+// But in fact, this ended up quite different, though some ideas are
+// still shared with the original.
+// It was also influenced by some of the published IBM work,
+// though it also differs in many ways from that.
+// We could speed this up if we had a way to atomically update
+// an entire cache entry, i.e. 2 contiguous words of memory.
+// That would usually be the case with a 32 bit ABI on a 64 bit processor.
+// But we don't currently go out of our way to target those.
+// I don't know how to do much better with a N bit ABI on a processor
+// that can atomically update only N bits at a time.
+// Author: Hans-J. Boehm  (Hans_Boehm at hp.com, boehm at acm.org)
+
+#include <limits.h>
+#include <unistd.h>	// for usleep, sysconf.
+#include <gcj/javaprims.h>
+#include <sysdep/locks.h>
+#include <java/lang/Thread.h>
+
+// Try to determine whether we are on a multiprocessor, i.e. whether
+// spinning may be profitable.
+// This should really use a suitable autoconf macro.
+// False is the conservative answer, though the right one is much better.
+static bool
+is_mp()
+{
+#ifdef _SC_NPROCESSORS_ONLN
+  long nprocs = sysconf(_SC_NPROCESSORS_ONLN);
+  return (nprocs > 1);
+#else
+  return false;
+#endif
+}
+
+// A call to keep_live(p) forces p to be accessible to the GC
+// at this point.
+inline static void
+keep_live(obj_addr_t p)
+{
+    __asm__ __volatile__("" : : "rm"(p) : "memory");
+}
+
+// Each hash table entry holds a single preallocated "lightweight" lock.
+// In addition, it holds a chain of "heavyweight" locks.  Lightweight
+// locks do not support Object.wait(), and are converted to heavyweight
+// status in response to contention.  Unlike the SGI scheme, both
+// ligtweight and heavyweight locks in one hash entry can be simultaneously
+// in use.  (The SGI scheme requires that we be able to acquire a heavyweight
+// lock on behalf of another thread, and can thus convert a lock we don't
+// hold to heavyweight status.  Here we don't insist on that, and thus
+// let the original holder of the lighweight lock keep it.)
+
+struct heavy_lock {
+  void * reserved_for_gc;
+  struct heavy_lock *next;	// Hash chain link.
+				// Traced by GC.
+  void * old_client_data;	// The only other field traced by GC.
+  GC_finalization_proc old_finalization_proc;
+  obj_addr_t address;		// Object to which this lock corresponds.
+				// Should not be traced by GC.
+  				// Cleared as heavy_lock is destroyed.
+  				// Together with the rest of the heavy lock
+  				// chain, this is protected by the lock
+  				// bit in the hash table entry to which
+  				// the chain is attached.
+  _Jv_SyncInfo si;
+  // The remaining fields save prior finalization info for
+  // the object, which we needed to replace in order to arrange
+  // for cleanup of the lock structure.
+};
+
+#ifdef LOCK_DEBUG
+void
+print_hl_list(heavy_lock *hl)
+{
+    heavy_lock *p = hl;
+    for (; 0 != p; p = p->next)
+      fprintf (stderr, "(hl = %p, addr = %p)", p, (void *)(p -> address));
+}
+#endif /* LOCK_DEBUG */
+
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+// If we have to run a destructor for a sync_info member, then this
+// function could be registered as a finalizer for the sync_info.
+// In fact, we now only invoke it explicitly.
+static inline void
+heavy_lock_finalization_proc (heavy_lock *hl)
+{
+#if defined (_Jv_HaveCondDestroy)
+  _Jv_CondDestroy (&hl->si.condition);
+#endif
+#if defined (_Jv_HaveMutexDestroy)
+  _Jv_MutexDestroy (&hl->si.mutex);
+#endif
+  hl->si.init = false;
+}
+#endif /* defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy) */
+
+// We convert the lock back to lightweight status when
+// we exit, so that a single contention episode doesn't doom the lock
+// forever.  But we also need to make sure that lock structures for dead
+// objects are eventually reclaimed.  We do that in a an additional
+// finalizer on the underlying object.
+// Note that if the corresponding object is dead, it is safe to drop
+// the heavy_lock structure from its list.  It is not necessarily
+// safe to deallocate it, since the unlock code could still be running.
+
+struct hash_entry {
+  volatile obj_addr_t address;	// Address of object for which lightweight
+  				// k is held.
+				// We assume the 3 low order bits are zero.
+				// With the Boehm collector and bitmap
+				// allocation, objects of size 4 bytes are
+				// broken anyway.  Thus this is primarily
+				// a constraint on statically allocated
+				// objects used for synchronization.
+				// This allows us to use the low order
+  				// bits as follows:
+#   define LOCKED 	1 	// This hash entry is locked, and its
+  				// state may be invalid.
+  				// The lock protects both the hash_entry
+  				// itself (except for the light_count
+  				// and light_thr_id fields, which
+  				// are protected by the lightweight
+  				// lock itself), and any heavy_monitor
+  				// structures attached to it.
+#   define HEAVY	2	// Heavyweight locks associated with this
+  				// hash entry may be held.
+				// The lightweight entry is still valid,
+  				// if the leading bits of the address
+  				// field are nonzero.
+  				// If the LOCKED bit is clear, then this is
+ 				// set exactly when heavy_count is > 0 .
+  				// Stored redundantly so a single
+  				// compare-and-swap works in the easy case.
+  				// If HEAVY is not set, it is safe to use
+  				// an available lightweight lock entry
+  				// without checking if there is an existing
+  				// heavyweight lock for the same object.
+  				// (There may be one, but it won't be held
+  				// or waited for.)
+#   define REQUEST_CONVERSION 4 // The lightweight lock is held.  But
+  				// one or more other threads have tried
+  				// to acquire the lock, and hence request
+  				// conversion to heavyweight status.
+  				// The heavyweight lock is already allocated.
+  				// Threads requesting conversion are
+  				// waiting on the condition variable associated
+  				// with the heavyweight lock.
+  				// Not used for conversion due to
+  				// Object.wait() calls.
+#   define FLAGS (LOCKED | HEAVY | REQUEST_CONVERSION)
+  volatile _Jv_ThreadId_t light_thr_id;
+				// Thr_id of holder of lightweight lock.
+  				// Only updated by lightweight lock holder.
+				// Must be recognizably invalid if the
+				// lightweight lock is not held.
+#   define INVALID_THREAD_ID 0  // Works for Linux?
+				// If zero doesn't work, we have to
+				// initialize lock table.
+  volatile unsigned short light_count;
+				// Number of times the lightweight lock
+  				// is held minus one.  Zero if lightweight
+  				// lock is not held.  Only updated by
+  				// lightweight lock holder or, in one
+  				// case, while holding the LOCKED bit in
+  				// a state in which there can be no
+  				// lightweight lock holder.
+  unsigned short heavy_count; 	// Total number of times heavyweight locks
+  				// associated with this hash entry are held
+  				// or waiting to be acquired.
+  				// Threads in wait() are included eventhough
+  				// they have temporarily released the lock.
+  				// Protected by LOCKED bit.
+  				// Threads requesting conversion to heavyweight
+  				// status are also included.
+  struct heavy_lock * heavy_locks;
+  				// Chain of heavy locks.  Protected
+  				// by lockbit for he.  Locks may
+  				// remain allocated here even if HEAVY
+  				// is not set and heavy_count is 0.
+  				// If a lightweight and heavyweight lock
+  				// correspond to the same address, the
+  				// lightweight lock is the right one.
+};
+
+#ifndef JV_SYNC_TABLE_SZ
+# define JV_SYNC_TABLE_SZ 2048	// Must be power of 2.
+#endif
+
+hash_entry light_locks[JV_SYNC_TABLE_SZ];
+
+#define JV_SYNC_HASH(p) (((long)p ^ ((long)p >> 10)) & (JV_SYNC_TABLE_SZ-1))
+
+// Note that the light_locks table is scanned conservatively by the
+// collector.  It is essential the the heavy_locks field is scanned.
+// Currently the address field may or may not cause the associated object
+// to be retained, depending on whether flag bits are set.
+// This means that we can conceivable get an unexpected deadlock if
+// 1) Object at address A is locked.
+// 2) The client drops A without unlocking it.
+// 3) Flag bits in the address entry are set, so the collector reclaims
+//    the object at A.
+// 4) A is reallocated, and an attempt is made to lock the result.
+// This could be fixed by scanning light_locks in a more customized
+// manner that ignores the flag bits.  But it can only happen with hand
+// generated semi-illegal .class files, and then it doesn't present a
+// security hole.
+
+#ifdef LOCK_DEBUG
+  void print_he(hash_entry *he)
+  {
+     fprintf(stderr, "lock hash entry = %p, index = %d, address = 0x%lx\n"
+		     "\tlight_thr_id = 0x%lx, light_count = %d, "
+		     "heavy_count = %d\n\theavy_locks:", he,
+		     he - light_locks, (unsigned long)(he -> address),
+		     (unsigned long)(he -> light_thr_id),
+		     he -> light_count, he -> heavy_count);
+     print_hl_list(he -> heavy_locks);
+     fprintf(stderr, "\n");
+  }
+#endif /* LOCK_DEBUG */
+
+#ifdef LOCK_LOG
+  // Log locking operations.  For debugging only.
+  // Logging is intended to be as unintrusive as possible.
+  // Log calls are made after an operation completes, and hence
+  // may not completely reflect actual synchronization ordering.
+  // The choice of events to log is currently a bit haphazard.
+  // The intent is that if we have to track down any other bugs
+  // inthis code, we extend the logging as appropriate.
+  typedef enum
+  {
+    ACQ_LIGHT, ACQ_LIGHT2, ACQ_HEAVY, ACQ_HEAVY2, PROMOTE, REL_LIGHT,
+    REL_HEAVY, REQ_CONV, PROMOTE2, WAIT_START, WAIT_END, NOTIFY, NOTIFY_ALL
+  } event_type;
+
+  struct lock_history
+  {
+    event_type tp;
+    obj_addr_t addr;  // Often includes flags.
+    _Jv_ThreadId_t thr;
+  };
+     
+  const int LOG_SIZE = 128;	// Power of 2.
+
+  lock_history lock_log[LOG_SIZE];
+
+  volatile obj_addr_t log_next = 0;
+  			   // Next location in lock_log.
+  			   // Really an int, but we need compare_and_swap.
+
+  static void add_log_entry(event_type t, obj_addr_t a, _Jv_ThreadId_t th)
+  {
+    obj_addr_t my_entry;
+    obj_addr_t next_entry;
+    do
+      {
+	my_entry = log_next;
+	next_entry = ((my_entry + 1) & (LOG_SIZE - 1));
+      }
+    while (!compare_and_swap(&log_next, my_entry, next_entry));
+    lock_log[my_entry].tp = t;
+    lock_log[my_entry].addr = a;
+    lock_log[my_entry].thr = th;
+  }
+
+# define LOG(t, a, th) add_log_entry(t, a, th)
+#else /* !LOCK_LOG */
+# define LOG(t, a, th)
+#endif
+
+static bool mp = false; // Known multiprocesssor.
+
+// Wait for roughly 2^n units, touching as little memory as possible.
+static void
+spin(unsigned n)
+{
+  const unsigned MP_SPINS = 10;
+  const unsigned YIELDS = 4;
+  const unsigned SPINS_PER_UNIT = 30;
+  const unsigned MIN_SLEEP_USECS = 2001; // Shorter times spin under Linux.
+  const unsigned MAX_SLEEP_USECS = 200000;
+  static unsigned spin_limit = 0;
+  static unsigned yield_limit = YIELDS;
+  static bool spin_initialized = false;
+
+  if (!spin_initialized)
+    {
+      mp = is_mp();
+      if (mp)
+	{
+	  spin_limit = MP_SPINS;
+	  yield_limit = MP_SPINS + YIELDS;
+	}
+      spin_initialized = true;
+    }
+  if (n < spin_limit)
+    {
+      unsigned i = SPINS_PER_UNIT << n;
+      for (; i > 0; --i)
+        __asm__ __volatile__("");
+    }
+  else if (n < yield_limit)
+    {
+      _Jv_ThreadYield();
+    }
+  else
+    {
+      unsigned duration = MIN_SLEEP_USECS << (n - yield_limit);
+      if (n >= 15 + yield_limit || duration > MAX_SLEEP_USECS)
+        duration = MAX_SLEEP_USECS;
+      _Jv_platform_usleep(duration);
+    }
+}
+
+// Wait for a hash entry to become unlocked.
+static void
+wait_unlocked (hash_entry *he)
+{
+  unsigned i = 0;
+  while (he -> address & LOCKED)
+    spin (i++);
+}
+
+// Return the heavy lock for addr if it was already allocated.
+// The client passes in the appropriate hash_entry.
+// We hold the lock for he.
+static inline heavy_lock *
+find_heavy (obj_addr_t addr, hash_entry *he)
+{
+  heavy_lock *hl = he -> heavy_locks;
+  while (hl != 0 && hl -> address != addr) hl = hl -> next;
+  return hl;
+}
+
+// Unlink the heavy lock for the given address from its hash table chain.
+// Dies miserably and conspicuously if it's not there, since that should
+// be impossible.
+static inline void
+unlink_heavy (obj_addr_t addr, hash_entry *he)
+{
+  heavy_lock **currentp = &(he -> heavy_locks);
+  while ((*currentp) -> address != addr)
+    currentp = &((*currentp) -> next);
+  *currentp = (*currentp) -> next;
+}
+
+// Finalization procedure for objects that have associated heavy-weight
+// locks.  This may replace the real finalization procedure.
+static void
+heavy_lock_obj_finalization_proc (void *obj, void *cd)
+{
+  heavy_lock *hl = (heavy_lock *)cd;
+
+// This only addresses misalignment of statics, not heap objects.  It
+// works only because registering statics for finalization is a noop,
+// no matter what the least significant bits are.
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+  obj_addr_t addr = (obj_addr_t)obj & ~((obj_addr_t)0x7);
+#else
+  obj_addr_t addr = (obj_addr_t)obj;
+#endif
+  hash_entry *he = light_locks + JV_SYNC_HASH(addr);
+  obj_addr_t he_address = (he -> address & ~LOCKED);
+
+  // Acquire lock bit immediately.  It's possible that the hl was already
+  // destroyed while we were waiting for the finalizer to run.  If it
+  // was, the address field was set to zero.  The address filed access is
+  // protected by the lock bit to ensure that we do this exactly once.
+  // The lock bit also protects updates to the objects finalizer.
+  while (!compare_and_swap(&(he -> address), he_address, he_address|LOCKED ))
+    {
+      // Hash table entry is currently locked.  We can't safely 
+      // touch the list of heavy locks.  
+      wait_unlocked(he);
+      he_address = (he -> address & ~LOCKED);
+    }
+  if (0 == hl -> address)
+    {
+      // remove_all_heavy destroyed hl, and took care of the real finalizer.
+      release_set(&(he -> address), he_address);
+      return;
+    }
+  JvAssert(hl -> address == addr);
+  GC_finalization_proc old_finalization_proc = hl -> old_finalization_proc;
+  if (old_finalization_proc != 0)
+    {
+      // We still need to run a real finalizer.  In an idealized
+      // world, in which people write thread-safe finalizers, that is
+      // likely to require synchronization.  Thus we reregister
+      // ourselves as the only finalizer, and simply run the real one.
+      // Thus we don't clean up the lock yet, but we're likely to do so
+      // on the next GC cycle.
+      // It's OK if remove_all_heavy actually destroys the heavy lock,
+      // since we've updated old_finalization_proc, and thus the user's
+      // finalizer won't be rerun.
+      void * old_client_data = hl -> old_client_data;
+      hl -> old_finalization_proc = 0;
+      hl -> old_client_data = 0;
+#     ifdef HAVE_BOEHM_GC
+        GC_REGISTER_FINALIZER_NO_ORDER(obj, heavy_lock_obj_finalization_proc, cd, 0, 0);
+#     endif
+      release_set(&(he -> address), he_address);
+      old_finalization_proc(obj, old_client_data);
+    }
+  else
+    {
+      // The object is really dead, although it's conceivable that
+      // some thread may still be in the process of releasing the
+      // heavy lock.  Unlink it and, if necessary, register a finalizer
+      // to destroy sync_info.
+      unlink_heavy(addr, he);
+      hl -> address = 0; 	// Don't destroy it again.
+      release_set(&(he -> address), he_address);
+#     if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+        // Make sure lock is not held and then destroy condvar and mutex.
+        _Jv_MutexLock(&(hl->si.mutex));
+        _Jv_MutexUnlock(&(hl->si.mutex));
+        heavy_lock_finalization_proc (hl);
+#     endif
+    }
+}
+
+// We hold the lock on he, and heavy_count is 0.
+// Release the lock by replacing the address with new_address_val.
+// Remove all heavy locks on the list.  Note that the only possible way
+// in which a lock may still be in use is if it's in the process of
+// being unlocked.
+// FIXME:  Why does this unlock the hash entry?  I think that
+// could now be done more cleanly in MonitorExit.
+static void
+remove_all_heavy (hash_entry *he, obj_addr_t new_address_val)
+{
+  JvAssert(he -> heavy_count == 0);
+  JvAssert(he -> address & LOCKED);
+  heavy_lock *hl = he -> heavy_locks;
+  he -> heavy_locks = 0;
+  // We would really like to release the lock bit here.  Unfortunately, that
+  // Creates a race between or finalizer removal, and the potential
+  // reinstallation of a new finalizer as a new heavy lock is created.
+  // This may need to be revisited.
+  for(; 0 != hl; hl = hl->next)
+    {
+      obj_addr_t obj = hl -> address;
+      JvAssert(0 != obj);  // If this was previously finalized, it should no
+			   // longer appear on our list.
+      hl -> address = 0; // Finalization proc might still see it after we
+      			 // finish.
+      GC_finalization_proc old_finalization_proc = hl -> old_finalization_proc;
+      void * old_client_data = hl -> old_client_data;
+#     ifdef HAVE_BOEHM_GC
+	// Remove our finalization procedure.
+        // Reregister the clients if applicable.
+          GC_REGISTER_FINALIZER_NO_ORDER((GC_PTR)obj, old_finalization_proc,
+			  		 old_client_data, 0, 0);
+      	  // Note that our old finalization procedure may have been
+          // previously determined to be runnable, and may still run.
+      	  // FIXME - direct dependency on boehm GC.
+#     endif
+#     if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+        // Wait for a possible lock holder to finish unlocking it.
+        // This is only an issue if we have to explicitly destroy the mutex
+        // or possibly if we have to destroy a condition variable that is
+        // still being notified.
+          _Jv_MutexLock(&(hl->si.mutex));
+          _Jv_MutexUnlock(&(hl->si.mutex));
+          heavy_lock_finalization_proc (hl);
+#     endif
+    }
+  release_set(&(he -> address), new_address_val);
+}
+
+// We hold the lock on he and heavy_count is 0.
+// We release it by replacing the address field with new_address_val.
+// Remove all heavy locks on the list if the list is sufficiently long.
+// This is called periodically to avoid very long lists of heavy locks.
+// This seems to otherwise become an issue with SPECjbb, for example.
+static inline void
+maybe_remove_all_heavy (hash_entry *he, obj_addr_t new_address_val)
+{
+  static const int max_len = 5;
+  heavy_lock *hl = he -> heavy_locks;
+
+  for (int i = 0; i < max_len; ++i)
+    {
+      if (0 == hl) 
+	{
+  	  release_set(&(he -> address), new_address_val);
+	  return;
+	}
+      hl = hl -> next;
+    }
+  remove_all_heavy(he, new_address_val);
+}
+
+// Allocate a new heavy lock for addr, returning its address.
+// Assumes we already have the hash_entry locked, and there
+// is currently no lightweight or allocated lock for addr.
+// We register a finalizer for addr, which is responsible for
+// removing the heavy lock when addr goes away, in addition
+// to the responsibilities of any prior finalizer.
+// This unfortunately holds the lock bit for the hash entry while it
+// allocates two objects (on for the finalizer).
+// It would be nice to avoid that somehow ...
+static heavy_lock *
+alloc_heavy(obj_addr_t addr, hash_entry *he)
+{
+  heavy_lock * hl = (heavy_lock *) _Jv_AllocTraceTwo(sizeof (heavy_lock));
+  
+  hl -> address = addr;
+  _Jv_MutexInit (&(hl -> si.mutex));
+  _Jv_CondInit (&(hl -> si.condition));
+# if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+    hl->si.init = true;  // needed ?
+# endif
+  hl -> next = he -> heavy_locks;
+  he -> heavy_locks = hl;
+  // FIXME: The only call that cheats and goes directly to the GC interface.
+# ifdef HAVE_BOEHM_GC
+    GC_REGISTER_FINALIZER_NO_ORDER(
+		    	  (void *)addr, heavy_lock_obj_finalization_proc,
+			  hl, &hl->old_finalization_proc,
+			  &hl->old_client_data);
+# endif /* HAVE_BOEHM_GC */
+  return hl;
+}
+
+// Return the heavy lock for addr, allocating if necessary.
+// Assumes we have the cache entry locked, and there is no lightweight
+// lock for addr.
+static heavy_lock *
+get_heavy(obj_addr_t addr, hash_entry *he)
+{
+  heavy_lock *hl = find_heavy(addr, he);
+  if (0 == hl)
+    hl = alloc_heavy(addr, he);
+  return hl;
+}
+
+void
+_Jv_MonitorEnter (jobject obj)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+  obj_addr_t addr = (obj_addr_t)obj & ~((obj_addr_t)FLAGS);
+#else
+  obj_addr_t addr = (obj_addr_t)obj;
+#endif
+  obj_addr_t address;
+  unsigned hash = JV_SYNC_HASH(addr);
+  hash_entry * he = light_locks + hash;
+  _Jv_ThreadId_t self = _Jv_ThreadSelf();
+  unsigned count;
+  const unsigned N_SPINS = 18;
+
+  // We need to somehow check that addr is not NULL on the fast path.
+  // A very predictable
+  // branch on a register value is probably cheaper than dereferencing addr.
+  // We could also permanently lock the NULL entry in the hash table.
+  // But it's not clear that's cheaper either.
+  if (__builtin_expect(!addr, false))
+    throw new java::lang::NullPointerException;
+   
+  JvAssert(!(addr & FLAGS));
+retry:
+  if (__builtin_expect(compare_and_swap(&(he -> address),
+					0, addr),true))
+    {
+      JvAssert(he -> light_thr_id == INVALID_THREAD_ID);
+      JvAssert(he -> light_count == 0);
+      he -> light_thr_id = self;
+      // Count fields are set correctly.  Heavy_count was also zero,
+      // but can change asynchronously.
+      // This path is hopefully both fast and the most common.
+      LOG(ACQ_LIGHT, addr, self);
+      return;
+    }
+  address = he -> address;
+  if ((address & ~(HEAVY | REQUEST_CONVERSION)) == addr)
+    {
+      if (he -> light_thr_id == self)
+	{
+	  // We hold the lightweight lock, and it's for the right
+	  // address.
+	  count = he -> light_count;
+	  if (count == USHRT_MAX)
+	    {
+	      // I think most JVMs don't check for this.
+	      // But I'm not convinced I couldn't turn this into a security
+	      // hole, even with a 32 bit counter.
+	      throw new java::lang::IllegalMonitorStateException(
+		JvNewStringLatin1("maximum monitor nesting level exceeded")); 
+	    }
+	  he -> light_count = count + 1;
+	  return;
+	}
+      else
+	{
+	  JvAssert(!(address & LOCKED));
+	  // Lightweight lock is held, but by somone else.
+          // Spin a few times.  This avoids turning this into a heavyweight
+    	  // lock if the current holder is about to release it.
+	  // FIXME: Does this make sense on a uniprocessor, where
+	  // it actually yields?  It's probably cheaper to convert.
+          for (unsigned int i = 0; i < N_SPINS; ++i)
+	    {
+	      if ((he -> address & ~LOCKED) != address) goto retry;
+	      spin(i);
+            }
+	  if (!compare_and_swap(&(he -> address), address, address | LOCKED ))
+	    {
+	      wait_unlocked(he);      
+	      goto retry;
+	    }
+	  heavy_lock *hl = get_heavy(addr, he);
+	  ++ (he -> heavy_count);
+	  // The hl lock acquisition can't block for long, since it can
+	  // only be held by other threads waiting for conversion, and
+	  // they, like us, drop it quickly without blocking.
+	  _Jv_MutexLock(&(hl->si.mutex));
+	  JvAssert(he -> address == address | LOCKED );
+	  release_set(&(he -> address), (address | REQUEST_CONVERSION | HEAVY));
+				// release lock on he
+	  LOG(REQ_CONV, (address | REQUEST_CONVERSION | HEAVY), self);
+	  // If _Jv_CondWait is interrupted, we ignore the interrupt, but
+	  // restore the thread's interrupt status flag when done.
+	  jboolean interrupt_flag = false;
+	  while ((he -> address & ~FLAGS) == (address & ~FLAGS))
+	    {
+	      // Once converted, the lock has to retain heavyweight
+	      // status, since heavy_count > 0.
+	      int r = _Jv_CondWait (&(hl->si.condition), &(hl->si.mutex), 0, 0);
+	      if (r == _JV_INTERRUPTED)
+	        {
+		  interrupt_flag = true;
+		  Thread::currentThread()->interrupt_flag = false;
+		}
+	    }
+	  if (interrupt_flag)
+	    Thread::currentThread()->interrupt_flag = interrupt_flag;
+	  keep_live(addr);
+		// Guarantee that hl doesn't get unlinked by finalizer.
+		// This is only an issue if the client fails to release
+		// the lock, which is unlikely.
+	  JvAssert(he -> address & HEAVY);
+	  // Lock has been converted, we hold the heavyweight lock,
+	  // heavy_count has been incremented.
+	  return;
+        }
+    }
+  obj_addr_t was_heavy = (address & HEAVY);
+  if ((address & LOCKED) ||
+      !compare_and_swap(&(he -> address), address, (address | LOCKED )))
+    {
+      wait_unlocked(he);
+      goto retry;
+    }
+  if ((address & ~(HEAVY | REQUEST_CONVERSION)) == 0)
+    {
+      // Either was_heavy is true, or something changed out from under us,
+      // since the initial test for 0 failed.
+      JvAssert(!(address & REQUEST_CONVERSION));
+	// Can't convert a nonexistent lightweight lock.
+      heavy_lock *hl;
+      hl = (was_heavy? find_heavy(addr, he) : 0);
+        // The CAS succeeded, so was_heavy is still accurate.
+      if (0 == hl)
+        {
+	  // It is OK to use the lighweight lock, since either the
+	  // heavyweight lock does not exist, or none of the
+	  // heavyweight locks are currently in use.  Future threads
+	  // trying to acquire the lock will see the lightweight
+	  // one first and use that.
+	  he -> light_thr_id = self;  // OK, since nobody else can hold
+				      // light lock or do this at the same time.
+	  JvAssert(he -> light_count == 0);
+	  JvAssert(was_heavy == (he -> address & HEAVY));
+	  release_set(&(he -> address), (addr | was_heavy));
+	  LOG(ACQ_LIGHT2, addr | was_heavy, self);
+        }
+      else
+	{
+	  // Must use heavy lock.
+	  ++ (he -> heavy_count);
+	  JvAssert(0 == (address & ~HEAVY));
+          release_set(&(he -> address), HEAVY);
+	  LOG(ACQ_HEAVY, addr | was_heavy, self);
+          _Jv_MutexLock(&(hl->si.mutex));
+	  keep_live(addr);
+        }
+      return;
+    }
+  // Lightweight lock is held, but does not correspond to this object.
+  // We hold the lock on the hash entry, and he -> address can't
+  // change from under us.  Neither can the chain of heavy locks.
+    {
+      JvAssert(0 == he -> heavy_count || (address & HEAVY));
+      heavy_lock *hl = get_heavy(addr, he);
+      ++ (he -> heavy_count);
+      release_set(&(he -> address), address | HEAVY);
+      LOG(ACQ_HEAVY2, address | HEAVY, self);
+      _Jv_MutexLock(&(hl->si.mutex));
+      keep_live(addr);
+    }
+}
+
+
+void
+_Jv_MonitorExit (jobject obj)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+  obj_addr_t addr = (obj_addr_t)obj & ~((obj_addr_t)FLAGS);
+#else
+  obj_addr_t addr = (obj_addr_t)obj;
+#endif
+  _Jv_ThreadId_t self = _Jv_ThreadSelf();
+  unsigned hash = JV_SYNC_HASH(addr);
+  hash_entry * he = light_locks + hash;
+  _Jv_ThreadId_t light_thr_id;
+  unsigned count;
+  obj_addr_t address;
+
+retry:
+  light_thr_id = he -> light_thr_id;
+  // Unfortunately, it turns out we always need to read the address
+  // first.  Even if we are going to update it with compare_and_swap,
+  // we need to reset light_thr_id, and that's not safe unless we know
+  // that we hold the lock.
+  address = he -> address;
+  // First the (relatively) fast cases:
+  if (__builtin_expect(light_thr_id == self, true))
+    // Above must fail if addr == 0 .
+    {
+      count = he -> light_count;
+      if (__builtin_expect((address & ~HEAVY) == addr, true))
+	{
+          if (count != 0)
+            {
+	      // We held the lightweight lock all along.  Thus the values
+	      // we saw for light_thr_id and light_count must have been valid. 
+	      he -> light_count = count - 1;
+	      return;
+            }
+	  else
+	    {
+	      // We hold the lightweight lock once.
+	      he -> light_thr_id = INVALID_THREAD_ID;
+              if (compare_and_swap_release(&(he -> address), address,
+					   address & HEAVY))
+		{
+		  LOG(REL_LIGHT, address & HEAVY, self);
+	          return;
+		}
+	      else
+		{
+	          he -> light_thr_id = light_thr_id; // Undo prior damage.
+	          goto retry;
+	        }
+            }
+        }
+      // else lock is not for this address, conversion is requested,
+      // or the lock bit in the address field is set.
+    }
+  else
+    {
+      if (__builtin_expect(!addr, false))
+	throw new java::lang::NullPointerException;
+      if ((address & ~(HEAVY | REQUEST_CONVERSION)) == addr)
+	{
+#	  ifdef LOCK_DEBUG
+	    fprintf(stderr, "Lightweight lock held by other thread\n\t"
+			    "light_thr_id = 0x%lx, self = 0x%lx, "
+			    "address = 0x%lx, heavy_count = %d, pid = %d\n",
+			    light_thr_id, self, (unsigned long)address,
+			    he -> heavy_count, getpid());
+	    print_he(he);
+	    for(;;) {}
+#	  endif
+	  // Someone holds the lightweight lock for this object, and
+	  // it can't be us.
+	  throw new java::lang::IllegalMonitorStateException(
+			JvNewStringLatin1("current thread not owner"));
+        }
+      else
+	count = he -> light_count;
+    }
+  if (address & LOCKED)
+    {
+      wait_unlocked(he);
+      goto retry;
+    }
+  // Now the unlikely cases.
+  // We do know that:
+  // - Address is set, and doesn't contain the LOCKED bit.
+  // - If address refers to the same object as addr, then he -> light_thr_id
+  //   refers to this thread, and count is valid.
+  // - The case in which we held the lightweight lock has been
+  //   completely handled, except for the REQUEST_CONVERSION case.
+  //   
+  if ((address & ~FLAGS) == addr)
+    {
+      // The lightweight lock is assigned to this object.
+      // Thus we must be in the REQUEST_CONVERSION case.
+      if (0 != count)
+        {
+	  // Defer conversion until we exit completely.
+	  he -> light_count = count - 1;
+	  return;
+        }
+      JvAssert(he -> light_thr_id == self);
+      JvAssert(address & REQUEST_CONVERSION);
+      // Conversion requested
+      // Convert now.
+      if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+	goto retry;
+      heavy_lock *hl = find_heavy(addr, he);
+      JvAssert (0 != hl);
+		// Requestor created it.
+      he -> light_count = 0;
+      JvAssert(he -> heavy_count > 0);
+	  	// was incremented by requestor.
+      _Jv_MutexLock(&(hl->si.mutex));
+	// Release the he lock after acquiring the mutex.
+	// Otherwise we can accidentally
+	// notify a thread that has already seen a heavyweight
+	// lock.
+      he -> light_thr_id = INVALID_THREAD_ID;
+      release_set(&(he -> address), HEAVY);
+      LOG(PROMOTE, address, self);
+	  	// lightweight lock now unused.
+      _Jv_CondNotifyAll(&(hl->si.condition), &(hl->si.mutex));
+      _Jv_MutexUnlock(&(hl->si.mutex));
+      // heavy_count was already incremented by original requestor.
+      keep_live(addr);
+      return;
+    }
+  // lightweight lock not for this object.
+  JvAssert(!(address & LOCKED));
+  JvAssert((address & ~FLAGS) != addr);
+  if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+	goto retry;
+  heavy_lock *hl = find_heavy(addr, he);
+  if (NULL == hl)
+    {
+#     ifdef LOCK_DEBUG
+	fprintf(stderr, "Failed to find heavyweight lock for addr 0x%lx"
+			" pid = %d\n", addr, getpid());
+	print_he(he);
+	for(;;) {}
+#     endif
+      release_set(&(he -> address), address);
+      throw new java::lang::IllegalMonitorStateException(
+			JvNewStringLatin1("current thread not owner"));
+    }
+  JvAssert(address & HEAVY);
+  count = he -> heavy_count;
+  JvAssert(count > 0);
+  --count;
+  he -> heavy_count = count;
+  if (0 == count)
+    {
+      const unsigned test_freq = 16;  // Power of 2
+      static volatile unsigned counter = 0;
+      unsigned my_counter = counter;
+
+      counter = my_counter + 1;
+      if (my_counter%test_freq == 0)
+	{
+	  // Randomize the interval length a bit.
+	    counter = my_counter + (my_counter >> 4) % (test_freq/2);
+	  // Unlock mutex first, to avoid self-deadlock, or worse.
+          _Jv_MutexUnlock(&(hl->si.mutex));
+	  maybe_remove_all_heavy(he, address &~HEAVY);
+    				// release lock bit, preserving
+				// REQUEST_CONVERSION
+    				// and object address.
+	}
+      else
+        {
+          release_set(&(he -> address), address &~HEAVY);
+          _Jv_MutexUnlock(&(hl->si.mutex));
+  			// Unlock after releasing the lock bit, so that
+  			// we don't switch to another thread prematurely.
+	}
+    } 
+  else
+    {
+      release_set(&(he -> address), address);
+      _Jv_MutexUnlock(&(hl->si.mutex));
+    }
+  LOG(REL_HEAVY, addr, self);
+  keep_live(addr);
+}     
+
+// Return false if obj's monitor is held by the current thread
+bool
+_Jv_ObjectCheckMonitor (jobject obj)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+  obj_addr_t addr = (obj_addr_t)obj & ~((obj_addr_t)FLAGS);
+#else
+  obj_addr_t addr = (obj_addr_t)obj;
+#endif
+  obj_addr_t address;
+  unsigned hash = JV_SYNC_HASH(addr);
+  hash_entry * he = light_locks + hash;
+
+  JvAssert(!(addr & FLAGS));
+  address = he -> address;
+  // Try it the easy way first:
+    if (address == 0) return true;
+    _Jv_ThreadId_t self = _Jv_ThreadSelf();
+    if ((address & ~(HEAVY | REQUEST_CONVERSION)) == addr)
+	// Fails if entry is LOCKED.
+	// I can't asynchronously become or stop being the holder.
+	return he -> light_thr_id != self;
+retry:
+  // Acquire the hash table entry lock
+  address &= ~LOCKED;
+  if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+    {
+      wait_unlocked(he);
+      goto retry;
+    }
+
+  bool not_mine;
+
+  if ((address & ~FLAGS) == addr)
+    not_mine = (he -> light_thr_id != self);
+  else
+    {
+      heavy_lock* hl = find_heavy(addr, he);
+      not_mine = hl ? _Jv_MutexCheckMonitor(&hl->si.mutex) : true;
+    }
+
+  release_set(&(he -> address), address);	// unlock hash entry
+  return not_mine;
+}
+
+// The rest of these are moderately thin veneers on _Jv_Cond ops.
+// The current version of Notify might be able to make the pthread
+// call AFTER releasing the lock, thus saving some context switches??
+
+void
+java::lang::Object::wait (jlong timeout, jint nanos)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+  obj_addr_t addr = (obj_addr_t)this & ~((obj_addr_t)FLAGS);
+#else
+  obj_addr_t addr = (obj_addr_t)this;
+#endif
+  _Jv_ThreadId_t self = _Jv_ThreadSelf();
+  unsigned hash = JV_SYNC_HASH(addr);
+  hash_entry * he = light_locks + hash;
+  unsigned count;
+  obj_addr_t address;
+  heavy_lock *hl;
+    
+  if (__builtin_expect (timeout < 0 || nanos < 0 || nanos > 999999, false))
+    throw new IllegalArgumentException;
+retry:
+  address = he -> address;
+  address &= ~LOCKED;
+  if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+    {
+      wait_unlocked(he);
+      goto retry;
+    }
+  // address did not have the lock bit set.  We now hold the lock on he.
+  if ((address & ~FLAGS) == addr)
+    {
+      // Convert to heavyweight.
+	if (he -> light_thr_id != self)
+	  {
+#	    ifdef LOCK_DEBUG
+	      fprintf(stderr, "Found wrong lightweight lock owner in wait "
+			      "address = 0x%lx pid = %d\n", address, getpid());
+	      print_he(he);
+	      for(;;) {}
+#	    endif
+	    release_set(&(he -> address), address);
+	    throw new IllegalMonitorStateException (JvNewStringLatin1 
+                          ("current thread not owner"));
+	  }
+	count = he -> light_count;
+	hl = get_heavy(addr, he);
+	he -> light_count = 0;
+	he -> heavy_count += count + 1;
+	for (unsigned i = 0; i <= count; ++i)
+	  _Jv_MutexLock(&(hl->si.mutex));
+	// Again release the he lock after acquiring the mutex.
+        he -> light_thr_id = INVALID_THREAD_ID;
+	release_set(&(he -> address), HEAVY);  // lightweight lock now unused.
+	LOG(PROMOTE2, addr, self);
+	if (address & REQUEST_CONVERSION)
+	  _Jv_CondNotifyAll (&(hl->si.condition), &(hl->si.mutex));
+	  // Since we do this before we do a CondWait, we guarantee that
+	  // threads waiting on requested conversion are awoken before
+	  // a real wait on the same condition variable.
+	  // No other notification can occur in the interim, since
+	  // we hold the heavy lock, and notifications are made
+	  // without acquiring it.
+    }
+  else /* We should hold the heavyweight lock. */
+    {
+      hl = find_heavy(addr, he);
+      release_set(&(he -> address), address);
+      if (0 == hl)
+	{
+#	  ifdef LOCK_DEBUG
+	    fprintf(stderr, "Couldn't find heavy lock in wait "
+		 	    "addr = 0x%lx pid = %d\n", addr, getpid());
+	    print_he(he);
+	    for(;;) {}
+#	  endif
+	  throw new IllegalMonitorStateException (JvNewStringLatin1 
+                          ("current thread not owner"));
+	}
+      JvAssert(address & HEAVY);
+    }
+  LOG(WAIT_START, addr, self);
+  switch (_Jv_CondWait (&(hl->si.condition), &(hl->si.mutex), timeout, nanos))
+    {
+      case _JV_NOT_OWNER:
+	throw new IllegalMonitorStateException (JvNewStringLatin1 
+                          ("current thread not owner"));        
+      case _JV_INTERRUPTED:
+	if (Thread::interrupted ())
+	  throw new InterruptedException;        
+    }
+  LOG(WAIT_END, addr, self);
+}
+
+void
+java::lang::Object::notify (void)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+  obj_addr_t addr = (obj_addr_t)this & ~((obj_addr_t)FLAGS);
+#else
+  obj_addr_t addr = (obj_addr_t)this;
+#endif
+  _Jv_ThreadId_t self = _Jv_ThreadSelf();
+  unsigned hash = JV_SYNC_HASH(addr);
+  hash_entry * he = light_locks + hash;
+  heavy_lock *hl;
+  obj_addr_t address;
+  int result;
+
+retry:
+  address = ((he -> address) & ~LOCKED);
+  if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+    {
+      wait_unlocked(he);
+      goto retry;
+    }
+  if ((address & ~FLAGS) == addr && he -> light_thr_id == self)
+    {
+      // We hold lightweight lock.  Since it has not
+      // been inflated, there are no waiters.
+      release_set(&(he -> address), address);	// unlock
+      return;
+    }
+  hl = find_heavy(addr, he);
+  // Hl can't disappear since we point to the underlying object.
+  // It's important that we release the lock bit before the notify, since
+  // otherwise we will try to wake up the target while we still hold the
+  // bit.  This results in lock bit contention, which we don't handle
+  // terribly well.
+  release_set(&(he -> address), address); // unlock
+  if (0 == hl)
+    {
+      throw new IllegalMonitorStateException(JvNewStringLatin1 
+                                              ("current thread not owner"));
+      return;
+    }
+  // We know that we hold the heavyweight lock at this point,
+  // and the lightweight lock is not in use.
+  result = _Jv_CondNotify(&(hl->si.condition), &(hl->si.mutex));
+  LOG(NOTIFY, addr, self);
+  keep_live(addr);
+  if (__builtin_expect (result, 0))
+    throw new IllegalMonitorStateException(JvNewStringLatin1 
+                                              ("current thread not owner"));
+}
+
+void
+java::lang::Object::notifyAll (void)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+  obj_addr_t addr = (obj_addr_t)this & ~((obj_addr_t)FLAGS);
+#else
+  obj_addr_t addr = (obj_addr_t)this;
+#endif
+  _Jv_ThreadId_t self = _Jv_ThreadSelf();
+  unsigned hash = JV_SYNC_HASH(addr);
+  hash_entry * he = light_locks + hash;
+  heavy_lock *hl;
+  obj_addr_t address;
+  int result;
+
+retry:
+  address = (he -> address) & ~LOCKED;
+  if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+    {
+      wait_unlocked(he);
+      goto retry;
+    }
+  hl = find_heavy(addr, he);
+  if ((address & ~FLAGS) == addr && he -> light_thr_id == self)
+    {
+      // We hold lightweight lock.  Since it has not
+      // been inflated, there are no waiters.
+      release_set(&(he -> address), address);	// unlock
+      return;
+    }
+  release_set(&(he -> address), address); // unlock
+  if (0 == hl)
+    {
+      throw new IllegalMonitorStateException(JvNewStringLatin1 
+                                              ("current thread not owner"));
+    }
+  result = _Jv_CondNotifyAll(&(hl->si.condition), &(hl->si.mutex));
+  LOG(NOTIFY_ALL, addr, self);
+  if (__builtin_expect (result, 0))
+    throw new IllegalMonitorStateException(JvNewStringLatin1 
+                                              ("current thread not owner"));
+}
+
+// This is declared in Java code and in Object.h.
+// It should never be called with JV_HASH_SYNCHRONIZATION
+void
+java::lang::Object::sync_init (void)
+{
+  throw new IllegalMonitorStateException(JvNewStringLatin1 
+                                              ("internal error: sync_init"));
+}
+
+// This is called on startup and declared in Object.h.
+// For now we just make it a no-op.
+void
+_Jv_InitializeSyncMutex (void)
+{
+}
+
+#endif /* JV_HASH_SYNCHRONIZATION */
+

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natPosixProcess.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natPosixProcess.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natPosixProcess.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natPosixProcess.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,455 @@
+// natPosixProcess.cc - Native side of POSIX process code.
+
+/* Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#include <signal.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/lang/ConcreteProcess$ProcessManager.h>
+#include <java/lang/ConcreteProcess.h>
+#include <java/lang/IllegalThreadStateException.h>
+#include <java/lang/InternalError.h>
+#include <java/lang/InterruptedException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Thread.h>
+#include <java/io/File.h>
+#include <java/io/FileDescriptor.h>
+#include <gnu/java/nio/channels/FileChannelImpl.h>
+#include <java/io/FileInputStream.h>
+#include <java/io/FileOutputStream.h>
+#include <java/io/IOException.h>
+#include <java/lang/OutOfMemoryError.h>
+
+using gnu::java::nio::channels::FileChannelImpl;
+
+extern char **environ;
+
+static char *
+new_string (jstring string)
+{
+  jsize s = _Jv_GetStringUTFLength (string);
+  char *buf = (char *) _Jv_Malloc (s + 1);
+  _Jv_GetStringUTFRegion (string, 0, string->length(), buf);
+  buf[s] = '\0';
+  return buf;
+}
+
+static void
+cleanup (char **args, char **env, char *path)
+{
+  if (args != NULL)
+    {
+      for (int i = 0; args[i] != NULL; ++i)
+	_Jv_Free (args[i]);
+      _Jv_Free (args);
+    }
+  if (env != NULL)
+    {
+      for (int i = 0; env[i] != NULL; ++i)
+	_Jv_Free (env[i]);
+      _Jv_Free (env);
+    }
+  if (path != NULL)
+    _Jv_Free (path);
+}
+
+// This makes our error handling a bit simpler and it lets us avoid
+// thread bugs where we close a possibly-reopened file descriptor for
+// a second time.
+static void
+myclose (int &fd)
+{
+  if (fd != -1)
+    close (fd);
+  fd = -1;
+}
+
+// There has to be a signal handler in order to be able to
+// sigwait() on SIGCHLD.  The information passed is ignored as it
+// will be recovered by the waitpid() call.
+static void
+sigchld_handler (int)
+{
+  // Ignore.
+}
+
+
+// Get ready to enter the main reaper thread loop.
+void
+java::lang::ConcreteProcess$ProcessManager::init ()
+{
+  using namespace java::lang;
+  // Remenber our PID so other threads can kill us.
+  reaperPID = (jlong) pthread_self ();
+
+  // SIGCHLD is blocked in all threads in posix-threads.cc.
+  // Setup the SIGCHLD handler.
+  struct sigaction sa;
+  memset (&sa, 0, sizeof (sa));
+
+  sa.sa_handler = sigchld_handler;
+  // We only want signals when the things exit.
+  sa.sa_flags = SA_NOCLDSTOP;
+
+  if (-1 == sigaction (SIGCHLD, &sa, NULL))
+    goto error;
+
+  // All OK.
+  return;
+
+error:
+  throw new InternalError (JvNewStringUTF (strerror (errno)));
+}
+
+void
+java::lang::ConcreteProcess$ProcessManager::waitForSignal ()
+{
+  // Wait for SIGCHLD
+  sigset_t mask;
+  pthread_sigmask (0, NULL, &mask);
+  sigdelset (&mask, SIGCHLD);
+
+  // Use sigsuspend() instead of sigwait() as sigwait() doesn't play
+  // nicely with the GC's use of signals.
+  sigsuspend (&mask);
+
+  // Do not check sigsuspend return value.  The only legitimate return
+  // is EINTR, but there is a known kernel bug affecting alpha-linux
+  // wrt sigsuspend+handler+sigreturn that can result in a return value
+  // of __NR_sigsuspend and errno unset.  Don't fail unnecessarily on
+  // older kernel versions.
+
+  // All OK.
+  return;
+}
+
+jboolean java::lang::ConcreteProcess$ProcessManager::reap ()
+{
+  using namespace java::lang;
+
+  pid_t pid;
+
+  for (;;)
+    {
+      // Get the return code from a dead child process.
+      int status;
+      pid = waitpid ((pid_t) - 1, &status, WNOHANG);
+      if (pid == -1)
+	{
+	  if (errno == ECHILD)
+	    return false;
+	  else
+	    goto error;
+	}
+
+      if (pid == 0)
+        return true;   // No children to wait for.
+
+      // Look up the process in our pid map.
+      ConcreteProcess * process = removeProcessFromMap ((jlong) pid);
+
+      // Note that if process==NULL, then we have an unknown child.
+      // This is not common, but can happen, and isn't an error.
+      if (process)
+	{
+	  JvSynchronize sync (process);
+	  process->status = WIFEXITED (status) ? WEXITSTATUS (status) : -1;
+	  process->state = ConcreteProcess::STATE_TERMINATED;
+          process->processTerminationCleanup();
+	  process->notifyAll ();
+	}
+    }
+
+error:
+  throw new InternalError (JvNewStringUTF (strerror (errno)));
+}
+
+void
+java::lang::ConcreteProcess$ProcessManager::signalReaper ()
+{
+  int c = pthread_kill ((pthread_t) reaperPID, SIGCHLD);
+  if (c == 0)
+    return;
+  // pthread_kill() failed.
+  throw new InternalError (JvNewStringUTF (strerror (c)));
+}
+
+void
+java::lang::ConcreteProcess::nativeDestroy ()
+{
+  int c = kill ((pid_t) pid, SIGKILL);
+  if (c == 0)
+    return;
+  // kill() failed.
+  throw new InternalError (JvNewStringUTF (strerror (errno)));
+}
+
+void
+java::lang::ConcreteProcess::nativeSpawn ()
+{
+  using namespace java::io;
+
+  // Initialize all locals here to make cleanup simpler.
+  char **args = NULL;
+  char **env = NULL;
+  char *path = NULL;
+  int inp[2], outp[2], errp[2], msgp[2];
+  inp[0] = -1;
+  inp[1] = -1;
+  outp[0] = -1;
+  outp[1] = -1;
+  errp[0] = -1;
+  errp[1] = -1;
+  msgp[0] = -1;
+  msgp[1] = -1;
+  errorStream = NULL;
+  inputStream = NULL;
+  outputStream = NULL;
+
+  try
+    {
+      // Transform arrays to native form.
+    args = (char **) _Jv_Malloc ((progarray->length + 1) * sizeof (char *));
+
+      // Initialize so we can gracefully recover.
+      jstring *elts = elements (progarray);
+      for (int i = 0; i <= progarray->length; ++i)
+	args[i] = NULL;
+
+      for (int i = 0; i < progarray->length; ++i)
+	args[i] = new_string (elts[i]);
+      args[progarray->length] = NULL;
+
+      if (envp)
+	{
+	  env = (char **) _Jv_Malloc ((envp->length + 1) * sizeof (char *));
+	  elts = elements (envp);
+
+	  // Initialize so we can gracefully recover.
+	  for (int i = 0; i <= envp->length; ++i)
+	    env[i] = NULL;
+
+	  for (int i = 0; i < envp->length; ++i)
+	    env[i] = new_string (elts[i]);
+	  env[envp->length] = NULL;
+	}
+
+      // We allocate this here because we can't call malloc() after
+      // the fork.
+      if (dir != NULL)
+	path = new_string (dir->getPath ());
+
+      // Create pipes for I/O.  MSGP is for communicating exec()
+      // status.
+      if (pipe (inp) || pipe (outp) || pipe (errp) || pipe (msgp)
+	  || fcntl (msgp[1], F_SETFD, FD_CLOEXEC))
+      throw new IOException (JvNewStringUTF (strerror (errno)));
+
+      // We create the streams before forking.  Otherwise if we had an
+      // error while creating the streams we would have run the child
+      // with no way to communicate with it.
+    errorStream =
+      new FileInputStream (new
+                           FileChannelImpl (errp[0], FileChannelImpl::READ));
+    inputStream =
+      new FileInputStream (new
+                           FileChannelImpl (inp[0], FileChannelImpl::READ));
+    outputStream =
+      new FileOutputStream (new FileChannelImpl (outp[1],
+                                             FileChannelImpl::WRITE));
+
+      // We don't use vfork() because that would cause the local
+      // environment to be set by the child.
+
+    // Use temporary for fork result to avoid dirtying an extra page.
+    pid_t pid_tmp;
+    if ((pid_tmp = fork ()) == -1)
+      throw new IOException (JvNewStringUTF (strerror (errno)));
+
+    if (pid_tmp == 0)
+	{
+	  // Child process, so remap descriptors, chdir and exec.
+	  if (envp)
+	    {
+	      // Preserve PATH and LD_LIBRARY_PATH unless specified
+	      // explicitly.
+	      char *path_val = getenv ("PATH");
+	      char *ld_path_val = getenv ("LD_LIBRARY_PATH");
+	      environ = env;
+	      if (path_val && getenv ("PATH") == NULL)
+		{
+		char *path_env =
+                  (char *) _Jv_Malloc (strlen (path_val) + 5 + 1);
+		  strcpy (path_env, "PATH=");
+		  strcat (path_env, path_val);
+		  putenv (path_env);
+		}
+	      if (ld_path_val && getenv ("LD_LIBRARY_PATH") == NULL)
+		{
+		char *ld_path_env =
+                  (char *) _Jv_Malloc (strlen (ld_path_val) + 16 + 1);
+		  strcpy (ld_path_env, "LD_LIBRARY_PATH=");
+		  strcat (ld_path_env, ld_path_val);
+		  putenv (ld_path_env);
+		}
+	    }
+
+	  // We ignore errors from dup2 because they should never occur.
+	  dup2 (outp[0], 0);
+	  dup2 (inp[1], 1);
+	  dup2 (errp[1], 2);
+
+	  // Use close and not myclose -- we're in the child, and we
+	  // aren't worried about the possible race condition.
+	  close (inp[0]);
+	  close (inp[1]);
+	  close (errp[0]);
+	  close (errp[1]);
+	  close (outp[0]);
+	  close (outp[1]);
+	  close (msgp[0]);
+          
+	  // Change directory.
+	  if (path != NULL)
+	    {
+	      if (chdir (path) != 0)
+		{
+		  char c = errno;
+		  write (msgp[1], &c, 1);
+		  _exit (127);
+		}
+	    }
+          // Make sure all file descriptors are closed.  In
+          // multi-threaded programs, there is a race between when a
+          // descriptor is obtained, when we can set FD_CLOEXEC, and
+          // fork().  If the fork occurs before FD_CLOEXEC is set, the
+          // descriptor would leak to the execed process if we did not
+          // manually close it.  So that is what we do.  Since we
+          // close all the descriptors, it is redundant to set
+          // FD_CLOEXEC on them elsewhere.
+          int max_fd;
+#ifdef HAVE_GETRLIMIT
+          rlimit rl;
+          int rv = getrlimit(RLIMIT_NOFILE, &rl);
+          if (rv == 0)
+            max_fd = rl.rlim_max - 1;
+          else
+            max_fd = 1024 - 1;
+#else
+          max_fd = 1024 - 1;
+#endif
+          while(max_fd > 2)
+            {
+              if (max_fd != msgp[1])
+                close (max_fd);
+              max_fd--;
+            }
+	  // Make sure that SIGCHLD is unblocked for the new process.
+	  sigset_t mask;
+	  sigemptyset (&mask);
+	  sigaddset (&mask, SIGCHLD);
+	  sigprocmask (SIG_UNBLOCK, &mask, NULL);
+
+	  execvp (args[0], args);
+
+	  // Send the parent notification that the exec failed.
+	  char c = errno;
+	  write (msgp[1], &c, 1);
+	  _exit (127);
+	}
+
+      // Parent.  Close extra file descriptors and mark ours as
+      // close-on-exec.
+      pid = (jlong) pid_tmp;
+
+      myclose (outp[0]);
+      myclose (inp[1]);
+      myclose (errp[1]);
+      myclose (msgp[1]);
+
+      char c;
+      int r = read (msgp[0], &c, 1);
+      if (r == -1)
+      throw new IOException (JvNewStringUTF (strerror (errno)));
+      else if (r != 0)
+      throw new IOException (JvNewStringUTF (strerror (c)));
+    }
+  catch (java::lang::Throwable *thrown)
+    {
+      // Do some cleanup we only do on failure.  If a stream object
+      // has been created, we must close the stream itself (to avoid
+      // duplicate closes when the stream object is collected).
+      // Otherwise we simply close the underlying file descriptor.
+      // We ignore errors here as they are uninteresting.
+
+      try
+	{
+	  if (inputStream != NULL)
+	    inputStream->close ();
+	  else
+	    myclose (inp[0]);
+	}
+      catch (java::lang::Throwable *ignore)
+	{
+	}
+
+      try
+	{
+	  if (outputStream != NULL)
+	    outputStream->close ();
+	  else
+	    myclose (outp[1]);
+	}
+      catch (java::lang::Throwable *ignore)
+	{
+	}
+
+      try
+	{
+	  if (errorStream != NULL)
+	    errorStream->close ();
+	  else
+	    myclose (errp[0]);
+	}
+      catch (java::lang::Throwable *ignore)
+	{
+	}
+
+      // These are potentially duplicate, but it doesn't matter due to
+      // the use of myclose.
+      myclose (outp[0]);
+      myclose (inp[1]);
+      myclose (errp[1]);
+      myclose (msgp[1]);
+
+    exception = thrown;
+    }
+
+  myclose (msgp[0]);
+  cleanup (args, env, path);
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natRuntime.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natRuntime.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natRuntime.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natRuntime.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,319 @@
+// natRuntime.cc - Implementation of native side of Runtime class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-props.h>
+#include <java-stack.h>
+#include <java/lang/Long.h>
+#include <java/lang/Runtime.h>
+#include <java/lang/UnknownError.h>
+#include <java/lang/UnsatisfiedLinkError.h>
+#include <gnu/gcj/runtime/FinalizerThread.h>
+#include <java/io/File.h>
+#include <java/util/TimeZone.h>
+#include <java/lang/StringBuffer.h>
+#include <java/lang/Process.h>
+#include <java/lang/ConcreteProcess.h>
+#include <java/lang/ClassLoader.h>
+
+#include <jni.h>
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#include <errno.h>
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+
+
+
+#ifdef USE_LTDL
+#include <ltdl.h>
+
+/* FIXME: we don't always need this.  The next libtool will let us use
+   AC_LTDL_PREOPEN to see if we do.  */
+extern const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } };
+
+struct lookup_data
+{
+  const char *symname;
+  void *result;
+};
+
+static int
+find_symbol (lt_dlhandle handle, lt_ptr data)
+{
+  lookup_data *ld = (lookup_data *) data;
+  ld->result = lt_dlsym (handle, ld->symname);
+  return ld->result != NULL;
+}
+
+void *
+_Jv_FindSymbolInExecutable (const char *symname)
+{
+  lookup_data data;
+  data.symname = symname;
+  data.result = NULL;
+  lt_dlforeach (find_symbol, (lt_ptr) &data);
+  return data.result;
+}
+
+#else
+
+void *
+_Jv_FindSymbolInExecutable (const char *)
+{
+  return NULL;
+}
+
+#endif /* USE_LTDL */
+
+
+
+void
+java::lang::Runtime::runFinalizationForExit ()
+{
+  if (finalizeOnExit)
+    _Jv_RunAllFinalizers ();
+}
+
+void
+java::lang::Runtime::exitInternal (jint status)
+{
+  // Make status right for Unix.  This is perhaps strange.
+  if (status < 0 || status > 255)
+    status = 255;
+
+  ::exit (status);
+}
+
+jlong
+java::lang::Runtime::freeMemory (void)
+{
+  return _Jv_GCFreeMemory ();
+}
+
+void
+java::lang::Runtime::gc (void)
+{
+  _Jv_RunGC ();
+}
+
+#ifdef USE_LTDL
+// List of names for JNI_OnLoad.
+static const char *onload_names[] = _Jv_platform_onload_names;
+#endif
+
+void
+java::lang::Runtime::_load (jstring path, jboolean do_search)
+{
+  JvSynchronize sync (this);
+  using namespace java::lang;
+#ifdef USE_LTDL
+  jint len = _Jv_GetStringUTFLength (path);
+  char buf[len + 1 + strlen (_Jv_platform_solib_prefix)
+	   + strlen (_Jv_platform_solib_suffix)];
+  int offset = 0;
+  if (do_search)
+    {
+      strcpy (buf, _Jv_platform_solib_prefix);
+      offset = strlen (_Jv_platform_solib_prefix);
+    }
+  jsize total = JvGetStringUTFRegion (path, 0, path->length(), &buf[offset]);
+  buf[offset + total] = '\0';
+
+  char *lib_name = buf;
+
+  if (do_search)
+    {
+      ClassLoader *look = _Jv_StackTrace::GetFirstNonSystemClassLoader ();
+
+      if (look != NULL)
+	{
+	  // Don't include solib prefix in string passed to
+	  // findLibrary.
+	  jstring name = look->findLibrary(JvNewStringUTF(&buf[offset]));
+	  if (name != NULL)
+	    {
+	      len = _Jv_GetStringUTFLength (name);
+	      lib_name = (char *) _Jv_AllocBytes(len + 1);
+	      total = JvGetStringUTFRegion (name, 0,
+					    name->length(), lib_name);
+	      lib_name[total] = '\0';
+	      // Don't append suffixes any more; we have the full file
+	      // name.
+	      do_search = false;
+	    }
+	}
+    }
+
+  lt_dlhandle h;
+  // FIXME: make sure path is absolute.
+  {
+    // Synchronize on java.lang.Class. This is to protect the class chain from
+    // concurrent modification by class registration calls which may be run
+    // during the dlopen().
+    JvSynchronize sync (&java::lang::Class::class$);
+    h = do_search ? lt_dlopenext (lib_name) : lt_dlopen (lib_name);
+  }
+  if (h == NULL)
+    {
+      const char *msg = lt_dlerror ();
+      jstring str = JvNewStringLatin1 (lib_name);
+      str = str->concat (JvNewStringLatin1 (": "));
+      str = str->concat (JvNewStringLatin1 (msg));
+      throw new UnsatisfiedLinkError (str);
+    }
+
+  // Search for JNI_OnLoad function.
+  void *onload = NULL;
+  const char **name = onload_names;
+  while (*name != NULL)
+    {
+      onload = lt_dlsym (h, *name);
+      if (onload != NULL)
+	break;
+      ++name;
+    }
+
+  if (onload != NULL)
+    {
+      JavaVM *vm = _Jv_GetJavaVM ();
+      if (vm == NULL)
+	{
+	  // FIXME: what?
+	  return;
+	}
+
+      // Push a new frame so that JNI_OnLoad will get the right class
+      // loader if it calls FindClass.
+      ::java::lang::ClassLoader *loader
+	  = _Jv_StackTrace::GetFirstNonSystemClassLoader();
+      JNIEnv *env = _Jv_GetJNIEnvNewFrameWithLoader (loader);
+      jint vers = ((jint (JNICALL *) (JavaVM *, void *)) onload) (vm, NULL);
+      _Jv_JNI_PopSystemFrame (env);
+      if (vers != JNI_VERSION_1_1 && vers != JNI_VERSION_1_2
+	  && vers != JNI_VERSION_1_4)
+	{
+	  // FIXME: unload the library.
+	  throw new UnsatisfiedLinkError (JvNewStringLatin1 ("unrecognized version from JNI_OnLoad"));
+	}
+    }
+#else
+  throw new UnknownError
+    (JvNewStringLatin1 (do_search
+			? "Runtime.loadLibrary not implemented"
+			: "Runtime.load not implemented"));
+#endif /* USE_LTDL */
+}
+
+jboolean
+java::lang::Runtime::loadLibraryInternal (jstring lib)
+{
+  JvSynchronize sync (this);
+  using namespace java::lang;
+#ifdef USE_LTDL
+  jint len = _Jv_GetStringUTFLength (lib);
+  char buf[len + 1];
+  jsize total = JvGetStringUTFRegion (lib, 0, lib->length(), buf);
+  buf[total] = '\0';
+  // FIXME: make sure path is absolute.
+  lt_dlhandle h = lt_dlopenext (buf);
+  return h != NULL;
+#else
+  return false;
+#endif /* USE_LTDL */
+}
+
+void
+java::lang::Runtime::init (void)
+{
+#ifdef USE_LTDL
+  lt_dlinit ();
+  // Set module load path.
+  lt_dlsetsearchpath (_Jv_Module_Load_Path);
+  // Make sure self is opened.
+  lt_dlopen (NULL);
+#endif
+}
+
+void
+java::lang::Runtime::runFinalization (void)
+{
+  gnu::gcj::runtime::FinalizerThread::finalizerReady ();
+}
+
+jlong
+java::lang::Runtime::totalMemory (void)
+{
+  return _Jv_GCTotalMemory ();
+}
+
+jlong
+java::lang::Runtime::maxMemory (void)
+{
+  // We don't have a maximum.  FIXME: we might if we ask the GC for
+  // one.
+  return Long::MAX_VALUE;
+}
+
+void
+java::lang::Runtime::traceInstructions (jboolean)
+{
+  // Do nothing.
+}
+
+void
+java::lang::Runtime::traceMethodCalls (jboolean)
+{
+  // Do nothing.
+}
+
+java::lang::Process *
+java::lang::Runtime::execInternal (jstringArray cmd,
+				   jstringArray env,
+				   java::io::File *dir)
+{
+  return new java::lang::ConcreteProcess (cmd, env, dir);
+}
+
+jint
+java::lang::Runtime::availableProcessors (void)
+{
+  // FIXME: find the real value.
+  return 1;
+}
+
+jstring
+java::lang::Runtime::nativeGetLibname (jstring pathname, jstring libname)
+{
+  java::lang::StringBuffer *sb = new java::lang::StringBuffer ();
+  sb->append(pathname);
+  if (pathname->length() > 0)
+    sb->append (_Jv_platform_file_separator);
+
+  sb->append (JvNewStringLatin1 (_Jv_platform_solib_prefix));
+  sb->append(libname);
+  sb->append (JvNewStringLatin1 (_Jv_platform_solib_suffix));
+
+  return sb->toString();
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natString.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natString.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natString.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natString.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1044 @@
+// natString.cc - Implementation of java.lang.String native methods.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <java/lang/Character.h>
+#include <java/lang/CharSequence.h>
+#include <java/lang/String.h>
+#include <java/lang/IndexOutOfBoundsException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/StringIndexOutOfBoundsException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/StringBuffer.h>
+#include <java/io/ByteArrayOutputStream.h>
+#include <java/io/OutputStreamWriter.h>
+#include <java/io/ByteArrayInputStream.h>
+#include <java/io/InputStreamReader.h>
+#include <java/util/Locale.h>
+#include <gnu/gcj/convert/UnicodeToBytes.h>
+#include <gnu/gcj/convert/BytesToUnicode.h>
+#include <gnu/gcj/runtime/StringBuffer.h>
+#include <jvm.h>
+
+static jstring* strhash = NULL;
+static int strhash_count = 0;  /* Number of slots used in strhash. */
+static int strhash_size = 0;  /* Number of slots available in strhash.
+                               * Assumed be power of 2! */
+
+// Some defines used by toUpperCase / toLowerCase.
+#define ESSET     0x00df
+#define CAPITAL_S 0x0053
+#define SMALL_I   0x0069
+#define CAPITAL_I_WITH_DOT 0x0130
+#define SMALL_DOTLESS_I    0x0131
+#define CAPITAL_I 0x0049
+
+#define DELETED_STRING ((jstring)(~0))
+#define SET_STRING_IS_INTERNED(STR) /* nothing */
+
+#define UNMASK_PTR(Ptr) (((unsigned long) (Ptr)) & ~0x01)
+#define MASK_PTR(Ptr) (((unsigned long) (Ptr)) | 0x01)
+#define PTR_MASKED(Ptr) (((unsigned long) (Ptr)) & 0x01)
+
+/* Find a slot where the string with elements DATA, length LEN,
+   and hash HASH should go in the strhash table of interned strings. */
+jstring*
+_Jv_StringFindSlot (jchar* data, jint len, jint hash)
+{
+  JvSynchronize sync (&java::lang::String::class$);
+
+  int start_index = hash & (strhash_size - 1);
+  int deleted_index = -1;
+
+  int index = start_index;
+  /* step must be non-zero, and relatively prime with strhash_size. */
+  jint step = (hash ^ (hash >> 16)) | 1;
+  do
+    {
+      jstring* ptr = &strhash[index];
+      jstring value = (jstring) UNMASK_PTR (*ptr);
+      if (value == NULL)
+	{
+	  if (deleted_index >= 0)
+	    return (&strhash[deleted_index]);
+	  else
+	    return ptr;
+	}
+      else if (*ptr == DELETED_STRING)
+	deleted_index = index;
+      else if (value->length() == len
+	       && memcmp(JvGetStringChars(value), data, 2*len) == 0)
+	return (ptr);
+      index = (index + step) & (strhash_size - 1);
+    }
+  while (index != start_index);
+  // Note that we can have INDEX == START_INDEX if the table has no
+  // NULL entries but does have DELETED_STRING entries.
+  JvAssert (deleted_index >= 0);
+  return &strhash[deleted_index];
+}
+
+/* Calculate a hash code for the string starting at PTR at given LENGTH.
+   This uses the same formula as specified for java.lang.String.hash. */
+
+static jint
+hashChars (jchar* ptr, jint length)
+{
+  jchar* limit = ptr + length;
+  jint hash = 0;
+  // Updated specification from
+  // http://www.javasoft.com/docs/books/jls/clarify.html.
+  while (ptr < limit)
+    hash = (31 * hash) + *ptr++;
+  return hash;
+}
+
+jint
+java::lang::String::hashCode()
+{
+  if (cachedHashCode == 0)
+    cachedHashCode = hashChars(JvGetStringChars(this), length());
+  return cachedHashCode;
+}
+
+jstring*
+_Jv_StringGetSlot (jstring str)
+{
+  jchar* data = JvGetStringChars(str);
+  int length = str->length();
+  return _Jv_StringFindSlot(data, length, hashChars (data, length));
+}
+
+static void
+rehash ()
+{
+  JvSynchronize sync (&java::lang::String::class$);
+
+  if (strhash == NULL)
+    {
+      strhash_size = 1024;
+      strhash = (jstring *) _Jv_AllocBytes (strhash_size * sizeof (jstring));
+    }
+  else
+    {
+      int i = strhash_size;
+      jstring* ptr = strhash + i;
+      int nsize = strhash_size * 2;
+      jstring *next = (jstring *) _Jv_AllocBytes (nsize * sizeof (jstring));
+
+      while (--i >= 0)
+	{
+	  --ptr;
+	  if (*ptr == NULL || *ptr == DELETED_STRING)
+	    continue;
+
+	  /* This is faster equivalent of
+	   * *__JvGetInternSlot(*ptr) = *ptr; */
+	  jstring val = (jstring) UNMASK_PTR (*ptr);
+	  jint hash = val->hashCode();
+	  jint index = hash & (nsize - 1);
+	  jint step = (hash ^ (hash >> 16)) | 1;
+	  for (;;)
+	    {
+	      if (next[index] == NULL)
+		{
+		  next[index] = *ptr;
+		  break;
+		}
+	      index = (index + step) & (nsize - 1);
+	    }
+	}
+
+      strhash_size = nsize;
+      strhash = next;
+    }
+}
+
+jstring
+java::lang::String::intern()
+{
+  JvSynchronize sync (&java::lang::String::class$);
+  if (3 * strhash_count >= 2 * strhash_size)
+    rehash();
+  jstring* ptr = _Jv_StringGetSlot(this);
+  if (*ptr != NULL && *ptr != DELETED_STRING)
+    {
+      // See description in _Jv_FinalizeString() to understand this.
+      *ptr = (jstring) MASK_PTR (*ptr);
+      return (jstring) UNMASK_PTR (*ptr);
+    }
+  jstring str = (this->data == this
+		 ? this
+		 : _Jv_NewString(JvGetStringChars(this), this->length()));
+  SET_STRING_IS_INTERNED(str);
+  strhash_count++;
+  *ptr = str;
+  // When string is GC'd, clear the slot in the hash table.
+  _Jv_RegisterStringFinalizer (str);
+  return str;
+}
+
+// The fake String finalizer.  This is only used when the String has
+// been intern()d.  However, we must check this case, as it might be
+// called by the Reference code for any String.
+void
+_Jv_FinalizeString (jobject obj)
+{
+  JvSynchronize sync (&java::lang::String::class$);
+
+  // We might not actually have intern()d any strings at all, if
+  // we're being called from Reference.
+  if (! strhash)
+    return;
+
+  jstring str = reinterpret_cast<jstring> (obj);
+  jstring *ptr = _Jv_StringGetSlot(str);
+  if (*ptr == NULL || *ptr == DELETED_STRING
+      || (jobject) UNMASK_PTR (*ptr) != obj)
+    return;
+
+  // We assume the lowest bit of the pointer is free for our nefarious
+  // manipulations.  What we do is set it to `0' (implicitly) when
+  // interning the String.  If we subsequently re-intern the same
+  // String, then we set the bit.  When finalizing, if the bit is set
+  // then we clear it and re-register the finalizer.  We know this is
+  // a safe approach because both intern() and _Jv_FinalizeString()
+  // acquire the class lock; this bit can't be manipulated when the
+  // lock is not held.  So if we are finalizing and the bit is clear
+  // then we know all references are gone and we can clear the entry
+  // in the hash table.  The naive approach of simply clearing the
+  // pointer here fails in the case where a request to intern a new
+  // string with the same contents is made between the time the
+  // intern()d string is found to be unreachable and when the
+  // finalizer is actually run.  In this case we could clear a pointer
+  // to a valid string, and future intern() calls for that particular
+  // value would spuriously fail.
+  if (PTR_MASKED (*ptr))
+    {
+      *ptr = (jstring) UNMASK_PTR (*ptr);
+      _Jv_RegisterStringFinalizer (obj);
+    }
+  else
+    {
+      *ptr = DELETED_STRING;
+      strhash_count--;
+    }
+}
+
+jstring
+_Jv_NewStringUTF (const char *bytes)
+{
+  int size = strlen (bytes);
+  unsigned char *p = (unsigned char *) bytes;
+
+  int length = _Jv_strLengthUtf8 ((char *) p, size);
+  if (length < 0)
+    return NULL;
+
+  jstring jstr = JvAllocString (length);
+  jchar *chrs = JvGetStringChars (jstr);
+
+  p = (unsigned char *) bytes;
+  unsigned char *limit = p + size;
+  while (p < limit)
+    *chrs++ = UTF8_GET (p, limit);
+
+  return jstr;
+}
+
+jstring
+_Jv_NewStringUtf8Const (Utf8Const* str)
+{
+  jchar *chrs;
+  jchar buffer[100];
+  jstring jstr;
+  unsigned char* data = (unsigned char*) str->data;
+  unsigned char* limit = data + str->length;
+  int length = _Jv_strLengthUtf8(str->data, str->length);
+
+  if (length <= (int) (sizeof(buffer) / sizeof(jchar)))
+    {
+      jstr = NULL;
+      chrs = buffer;
+    }
+  else
+    {
+      jstr = JvAllocString(length);
+      chrs = JvGetStringChars(jstr);
+    }
+
+  jint hash = 0;
+  while (data < limit)
+    {
+      jchar ch = UTF8_GET(data, limit);
+      hash = (31 * hash) + ch;
+      *chrs++ = ch;
+    }
+  chrs -= length;
+
+  JvSynchronize sync (&java::lang::String::class$);
+  if (3 * strhash_count >= 2 * strhash_size)
+    rehash();
+  jstring* ptr = _Jv_StringFindSlot (chrs, length, hash);
+  if (*ptr != NULL && *ptr != DELETED_STRING)
+    return (jstring) UNMASK_PTR (*ptr);
+  strhash_count++;
+  if (jstr == NULL)
+    {
+      jstr = JvAllocString(length);
+      chrs = JvGetStringChars(jstr);
+      memcpy (chrs, buffer, sizeof(jchar)*length);
+    }
+  jstr->cachedHashCode = hash;
+  *ptr = jstr;
+  SET_STRING_IS_INTERNED(jstr);
+  // When string is GC'd, clear the slot in the hash table.  Note that
+  // we don't have to call _Jv_RegisterStringFinalizer here, as we
+  // know the new object cannot be referred to by a Reference.
+  _Jv_RegisterFinalizer ((void *) jstr, _Jv_FinalizeString);
+  return jstr;
+}
+
+jsize
+_Jv_GetStringUTFLength (jstring string)
+{
+  jsize len = 0;
+  jchar *ptr = JvGetStringChars (string);
+  jsize i = string->length();
+  while (--i >= 0)
+    {
+      jchar ch = *ptr++;
+      if (ch > 0 && ch <= 0x7F)
+	len += 1;
+      else if (ch <= 0x7FF)
+	len += 2;
+      else
+	len += 3;
+    }
+  return len;
+}
+
+// Not sure this quite matches GetStringUTFRegion.
+// null-termination of result?  len?  throw exception?
+jsize
+_Jv_GetStringUTFRegion (jstring str, jsize start, jsize len, char *buf)
+{
+  jchar *sptr = JvGetStringChars (str) + start;
+  jsize i = len;
+  char *dptr = buf;
+  while (--i >= 0)
+    {
+      jchar ch = *sptr++;
+      if (ch > 0 && ch <= 0x7F)
+	*dptr++ = (char) ch;
+      else if (ch <= 0x7FF)
+	{
+	  *dptr++ = (char) (0xC0 + ((ch >> 6) & 0x1F));
+	  *dptr++ = (char) (0x80 + (ch & 0x3F));
+	}
+      else
+	{
+	  *dptr++ = (char) (0xE0 + ((ch >> 12) & 0xF));
+	  *dptr++ = (char) (0x80 + ((ch >> 6) & 0x3F));
+	  *dptr++ = (char) (0x80 + (ch & 0x3F));
+	}
+    }
+  return dptr - buf;
+}
+
+/* Put printed (decimal) representation of NUM in a buffer.
+   BUFEND marks the end of the buffer, which must be at least 11 jchars long.
+   Returns the COUNT of jchars written.  The result is in
+   (BUFEND - COUNT) (inclusive) upto (BUFEND) (exclusive). */
+
+jint
+_Jv_FormatInt (jchar* bufend, jint num)
+{
+  register jchar* ptr = bufend;
+  jboolean isNeg;
+  if (num < 0)
+    {
+      isNeg = true;
+      if (num != (jint) -2147483648U)
+	num = -(num);
+      else
+	{
+	  // Handle special case of MIN_VALUE.
+	  *--ptr = '8';
+	  num = 214748364;
+	}
+      }
+    else
+      isNeg = false;
+
+    do
+      {
+        *--ptr = (jchar) ((int) '0' + (num % 10));
+        num /= 10;
+      }
+    while (num > 0);
+
+    if (isNeg)
+      *--ptr = '-';
+    return bufend - ptr;
+}
+
+jstring
+java::lang::String::valueOf (jint num)
+{
+  // Use an array large enough for "-2147483648"; i.e. 11 chars.
+  jchar buffer[11];
+  int i = _Jv_FormatInt (buffer+11, num);
+  return _Jv_NewString (buffer+11-i, i);
+}
+
+jstring
+_Jv_NewString(const jchar *chars, jsize len)
+{
+  jstring str = _Jv_AllocString(len);
+  jchar* data = JvGetStringChars (str);
+  memcpy (data, chars, len * sizeof (jchar));
+  return str;
+}
+
+jstring
+_Jv_NewStringLatin1(const char *bytes, jsize len)
+{
+  jstring str = JvAllocString(len);
+  jchar* data = JvGetStringChars (str);
+  while (--len >= 0)
+    *data++ = *(unsigned char*)bytes++;
+  return str;
+}
+
+void
+java::lang::String::init(jcharArray chars, jint offset, jint count,
+			 jboolean dont_copy)
+{
+  if (! chars)
+    throw new NullPointerException;
+  jsize data_size = JvGetArrayLength (chars);
+  if (offset < 0 || count < 0 || offset + count < 0
+      || offset + count > data_size)
+    throw new ArrayIndexOutOfBoundsException;
+  jcharArray array;
+  jchar *pdst;
+  if (! dont_copy)
+    {
+      array = JvNewCharArray(count);
+      pdst = elements (array);
+      memcpy (pdst, elements (chars) + offset, count * sizeof (jchar));
+    }
+  else
+    {
+      array = chars;
+      pdst = &(elements(array)[offset]);
+    }
+
+  data = array;
+  boffset = (char *) pdst - (char *) array;
+  this->count = count;
+}
+
+void
+java::lang::String::init(jbyteArray ascii, jint hibyte, jint offset,
+			 jint count)
+{
+  if (! ascii)
+    throw new NullPointerException;
+  jsize data_size = JvGetArrayLength (ascii);
+  if (offset < 0 || count < 0 || offset + count < 0
+      || offset + count > data_size)
+    throw new ArrayIndexOutOfBoundsException;
+  jcharArray array = JvNewCharArray(count);
+  jbyte *psrc = elements (ascii) + offset;
+  jchar *pdst = elements (array);
+  data = array;
+  boffset = (char *) pdst - (char *) array;
+  this->count = count;
+  hibyte = (hibyte & 0xff) << 8;
+  while (-- count >= 0)
+    {
+      *pdst++ = hibyte | (*psrc++ & 0xff);
+    }
+}
+
+void
+java::lang::String::init (jbyteArray bytes, jint offset, jint count,
+			  jstring encoding)
+{
+  if (! bytes)
+    throw new NullPointerException;
+  jsize data_size = JvGetArrayLength (bytes);
+  if (offset < 0 || count < 0 || offset + count < 0
+      || offset + count > data_size)
+    throw new ArrayIndexOutOfBoundsException;
+  jcharArray array = JvNewCharArray (count);
+  gnu::gcj::convert::BytesToUnicode *converter
+    = gnu::gcj::convert::BytesToUnicode::getDecoder(encoding);
+  jint outpos = 0;
+  int avail = count;
+  converter->setInput(bytes, offset, offset+count);
+  while (converter->inpos < converter->inlength)
+    {
+      int done = converter->read(array, outpos, avail);
+      if (done == 0)
+	{
+	  jint new_size = 2 * (outpos + avail);
+	  jcharArray new_array = JvNewCharArray (new_size);
+	  memcpy (elements (new_array), elements (array),
+		  outpos * sizeof(jchar));
+	  array = new_array;
+	  avail = new_size - outpos;
+	}
+      else
+	{
+	  outpos += done;
+	  avail -= done;
+	}
+    }
+  converter->done ();
+  this->data = array;
+  this->boffset = (char *) elements (array) - (char *) array;
+  this->count = outpos;
+}
+
+void
+java::lang::String::init (gnu::gcj::runtime::StringBuffer *buffer)
+{
+  init (buffer->value, 0, buffer->count, true);
+}
+
+jboolean
+java::lang::String::equals(jobject anObject)
+{
+  if (anObject == NULL)
+    return false;
+  if (anObject == this)
+    return true;
+  if (anObject->getClass() != &java::lang::String::class$)
+    return false;
+  jstring other = (jstring) anObject;
+  if (count != other->count)
+    return false;
+
+  // If both have cached hash codes, check that.  If the cached hash
+  // codes are zero, don't bother trying to compute them.
+  int myHash = cachedHashCode;
+  int otherHash = other->cachedHashCode;
+  if (myHash && otherHash && myHash != otherHash)
+    return false;
+
+  // We could see if both are interned, and return false.  But that
+  // seems too expensive.
+
+  jchar *xptr = JvGetStringChars (this);
+  jchar *yptr = JvGetStringChars (other);
+  return ! memcmp (xptr, yptr, count * sizeof (jchar));
+}
+
+jboolean
+java::lang::String::contentEquals(java::lang::StringBuffer* buffer)
+{
+  if (buffer == NULL)
+    throw new NullPointerException;
+  JvSynchronize sync(buffer);
+  if (count != buffer->count)
+    return false;
+  if (data == buffer->value)
+    return true; // Possible if shared.
+  jchar *xptr = JvGetStringChars(this);
+  jchar *yptr = elements(buffer->value);
+  return ! memcmp (xptr, yptr, count * sizeof (jchar));
+}
+
+jboolean
+java::lang::String::contentEquals(java::lang::CharSequence *seq)
+{
+  if (seq->length() != count)
+    return false;
+  jchar *value = JvGetStringChars(this);
+  for (int i = 0; i < count; ++i)
+    if (value[i] != seq->charAt(i))
+      return false;
+  return true;
+}
+
+jchar
+java::lang::String::charAt(jint i)
+{
+  if (i < 0 || i >= count)
+    throw new java::lang::StringIndexOutOfBoundsException(i);
+  return JvGetStringChars(this)[i];
+}
+
+void
+java::lang::String::getChars(jint srcBegin, jint srcEnd,
+			     jcharArray dst, jint dstBegin)
+{
+  jint dst_length = JvGetArrayLength (dst);
+  if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count)
+    throw new java::lang::StringIndexOutOfBoundsException;
+  // The 2nd part of the test below is equivalent to 
+  // dstBegin + (srcEnd-srcBegin) > dst_length
+  // except that it does not overflow.
+  if (dstBegin < 0 || dstBegin > dst_length - (srcEnd-srcBegin))
+    throw new ArrayIndexOutOfBoundsException;
+  jchar *dPtr = elements (dst) + dstBegin;
+  jchar *sPtr = JvGetStringChars (this) + srcBegin;
+  jint i = srcEnd - srcBegin;
+  memcpy (dPtr, sPtr, i * sizeof (jchar));
+}
+
+jbyteArray
+java::lang::String::getBytes (jstring enc)
+{
+  jint todo = length();
+  jint buflen = todo;
+  jbyteArray buffer = JvNewByteArray(todo);
+  jint bufpos = 0;
+  jint offset = 0;
+  gnu::gcj::convert::UnicodeToBytes *converter
+    = gnu::gcj::convert::UnicodeToBytes::getEncoder(enc);
+  while (todo > 0 || converter->havePendingBytes())
+    {
+      converter->setOutput(buffer, bufpos);
+      // We only really need to do a single write.
+      converter->setFinished();
+      int converted = converter->write(this, offset, todo, NULL);
+      bufpos = converter->count;
+      if (converted == 0 && bufpos == converter->count)
+	{
+	  buflen *= 2;
+	  jbyteArray newbuffer = JvNewByteArray(buflen);
+	  memcpy (elements (newbuffer), elements (buffer), bufpos);
+	  buffer = newbuffer;
+	}
+      else
+	bufpos = converter->count;
+
+      offset += converted;
+      todo -= converted;
+    }
+  converter->done ();
+  if (bufpos == buflen)
+    return buffer;
+  jbyteArray result = JvNewByteArray(bufpos);
+  memcpy (elements (result), elements (buffer), bufpos);
+  return result;
+}
+
+void
+java::lang::String::getBytes(jint srcBegin, jint srcEnd,
+			     jbyteArray dst, jint dstBegin)
+{
+  jint dst_length = JvGetArrayLength (dst);
+  if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count)
+    throw new java::lang::StringIndexOutOfBoundsException;
+  // The 2nd part of the test below is equivalent to 
+  // dstBegin + (srcEnd-srcBegin) > dst_length
+  // except that it does not overflow.
+  if (dstBegin < 0 || dstBegin > dst_length - (srcEnd-srcBegin))
+    throw new ArrayIndexOutOfBoundsException;
+  jbyte *dPtr = elements (dst) + dstBegin;
+  jchar *sPtr = JvGetStringChars (this) + srcBegin;
+  jint i = srcEnd-srcBegin;
+  while (--i >= 0)
+    *dPtr++ = (jbyte) *sPtr++;
+}
+
+jcharArray
+java::lang::String::toCharArray()
+{
+  jcharArray array = JvNewCharArray(count);
+  jchar *dPtr = elements (array);
+  jchar *sPtr = JvGetStringChars (this);
+  jint i = count;
+  memcpy (dPtr, sPtr, i * sizeof (jchar));
+  return array;
+}
+
+jboolean
+java::lang::String::equalsIgnoreCase (jstring anotherString)
+{
+  if (anotherString == NULL || count != anotherString->count)
+    return false;
+  jchar *tptr = JvGetStringChars (this);
+  jchar *optr = JvGetStringChars (anotherString);
+  jint i = count;
+  while (--i >= 0)
+    {
+      jchar tch = *tptr++;
+      jchar och = *optr++;
+      if (tch != och
+	  && (java::lang::Character::toLowerCase (tch)
+	      != java::lang::Character::toLowerCase (och))
+	  && (java::lang::Character::toUpperCase (tch)
+	      != java::lang::Character::toUpperCase (och)))
+	return false;
+    }
+  return true;
+}
+
+jboolean
+java::lang::String::regionMatches (jint toffset,
+				   jstring other, jint ooffset, jint len)
+{
+  if (toffset < 0 || ooffset < 0 || len < 0
+      || toffset > count - len
+      || ooffset > other->count - len)
+    return false;
+  jchar *tptr = JvGetStringChars (this) + toffset;
+  jchar *optr = JvGetStringChars (other) + ooffset;
+  jint i = len;
+  return ! memcmp (tptr, optr, i * sizeof (jchar));
+}
+
+jint
+java::lang::String::compareTo (jstring anotherString)
+{
+  jchar *tptr = JvGetStringChars (this);
+  jchar *optr = JvGetStringChars (anotherString);
+  jint tlen = this->count;
+  jint olen = anotherString->count;
+  jint i = tlen > olen ? olen : tlen;
+  while (--i >= 0)
+    {
+      jchar tch = *tptr++;
+      jchar och = *optr++;
+      if (tch != och)
+	return (jint) tch - (jint) och;
+    }
+  return tlen - olen;
+}
+
+jboolean
+java::lang::String::regionMatches (jboolean ignoreCase, jint toffset,
+				   jstring other, jint ooffset, jint len)
+{
+  if (toffset < 0 || ooffset < 0 || len < 0
+      || toffset > count - len
+      || ooffset > other->count - len)
+    return false;
+  jchar *tptr = JvGetStringChars (this) + toffset;
+  jchar *optr = JvGetStringChars (other) + ooffset;
+  jint i = len;
+  if (ignoreCase)
+    {
+      while (--i >= 0)
+	{
+	  jchar tch = *tptr++;
+	  jchar och = *optr++;
+	  if ((java::lang::Character::toLowerCase (tch)
+	       != java::lang::Character::toLowerCase (och))
+	      && (java::lang::Character::toUpperCase (tch)
+		  != java::lang::Character::toUpperCase (och)))
+	    return false;
+	}
+      return true;
+    }
+  return ! memcmp (tptr, optr, i * sizeof (jchar));
+}
+
+jboolean
+java::lang::String::startsWith (jstring prefix, jint toffset)
+{
+  jint i = prefix->count;
+  if (toffset < 0 || toffset > count - i)
+    return false;
+  jchar *xptr = JvGetStringChars (this) + toffset;
+  jchar *yptr = JvGetStringChars (prefix);
+  return ! memcmp (xptr, yptr, i * sizeof (jchar));
+}
+
+jint
+java::lang::String::indexOf (jint ch, jint fromIndex)
+{
+  if (fromIndex < 0)
+    fromIndex = 0;
+  jchar *ptr = JvGetStringChars(this);
+  for (;; ++fromIndex)
+    {
+      if (fromIndex >= count)
+	return -1;
+      if (ptr[fromIndex] == ch)
+	return fromIndex;
+    }
+}
+
+jint
+java::lang::String::indexOf (jstring s, jint fromIndex)
+{
+  const jchar *const xchars = JvGetStringChars(s);
+  const jchar *const ychars = JvGetStringChars(this) + fromIndex;
+  
+  const int xlength = s->length ();
+  const int ylength = length () - fromIndex;
+  
+  int i = 0;
+  int j = 0;
+
+  while (i < ylength && j < xlength)
+    {
+      if (xchars[j] != ychars[i])
+	{
+	  i = i - j + 1;
+	  j = 0;
+	}
+      else
+	i++, j++;
+    }
+
+  if (j >= xlength)
+    return fromIndex + i - xlength;
+  else
+    return -1;
+}
+    
+jint
+java::lang::String::lastIndexOf (jint ch, jint fromIndex)
+{
+  if (fromIndex >= count)
+    fromIndex = count - 1;
+  jchar *ptr = JvGetStringChars(this);
+  for (;; --fromIndex)
+    {
+      if (fromIndex < 0)
+	return -1;
+      if (ptr[fromIndex] == ch)
+	return fromIndex;
+    }
+}
+
+jstring
+java::lang::String::substring (jint beginIndex, jint endIndex)
+{
+  if (beginIndex < 0 || endIndex > count || beginIndex > endIndex)
+    throw new StringIndexOutOfBoundsException;
+  if (beginIndex == 0 && endIndex == count)
+    return this;
+  jint newCount = endIndex - beginIndex;
+  // For very small strings, just allocate a new one.  For other
+  // substrings, allocate a new one unless the substring is over half
+  // of the original string.
+  if (newCount <= 8 || newCount < (count >> 1))
+    return JvNewString(JvGetStringChars(this) + beginIndex, newCount);
+  jstring s = new String();
+  s->data = data;
+  s->count = newCount;
+  s->boffset = boffset + sizeof(jchar) * beginIndex;
+  return s;
+}
+
+jstring
+java::lang::String::concat(jstring str)
+{
+  jint str_count = str->count;
+  if (str_count == 0)
+    return this;
+  jstring result = JvAllocString(count + str_count);
+  jchar *dstPtr = JvGetStringChars(result);
+  jchar *srcPtr = JvGetStringChars(this);
+  jint i = count;
+  memcpy (dstPtr, srcPtr, i * sizeof (jchar));
+  dstPtr += i;
+  srcPtr = JvGetStringChars(str);
+  i = str->count;
+  memcpy (dstPtr, srcPtr, i * sizeof (jchar));
+  return result;
+}
+
+jstring
+java::lang::String::replace (jchar oldChar, jchar newChar)
+{
+  jint i;
+  jchar* chrs = JvGetStringChars (this);
+  for (i = 0;  ;  i++)
+    {
+      if (i == count)
+	return this;
+      if (chrs[i] == oldChar)
+	break;
+    }
+  jstring result = JvAllocString (count);
+  jchar *dPtr = JvGetStringChars (result);
+  for (int j = 0;  j < i;  j++)
+    *dPtr++ = chrs[j];
+  for (; i < count;  i++)
+    {
+      jchar ch = chrs[i];
+      if (ch == oldChar)
+	ch = newChar;
+      *dPtr++ = ch;
+    }
+  return result;
+}
+
+jstring
+java::lang::String::toLowerCase (java::util::Locale *locale)
+{
+  jint i;
+  jchar* chrs = JvGetStringChars(this);
+  jchar ch = 0;
+
+  bool handle_tr = false;
+  if (locale != NULL)
+    {
+      String *lang = locale->getLanguage ();
+      if (lang->length () == 2
+	  && lang->charAt (0) == 't'
+	  && lang->charAt (1) == 'r')
+	handle_tr = true;
+    }
+
+  for (i = 0;  ;  i++)
+    {
+      if (i == count)
+	return this;
+      jchar origChar = chrs[i];
+
+      if (handle_tr && (origChar == CAPITAL_I
+			|| origChar == CAPITAL_I_WITH_DOT))
+	break;
+
+      ch = java::lang::Character::toLowerCase(origChar);
+      if (ch != origChar)
+	break;
+    }
+  jstring result = JvAllocString(count);
+  jchar *dPtr = JvGetStringChars (result);
+  for (int j = 0;  j < i;  j++)
+    *dPtr++ = chrs[j];
+  *dPtr++ = ch;  i++;
+  for (; i < count;  i++)
+    {
+      if (handle_tr && chrs[i] == CAPITAL_I)
+	*dPtr++ = SMALL_DOTLESS_I;
+      else if (handle_tr && chrs[i] == CAPITAL_I_WITH_DOT)
+	*dPtr++ = SMALL_I;
+      else
+	*dPtr++ = java::lang::Character::toLowerCase(chrs[i]);
+    }
+  return result;
+}
+
+jstring
+java::lang::String::toUpperCase (java::util::Locale *locale)
+{
+  jint i;
+  jchar* chrs = JvGetStringChars(this);
+  jchar ch;
+
+  // When handling a specific locale there might be special rules.
+  // Currently all existing rules are simply handled inline, as there
+  // are only two and they are documented in the online 1.2 docs.
+  bool handle_esset = locale != NULL;
+  bool handle_tr = false;
+  if (locale != NULL)
+    {
+      String *lang = locale->getLanguage ();
+      if (lang->length () == 2
+	  && lang->charAt (0) == 't'
+	  && lang->charAt (1) == 'r')
+	handle_tr = true;
+    }
+
+  int new_count = count;
+  bool new_string = false;
+  for (i = 0;  ;  i++)
+    {
+      if (i == count)
+	break;
+      jchar origChar = chrs[i];
+
+      if (handle_esset && origChar == ESSET)
+	{
+	  ++new_count;
+	  new_string = true;
+	}
+      else if (handle_tr && (origChar == SMALL_I
+			     || origChar == SMALL_DOTLESS_I))
+	new_string = true;
+      else
+	{
+	  ch = java::lang::Character::toUpperCase(origChar);
+	  if (ch != origChar)
+	    new_string = true;
+	}
+
+      if (new_string && ! handle_esset)
+	break;
+    }
+  if (! new_string)
+    return this;
+  jstring result = JvAllocString(new_count);
+  jchar *dPtr = JvGetStringChars (result);
+  for (i = 0; i < count;  i++)
+    {
+      if (handle_esset && chrs[i] == ESSET)
+	{
+	  *dPtr++ = CAPITAL_S;
+	  *dPtr++ = CAPITAL_S;
+	}
+      else if (handle_tr && chrs[i] == SMALL_I)
+	*dPtr++ = CAPITAL_I_WITH_DOT;
+      else if (handle_tr && chrs[i] == SMALL_DOTLESS_I)
+	*dPtr++ = CAPITAL_I;
+      else
+	*dPtr++ = java::lang::Character::toUpperCase(chrs[i]);
+    }
+  return result;
+}
+
+jstring
+java::lang::String::trim ()
+{
+  jchar* chrs = JvGetStringChars(this);
+  if (count == 0 || (chrs[0] > ' ' && chrs[count-1] > ' '))
+    return this;
+  jint preTrim = 0;
+  for (;; preTrim++)
+    {
+      if (preTrim == count)
+	return new String();
+      if (chrs[preTrim] > ' ')
+	break;
+    }
+  jint endTrim = count;
+  while (chrs[endTrim-1] <= ' ')
+    endTrim--;
+  return substring(preTrim, endTrim);
+}
+
+jstring
+java::lang::String::valueOf(jcharArray data, jint offset, jint count)
+{
+  jint data_length = JvGetArrayLength (data);
+  if (offset < 0 || count < 0 || offset > data_length - count)
+    throw new ArrayIndexOutOfBoundsException;
+  jstring result = JvAllocString(count);
+  jchar *sPtr = elements (data) + offset;
+  jchar *dPtr = JvGetStringChars(result);
+  memcpy (dPtr, sPtr, count * sizeof (jchar));
+  return result;
+}
+
+jstring
+java::lang::String::valueOf(jchar c)
+{
+  jstring result = JvAllocString(1);
+  JvGetStringChars (result)[0] = c;
+  return result;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natStringBuffer.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natStringBuffer.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natStringBuffer.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natStringBuffer.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,42 @@
+// natStringBuffer.cc - Implementation of java.lang.StringBuffer native methods.
+
+/* Copyright (C) 2001, 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <gcj/cni.h>
+#include <java/lang/StringBuffer.h>
+
+java::lang::StringBuffer*
+java::lang::StringBuffer::append (jint num)
+{
+  // Use an array large enough for "-2147483648"; i.e. 11 chars.
+  jchar buffer[11];
+  int i = _Jv_FormatInt (buffer+11, num);
+  JvSynchronize dummy (this);
+  jint needed = count + i;
+  ensureCapacity_unsynchronized (needed);
+  jchar* dst = elements (value) + count;
+  jchar* src = buffer+11-i;
+  while (--i >= 0)
+    *dst++ = *src++;
+  count = needed;
+  return this;
+}
+
+jboolean
+java::lang::StringBuffer::regionMatches(jint toffset, jstring other)
+{
+  jint len = other->count;
+  jchar *tptr = elements(value) + toffset;
+  jchar *optr = JvGetStringChars(other);
+  while (--len >= 0)
+    if (*tptr++ != *optr++)
+      return false;
+  return true;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natStringBuilder.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natStringBuilder.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natStringBuilder.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natStringBuilder.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,29 @@
+// Native methods for StringBuilder.
+
+/* Copyright (C) 2005  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <gcj/cni.h>
+#include <java/lang/StringBuilder.h>
+#include <java/lang/String.h>
+
+jboolean
+java::lang::StringBuilder::regionMatches(jint offset, jstring other)
+{
+  int len = other->count;
+  int index = 0;
+  jchar *sc = elements (value);
+  jchar *oc = _Jv_GetStringChars (other);
+  while (--len >= 0)
+    {
+      if (sc[offset++] != oc[index++])
+	return false;
+    }
+  return true;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natSystem.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natSystem.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natSystem.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natSystem.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,150 @@
+// natSystem.cc - Native code implementing System class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006 Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/lang/System.h>
+#include <java/lang/Class.h>
+#include <java/lang/ArrayStoreException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/io/PrintStream.h>
+#include <java/io/InputStream.h>
+
+
+
+void
+java::lang::System::setErr0 (java::io::PrintStream *newErr)
+{
+  err = newErr;
+}
+
+void
+java::lang::System::setIn0 (java::io::InputStream *newIn)
+{
+  in = newIn;
+}
+
+void
+java::lang::System::setOut0 (java::io::PrintStream *newOut)
+{
+  out = newOut;
+}
+
+void
+java::lang::System::arraycopy (jobject src, jint src_offset,
+			       jobject dst, jint dst_offset,
+			       jint count)
+{
+  if (! src || ! dst)
+    throw new NullPointerException;
+
+  jclass src_c = src->getClass();
+  jclass dst_c = dst->getClass();
+  jclass src_comp = src_c->getComponentType();
+  jclass dst_comp = dst_c->getComponentType();
+
+  if (! src_c->isArray() || ! dst_c->isArray()
+      || src_comp->isPrimitive() != dst_comp->isPrimitive()
+      || (src_comp->isPrimitive() && src_comp != dst_comp))
+    throw new ArrayStoreException;
+
+  __JArray *src_a = (__JArray *) src;
+  __JArray *dst_a = (__JArray *) dst;
+  if (src_offset < 0 || dst_offset < 0 || count < 0
+      || (unsigned jint) src_offset > (unsigned jint) src_a->length
+      || (unsigned jint) (src_offset + count) > (unsigned jint) src_a->length
+      || (unsigned jint) dst_offset > (unsigned jint) dst_a->length
+      || (unsigned jint) (dst_offset + count) > (unsigned jint) dst_a->length)
+    throw new ArrayIndexOutOfBoundsException;
+
+  // Do-nothing cases.
+  if ((src == dst && src_offset == dst_offset)
+      || ! count)
+    return;
+
+  // If both are primitive, we can optimize trivially.  If DST
+  // components are always assignable from SRC components, then we
+  // will never need to raise an error, and thus can do the
+  // optimization.  If source and destinations are the same, then we
+  // know that the assignability premise always holds.
+  const bool prim = src_comp->isPrimitive();
+  if (prim || dst_comp->isAssignableFrom(src_comp) || src == dst)
+    {
+      const size_t size = (prim ? src_comp->size()
+			   : sizeof elements((jobjectArray)src)[0]);
+
+      char *src_elts = _Jv_GetArrayElementFromElementType (src, src_comp);
+      src_elts += size * src_offset;
+
+      char *dst_elts = _Jv_GetArrayElementFromElementType (dst, dst_comp);
+      dst_elts += size * dst_offset;
+
+#if HAVE_MEMMOVE
+      // We don't bother trying memcpy.  It can't be worth the cost of
+      // the check.
+      // Don't cast to (void*), as memmove may expect (char*)
+      memmove (dst_elts, src_elts, count * size);
+#else
+      bcopy (src_elts, dst_elts, count * size);
+#endif
+    }
+  else
+    {
+      jobject *src_elts = elements ((jobjectArray) src_a) + src_offset;
+      jobject *dst_elts = elements ((jobjectArray) dst_a) + dst_offset;
+
+      for (int i = 0; i < count; ++i)
+	{
+	  if (*src_elts
+	      && ! dst_comp->isAssignableFrom((*src_elts)->getClass()))
+	    throw new ArrayStoreException;
+	  *dst_elts++ = *src_elts++;
+	}
+    }
+}
+
+jlong
+java::lang::System::currentTimeMillis (void)
+{
+  return _Jv_platform_gettimeofday ();
+}
+
+jlong
+java::lang::System::nanoTime ()
+{
+  return _Jv_platform_nanotime ();
+}
+
+jint
+java::lang::System::identityHashCode (jobject obj)
+{
+  return _Jv_HashCode (obj);
+}
+
+jstring
+java::lang::System::getenv0 (jstring name)
+{
+  jint len = _Jv_GetStringUTFLength (name);
+  char buf[len + 1];
+  jsize total = JvGetStringUTFRegion (name, 0, name->length(), buf);
+  buf[total] = '\0';
+  const char *value = ::getenv (buf);
+  if (value == NULL)
+    return NULL;
+  return JvNewStringUTF (value);
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natThread.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natThread.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natThread.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natThread.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,472 @@
+// natThread.cc - Native part of Thread class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2006  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-threads.h>
+
+#include <gnu/gcj/RawDataManaged.h>
+#include <java/lang/Thread.h>
+#include <java/lang/ThreadGroup.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IllegalThreadStateException.h>
+#include <java/lang/InterruptedException.h>
+#include <java/lang/NullPointerException.h>
+
+#include <jni.h>
+
+#ifdef ENABLE_JVMPI
+#include <jvmpi.h>
+#endif
+
+
+
+// This structure is used to represent all the data the native side
+// needs.  An object of this type is assigned to the `data' member of
+// the Thread class.
+struct natThread
+{
+  // These are used to interrupt sleep and join calls.  We can share a
+  // condition variable here since it only ever gets notified when the thread
+  // exits.
+  _Jv_Mutex_t join_mutex;
+  _Jv_ConditionVariable_t join_cond;
+
+  // This is private data for the thread system layer.
+  _Jv_Thread_t *thread;
+
+  // Each thread has its own JNI object.
+  JNIEnv *jni_env;
+};
+
+static void finalize_native (jobject ptr);
+
+// This is called from the constructor to initialize the native side
+// of the Thread.
+void
+java::lang::Thread::initialize_native (void)
+{
+  natThread *nt = (natThread *) _Jv_AllocBytes (sizeof (natThread));
+  
+  data = (gnu::gcj::RawDataManaged *) nt;
+  
+  // Register a finalizer to clean up the native thread resources.
+  _Jv_RegisterFinalizer (data, finalize_native);
+
+  _Jv_MutexInit (&nt->join_mutex);
+  _Jv_CondInit (&nt->join_cond);
+  nt->thread = _Jv_ThreadInitData (this);
+  // FIXME: if JNI_ENV is set we will want to free it.  It is
+  // malloc()d.
+  nt->jni_env = NULL;
+}
+
+static void
+finalize_native (jobject ptr)
+{
+  natThread *nt = (natThread *) ptr;
+  _Jv_ThreadDestroyData (nt->thread);
+#ifdef _Jv_HaveCondDestroy
+  _Jv_CondDestroy (&nt->join_cond);
+#endif
+#ifdef _Jv_HaveMutexDestroy
+  _Jv_MutexDestroy (&nt->join_mutex);
+#endif
+  _Jv_FreeJNIEnv(nt->jni_env);
+}
+
+jint
+java::lang::Thread::countStackFrames (void)
+{
+  // NOTE: This is deprecated in JDK 1.2.
+
+  // Old applets still call this method.  Rather than throwing
+  // UnsupportedOperationException we simply fail silently.
+
+  return 0;
+}
+
+java::lang::Thread *
+java::lang::Thread::currentThread (void)
+{
+  return _Jv_ThreadCurrent ();
+}
+
+jboolean
+java::lang::Thread::holdsLock (jobject obj)
+{
+  if (!obj)
+    throw new NullPointerException;
+  return !_Jv_ObjectCheckMonitor (obj);
+}
+
+void
+java::lang::Thread::interrupt (void)
+{
+  checkAccess ();
+  natThread *nt = (natThread *) data;
+  JvSynchronize sync (this);
+  if (alive_flag)
+    _Jv_ThreadInterrupt (nt->thread);
+}
+
+void
+java::lang::Thread::join (jlong millis, jint nanos)
+{
+  if (millis < 0 || nanos < 0 || nanos > 999999)
+    throw new IllegalArgumentException;
+
+  Thread *current = currentThread ();
+
+  // Here `NT' is the native structure for the thread we are trying to join.
+  natThread *nt = (natThread *) data;
+
+  // Now wait for: (1) an interrupt, (2) the thread to exit, or (3)
+  // the timeout to occur. 
+  _Jv_MutexLock (&nt->join_mutex);
+  if (! isAlive ())
+    {
+      _Jv_MutexUnlock (&nt->join_mutex);
+      return;
+    }
+  _Jv_CondWait (&nt->join_cond, &nt->join_mutex, millis, nanos);
+  _Jv_MutexUnlock (&nt->join_mutex);
+
+  if (current->isInterrupted (true))
+    throw new InterruptedException;
+}
+
+void
+java::lang::Thread::resume (void)
+{
+  checkAccess ();
+
+  // Old applets still call this method.  Rather than throwing
+  // UnsupportedOperationException we simply fail silently.
+}
+
+void
+java::lang::Thread::setPriority (jint newPriority)
+{
+  checkAccess ();
+  if (newPriority < MIN_PRIORITY || newPriority > MAX_PRIORITY)
+    throw new IllegalArgumentException;
+
+  jint gmax = group->getMaxPriority();
+  if (newPriority > gmax)
+    newPriority = gmax;
+
+  priority = newPriority;
+  natThread *nt = (natThread *) data;
+  _Jv_ThreadSetPriority (nt->thread, priority);
+}
+
+void
+java::lang::Thread::sleep (jlong millis, jint nanos)
+{
+  if (millis < 0 || nanos < 0 || nanos > 999999)
+    throw new IllegalArgumentException;
+
+  if (millis == 0 && nanos == 0)
+    ++nanos;
+
+  Thread *current = currentThread ();
+
+  // We use a condition variable to implement sleeping so that an
+  // interrupt can wake us up. 
+  natThread *nt = (natThread *) current->data;
+  _Jv_MutexLock (&nt->join_mutex);
+  _Jv_CondWait (&nt->join_cond, &nt->join_mutex, millis, nanos);
+  _Jv_MutexUnlock (&nt->join_mutex);
+
+  if (current->isInterrupted (true))
+    throw new InterruptedException;
+}
+
+void
+java::lang::Thread::finish_ ()
+{
+  natThread *nt = (natThread *) data;
+  
+  group->removeThread (this);
+
+#ifdef ENABLE_JVMPI  
+  if (_Jv_JVMPI_Notify_THREAD_END)
+    {
+      JVMPI_Event event;
+
+      event.event_type = JVMPI_EVENT_THREAD_END;
+      event.env_id = _Jv_GetCurrentJNIEnv ();
+
+      _Jv_DisableGC ();
+      (*_Jv_JVMPI_Notify_THREAD_END) (&event);
+      _Jv_EnableGC ();
+    }
+#endif
+
+  // If a method cache was created, free it.
+  _Jv_FreeMethodCache();
+
+  // Clear out thread locals.
+  locals = NULL;
+
+  // Signal any threads that are waiting to join() us.
+  _Jv_MutexLock (&nt->join_mutex);
+
+  {
+    JvSynchronize sync (this);
+    alive_flag = false;
+  }
+
+  _Jv_CondNotifyAll (&nt->join_cond, &nt->join_mutex);
+  _Jv_MutexUnlock (&nt->join_mutex);  
+}
+
+// Run once at thread startup, either when thread is attached or when 
+// _Jv_ThreadRun is called.
+static void
+_Jv_NotifyThreadStart (java::lang::Thread* thread)
+{
+#ifdef ENABLE_JVMPI
+      if (_Jv_JVMPI_Notify_THREAD_START)
+	{
+	  JVMPI_Event event;
+	  
+	  jstring thread_name = thread->getName ();
+	  jstring group_name = NULL, parent_name = NULL;
+	  java::lang::ThreadGroup *group = thread->getThreadGroup ();
+
+	  if (group)
+	    {
+	      group_name = group->getName ();
+	      group = group->getParent ();
+	      
+	      if (group)
+		parent_name = group->getName ();
+	    }
+	  
+	  int thread_len = thread_name ? JvGetStringUTFLength (thread_name) : 0;
+	  int group_len = group_name ? JvGetStringUTFLength (group_name) : 0;
+	  int parent_len = parent_name ? JvGetStringUTFLength (parent_name) : 0;
+	  
+	  char thread_chars[thread_len + 1];
+	  char group_chars[group_len + 1];
+	  char parent_chars[parent_len + 1];
+	  
+	  if (thread_name)
+	    JvGetStringUTFRegion (thread_name, 0, 
+				  thread_name->length(), thread_chars);
+	  if (group_name)
+	    JvGetStringUTFRegion (group_name, 0, 
+				  group_name->length(), group_chars);
+	  if (parent_name)
+	    JvGetStringUTFRegion (parent_name, 0, 
+				  parent_name->length(), parent_chars);
+	  
+	  thread_chars[thread_len] = '\0';
+	  group_chars[group_len] = '\0';
+	  parent_chars[parent_len] = '\0';
+	  
+	  event.event_type = JVMPI_EVENT_THREAD_START;
+	  event.env_id = NULL;
+	  event.u.thread_start.thread_name = thread_chars;
+	  event.u.thread_start.group_name = group_chars;
+	  event.u.thread_start.parent_name = parent_chars;
+	  event.u.thread_start.thread_id = (jobjectID) thread;
+	  event.u.thread_start.thread_env_id = _Jv_GetCurrentJNIEnv ();
+	  
+	  _Jv_DisableGC ();
+	  (*_Jv_JVMPI_Notify_THREAD_START) (&event);
+	  _Jv_EnableGC ();
+	}
+#endif
+}
+
+void
+_Jv_ThreadRun (java::lang::Thread* thread)
+{
+  try
+    {
+      _Jv_NotifyThreadStart (thread);
+      thread->run ();
+    }
+  catch (java::lang::Throwable *t)
+    {
+      // Uncaught exceptions are forwarded to the ThreadGroup.  If
+      // this results in an uncaught exception, that is ignored.
+      try
+	{
+	  thread->group->uncaughtException (thread, t);
+	}
+      catch (java::lang::Throwable *f)
+	{
+	  // Nothing.
+	}
+    }
+
+  thread->finish_ ();
+}
+
+_Jv_Thread_t*
+_Jv_ThreadGetData (java::lang::Thread* thread)
+{
+  natThread* nt = (natThread*) thread->data;
+  return nt->thread;
+}
+
+void
+java::lang::Thread::start (void)
+{
+  JvSynchronize sync (this);
+
+  // Its illegal to re-start() a thread, even if its dead.
+  if (!startable_flag)
+    throw new IllegalThreadStateException;
+
+  alive_flag = true;
+  startable_flag = false;
+  natThread *nt = (natThread *) data;
+  _Jv_ThreadStart (this, nt->thread, (_Jv_ThreadStartFunc *) &_Jv_ThreadRun);
+}
+
+void
+java::lang::Thread::stop (java::lang::Throwable *)
+{
+  checkAccess ();
+
+  // Old applets still call this method.  Rather than throwing
+  // UnsupportedOperationException we simply fail silently.
+}
+
+void
+java::lang::Thread::suspend (void)
+{
+  checkAccess ();
+
+  // Old applets still call this method.  Rather than throwing
+  // UnsupportedOperationException we simply fail silently.
+}
+
+static int nextThreadNumber = 0;
+
+jstring
+java::lang::Thread::gen_name (void)
+{
+  jint i;
+  jclass sync = &java::lang::Thread::class$;
+  {
+    JvSynchronize dummy(sync); 
+    i = ++nextThreadNumber;
+  }
+
+  // Use an array large enough for "-2147483648"; i.e. 11 chars, + "Thread-".
+  jchar buffer[7+11];
+  jchar *bufend = (jchar *) ((char *) buffer + sizeof(buffer));
+  i = _Jv_FormatInt (bufend, i);
+  jchar *ptr = bufend - i;
+  // Prepend "Thread-".
+  *--ptr = '-';
+  *--ptr = 'd';
+  *--ptr = 'a';
+  *--ptr = 'e';
+  *--ptr = 'r';
+  *--ptr = 'h';
+  *--ptr = 'T';
+  return JvNewString (ptr, bufend - ptr);
+}
+
+void
+java::lang::Thread::yield (void)
+{
+  _Jv_ThreadYield ();
+}
+
+JNIEnv *
+_Jv_GetCurrentJNIEnv ()
+{
+  java::lang::Thread *t = _Jv_ThreadCurrent ();
+  if (t == NULL)
+    return NULL;
+  return ((natThread *) t->data)->jni_env;
+}
+
+void
+_Jv_SetCurrentJNIEnv (JNIEnv *env)
+{
+  java::lang::Thread *t = _Jv_ThreadCurrent ();
+  JvAssert (t != NULL);
+  ((natThread *) t->data)->jni_env = env;
+}
+
+// Attach the current native thread to an existing (but unstarted) Thread 
+// object. Does not register thread with the garbage collector.
+// Returns -1 on failure, 0 upon success.
+jint
+_Jv_AttachCurrentThread(java::lang::Thread* thread)
+{
+  JvSynchronize sync (thread);
+  if (thread == NULL || thread->startable_flag == false)
+    return -1;
+  thread->startable_flag = false;
+  thread->alive_flag = true;
+  natThread *nt = (natThread *) thread->data;
+  _Jv_ThreadRegister (nt->thread);
+  return 0;
+}
+
+java::lang::Thread*
+_Jv_AttachCurrentThread(jstring name, java::lang::ThreadGroup* group)
+{
+  // Register thread with GC before attempting any allocations.
+  _Jv_GCAttachThread ();
+  java::lang::Thread *thread = _Jv_ThreadCurrent ();
+  if (thread != NULL)
+    return thread;
+  if (name == NULL)
+    name = java::lang::Thread::gen_name ();
+  thread = new java::lang::Thread (NULL, group, NULL, name);
+  _Jv_AttachCurrentThread (thread);
+  _Jv_NotifyThreadStart (thread);
+  return thread;
+}
+
+java::lang::Thread*
+_Jv_AttachCurrentThreadAsDaemon(jstring name, java::lang::ThreadGroup* group)
+{
+  java::lang::Thread *thread = _Jv_ThreadCurrent ();
+  if (thread != NULL)
+    return thread;
+  if (name == NULL)
+    name = java::lang::Thread::gen_name ();
+  thread = new java::lang::Thread (NULL, group, NULL, name);
+  thread->setDaemon (true);
+  _Jv_AttachCurrentThread (thread);
+  _Jv_NotifyThreadStart (thread);
+  return thread;
+}
+
+jint
+_Jv_DetachCurrentThread (void)
+{
+  java::lang::Thread *t = _Jv_ThreadCurrent ();
+  if (t == NULL)
+    return -1;
+
+  _Jv_ThreadUnRegister ();
+  _Jv_GCDetachThread ();
+  // Release the monitors.
+  t->finish_ ();
+
+  return 0;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natVMClassLoader.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natVMClassLoader.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natVMClassLoader.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natVMClassLoader.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,230 @@
+// natVMClassLoader.cc - VMClassLoader native methods
+
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+/* Author: Kresten Krab Thorup <krab at gnu.org>  */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java-threads.h>
+#include <java-interp.h>
+
+#include <java/lang/VMClassLoader.h>
+#include <java/lang/VMCompiler.h>
+#include <gnu/gcj/runtime/ExtensionClassLoader.h>
+#include <gnu/gcj/runtime/SystemClassLoader.h>
+#include <gnu/gcj/runtime/BootClassLoader.h>
+#include <java/lang/ClassLoader.h>
+#include <java/lang/Class.h>
+#include <java/lang/Throwable.h>
+#include <java/security/ProtectionDomain.h>
+#include <java/lang/ClassFormatError.h>
+#include <java/lang/StringBuffer.h>
+#include <java/lang/Runtime.h>
+#include <java/util/HashSet.h>
+#include <java/lang/VirtualMachineError.h>
+
+java::lang::Class *
+java::lang::VMClassLoader::defineClass (java::lang::ClassLoader *loader,
+					jstring name,
+					jbyteArray data, 
+					jint offset,
+					jint length,
+					java::security::ProtectionDomain *pd)
+{
+  jclass klass = VMCompiler::compileClass(loader, name, data,
+					  offset, length, pd);
+
+#ifdef INTERPRETER
+  if (klass == NULL)
+    {
+      klass = new java::lang::Class ();
+
+      // Synchronize on the class, so that it is not attempted initialized
+      // until we're done loading.
+      JvSynchronize sync (klass);
+
+      // Record the defining loader.  For the bootstrap class loader,
+      // we record NULL.
+      if (loader != bootLoader)
+	klass->loader = loader;
+
+      if (name != 0)
+	{
+	  _Jv_Utf8Const *name2 = _Jv_makeUtf8Const (name);
+
+	  if (! _Jv_VerifyClassName (name2))
+	    throw new java::lang::ClassFormatError
+	      (JvNewStringLatin1 ("erroneous class name"));
+
+	  klass->name = name2;
+	}
+
+      _Jv_Utf8Const *found_name = NULL;
+      try
+	{
+	  _Jv_DefineClass (klass, data, offset, length, pd, &found_name);
+	}
+      catch (java::lang::Throwable *ex)
+	{
+	  klass->state = JV_STATE_ERROR;
+	  klass->notifyAll ();
+
+	  if (found_name != NULL)
+	    _Jv_UnregisterInitiatingLoader (klass, klass->loader);
+
+	  // If EX is not a ClassNotFoundException, that's ok, because we
+	  // account for the possibility in defineClass().
+	  throw ex;
+	}
+
+      // if everything proceeded sucessfully, we're loaded.
+      JvAssert (klass->state == JV_STATE_LOADED);
+    }
+#endif // INTERPRETER
+
+  if (! klass)
+    {
+      StringBuffer *sb = new StringBuffer();
+      if (name)
+	{
+	  sb->append(JvNewStringLatin1("found class file for class "));
+	  sb->append(name);
+	}
+      else
+	sb->append(JvNewStringLatin1("found unnamed class file"));
+      sb->append(JvNewStringLatin1(", but no interpreter configured in this libgcj"));
+      throw new VirtualMachineError(sb->toString());
+    }
+
+  return klass;
+}
+
+java::lang::ClassLoader *
+java::lang::VMClassLoader::getSystemClassLoaderInternal()
+{
+  _Jv_InitClass (&gnu::gcj::runtime::ExtensionClassLoader::class$);
+  _Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::ExtensionClassLoader::system_instance);
+  return gnu::gcj::runtime::ExtensionClassLoader::system_instance;
+}
+
+jclass
+java::lang::VMClassLoader::getPrimitiveClass (jchar type)
+{
+  char sig[2];
+  sig[0] = (char) type;
+  sig[1] = '\0';
+  // Note: this cannot return NULL, since the input is always correct.
+  return _Jv_FindClassFromSignature (sig, NULL);
+}
+
+void
+java::lang::VMClassLoader::initBootLoader(jstring libdir)
+{
+  bootLoader = new gnu::gcj::runtime::BootClassLoader(libdir);
+}
+
+jclass
+java::lang::VMClassLoader::nativeFindClass (jstring name)
+{
+  jclass klass = NULL;
+
+  if (lib_control != LIB_NEVER)
+    {
+      // Turn `gnu.pkg.quux' into `lib-gnu-pkg-quux'.  Then search for
+      // a module named (eg, on Linux) `lib-gnu-pkg-quux.so', followed
+      // by `lib-gnu-pkg.so' and `lib-gnu.so'.  If loading one of
+      // these causes the class to appear in the cache, then use it.
+      java::lang::StringBuffer *sb
+	= new java::lang::StringBuffer (JvNewStringLatin1("lib-"));
+      // Skip inner classes
+      jstring cn;
+      jint ci = name->indexOf('$');
+      if (ci == -1)
+	cn = name;
+      else
+	cn = name->substring (0, ci);
+      jstring so_base_name
+	= (sb->append (cn)->toString ())->replace ('.', '-');
+
+      using namespace ::java::lang;
+      Runtime *rt = Runtime::getRuntime();
+
+      _Jv_Utf8Const *name_u = NULL;
+
+      // Compare against `3' because that is the length of "lib".
+      while (! klass && so_base_name && so_base_name->length() > 3)
+	{
+	  if (lib_control == LIB_CACHE)
+	    {
+	      // If we've already tried this name, we're done.
+	      if (tried_libraries->contains(so_base_name))
+		break;
+	      tried_libraries->add(so_base_name);
+	    }
+
+	  jboolean loaded = rt->loadLibraryInternal (so_base_name);
+
+	  jint nd = so_base_name->lastIndexOf ('-');
+	  if (nd == -1)
+	    so_base_name = NULL;
+	  else
+	    so_base_name = so_base_name->substring (0, nd);
+
+	  if (loaded)
+	    {
+	      if (name_u == NULL)
+		name_u = _Jv_makeUtf8Const (name);
+	      klass = _Jv_FindClassInCache (name_u);
+	    }
+	}
+    }
+
+  if (klass)
+    definePackageForNative(name);
+
+  return klass;
+}
+
+jclass
+java::lang::VMClassLoader::loadClass(jstring name, jboolean resolve)
+{
+  // We try the boot loader first, so that the endorsed directory
+  // overrides compiled-in classes.
+  jclass klass = NULL;
+  if (bootLoader)
+    klass = bootLoader->bootLoadClass(name);
+  if (! klass)
+    {
+      _Jv_Utf8Const *utf = _Jv_makeUtf8Const (name);
+      klass = _Jv_FindClassInCache (utf);
+    }
+  if (! klass)
+    klass = nativeFindClass(name);
+  if (klass)
+    {
+      // We never want to return a class without its supers linked.
+      // It isn't clear from the spec, but this is what other
+      // implementations do in practice.
+      if (resolve)
+	resolveClass (klass);
+      else
+	_Jv_Linker::wait_for_state (klass, JV_STATE_LOADING);
+
+      definePackageForNative(name);
+    }
+
+  return klass;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natVMSecurityManager.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natVMSecurityManager.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natVMSecurityManager.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natVMSecurityManager.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,29 @@
+/* Copyright (C) 2002  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+// Written by Tom Tromey <tromey at redhat.com>
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-stack.h>
+
+#include <java/lang/VMSecurityManager.h>
+#include <java/lang/SecurityManager.h>
+#include <java/lang/ClassLoader.h>
+#include <java/lang/Class.h>
+
+JArray<jclass> *
+java::lang::VMSecurityManager::getClassContext (jclass klass)
+{
+  JArray<jclass> *result = 
+    _Jv_StackTrace::GetClassContext (klass);
+
+  return result;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natVMThrowable.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natVMThrowable.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natVMThrowable.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natVMThrowable.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,45 @@
+// natVMThrowable.cc - Native part of VMThrowable class.
+
+/* Copyright (C) 2003, 2006 Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-stack.h>
+
+#include <java/lang/Throwable.h>
+#include <java/lang/VMThrowable.h>
+
+using namespace gnu::gcj;
+
+java::lang::VMThrowable *
+java::lang::VMThrowable::fillInStackTrace (java::lang::Throwable *)
+{
+  using namespace java::lang;
+
+  // Don't trace stack during initialization of the runtime.
+  if (! gcj::runtimeInitialized)
+    return NULL;
+  
+  _Jv_StackTrace *trace = _Jv_StackTrace::GetStackTrace ();
+  VMThrowable *vmthrowable = new VMThrowable ();
+  vmthrowable->data = (RawDataManaged *) trace;
+  return vmthrowable;
+}
+
+
+JArray< ::java::lang::StackTraceElement *> *
+java::lang::VMThrowable::getStackTrace (java::lang::Throwable *throwable)
+{
+  _Jv_StackTrace *trace = reinterpret_cast <_Jv_StackTrace *> (data);
+  return _Jv_StackTrace::GetStackTraceElements (trace, throwable);
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/natWin32Process.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/natWin32Process.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/natWin32Process.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/natWin32Process.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,351 @@
+// natWin32Process.cc - Native side of Win32 process code.
+
+/* Copyright (C) 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+// Conflicts with the definition in "java/lang/reflect/Modifier.h"
+#undef STRICT
+
+#include <java/lang/ConcreteProcess.h>
+#include <java/lang/IllegalThreadStateException.h>
+#include <java/lang/InterruptedException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Thread.h>
+#include <java/io/File.h>
+#include <java/io/FileDescriptor.h>
+#include <java/io/FileInputStream.h>
+#include <java/io/FileOutputStream.h>
+#include <java/io/IOException.h>
+#include <java/lang/OutOfMemoryError.h>
+#include <gnu/java/nio/channels/FileChannelImpl.h>
+
+using gnu::java::nio::channels::FileChannelImpl;
+
+void
+java::lang::ConcreteProcess::cleanup (void)
+{
+  // FIXME:
+  // We used to close the input, output and
+  // error streams here, but we can't do that
+  // because the caller also has the right
+  // to close these and FileInputStream and FileOutputStream
+  // scream if you attempt to close() them twice. Presently,
+  // we use _Jv_platform_close_on_exec, which is similar
+  // to the POSIX approach.
+  //
+  // What I wanted to do is have private nested
+  // classes in ConcreteProcess which extend FileInputStream
+  // and FileOutputStream, respectively, but override
+  // close() to permit multiple calls to close(). This
+  // led to class header and platform configury issues
+  // that I didn't feel like dealing with. However,
+  // this approach could conceivably be a good multiplatform
+  // one since delaying the pipe close until process
+  // termination could be wasteful if many child processes
+  // are spawned within the parent process' lifetime.
+  inputStream = NULL;
+  outputStream = NULL;
+  errorStream = NULL;
+  
+  if (procHandle)
+    {
+      CloseHandle((HANDLE) procHandle);
+      procHandle = (jint) INVALID_HANDLE_VALUE;
+    }
+}
+
+void
+java::lang::ConcreteProcess::destroy (void)
+{
+  if (! hasExited ())
+    {
+      // Kill it forcibly and assign an (arbitrary) exit code of 0.
+      TerminateProcess ((HANDLE) procHandle, 0);
+      exitCode = 0;
+
+      cleanup ();
+    }
+}
+
+jboolean
+java::lang::ConcreteProcess::hasExited (void)
+{
+  DWORD exitStatus;
+
+  if (GetExitCodeProcess ((HANDLE) procHandle, &exitStatus) != 0)
+    {
+      // NOTE: STILL_ACTIVE is defined as "259" by Win32 - if the
+      // child actually exits with this return code, we have a
+      // problem here. See MSDN documentation on GetExitCodeProcess( ).
+
+      if (exitStatus == STILL_ACTIVE)
+        return false;
+      else
+        {
+          cleanup ();
+          exitCode = exitStatus;
+          return true;
+        }
+    }
+  else
+    return true;
+}
+
+jint
+java::lang::ConcreteProcess::waitFor (void)
+{
+  if (! hasExited ())
+    {
+      DWORD exitStatus = 0UL;
+
+      // Set up our waitable objects array
+      // - 0: the handle to the process we just launched
+      // - 1: our thread's interrupt event
+      HANDLE arh[2];
+      arh[0] = (HANDLE) procHandle;
+      arh[1] = _Jv_Win32GetInterruptEvent ();
+      DWORD rval = WaitForMultipleObjects (2, arh, 0, INFINITE);
+
+      // Use the returned value from WaitForMultipleObjects
+      // instead of our thread's interrupt_flag to test for
+      // thread interruption. See the comment for
+      // _Jv_Win32GetInterruptEvent().
+      bool bInterrupted = rval == (WAIT_OBJECT_0 + 1);
+      
+      if (bInterrupted)
+        {
+          // Querying this forces a reset our thread's interrupt flag.
+          Thread::interrupted();
+          
+          cleanup ();
+          throw new InterruptedException ();
+        }
+
+      GetExitCodeProcess ((HANDLE) procHandle, &exitStatus);
+      exitCode = exitStatus;
+
+      cleanup ();
+    }
+
+  return exitCode;
+}
+
+
+// Helper class for creating and managing the pipes
+// used for I/O redirection for child processes.
+class ChildProcessPipe
+{
+public:
+  // Indicates from the child process' point of view
+  // whether the pipe is for reading or writing.
+  enum EType {INPUT, OUTPUT};
+
+  ChildProcessPipe(EType eType);
+  ~ChildProcessPipe();
+  
+  // Returns a pipe handle suitable for use by the parent process
+  HANDLE getParentHandle();
+  
+  // Returns a pipe handle suitable for use by the child process.
+  HANDLE getChildHandle();
+  
+private:
+  EType m_eType;
+  HANDLE m_hRead, m_hWrite;
+};
+
+ChildProcessPipe::ChildProcessPipe(EType eType):
+  m_eType(eType)
+{
+  SECURITY_ATTRIBUTES sAttrs;
+
+  // Explicitly allow the handles to the pipes to be inherited.
+  sAttrs.nLength = sizeof (SECURITY_ATTRIBUTES);
+  sAttrs.bInheritHandle = 1;
+  sAttrs.lpSecurityDescriptor = NULL;
+
+  if (CreatePipe (&m_hRead, &m_hWrite, &sAttrs, 0) == 0)
+    {
+      DWORD dwErrorCode = GetLastError ();
+      throw new java::io::IOException (
+        _Jv_WinStrError (_T("Error creating pipe"), dwErrorCode));
+    }
+
+  // If this is the read end of the child, we need
+  // to make the parent write end non-inheritable. Similarly,
+  // if this is the write end of the child, we need to make
+  // the parent read end non-inheritable. If we didn't
+  // do this, the child would inherit these ends and we wouldn't
+  // be able to close them from our end. For full details,
+  // do a Google search on "Q190351".
+  HANDLE& rhStd = m_eType==INPUT ? m_hWrite : m_hRead;
+  _Jv_platform_close_on_exec (rhStd);
+}
+
+ChildProcessPipe::~ChildProcessPipe()
+{
+  // Close the parent end of the pipe. This
+  // destructor is called after the child process
+  // has been spawned.
+  CloseHandle(getChildHandle());
+}
+
+HANDLE ChildProcessPipe::getParentHandle()
+{
+  return m_eType==INPUT ? m_hWrite : m_hRead;
+}
+
+HANDLE ChildProcessPipe::getChildHandle()
+{
+  return m_eType==INPUT ? m_hRead : m_hWrite;
+}
+
+void
+java::lang::ConcreteProcess::startProcess (jstringArray progarray,
+                                           jstringArray envp,
+                                           java::io::File *dir)
+{
+  using namespace java::io;
+
+  procHandle = (jint) INVALID_HANDLE_VALUE;
+
+  // Reconstruct the command line.
+  jstring *elts = elements (progarray);
+
+  int cmdLineLen = 0;
+
+  for (int i = 0; i < progarray->length; ++i)
+    cmdLineLen += (elts[i]->length() + 1);
+
+  LPTSTR cmdLine = (LPTSTR) _Jv_Malloc ((cmdLineLen + 1) * sizeof(TCHAR));
+  LPTSTR cmdLineCurPos = cmdLine;
+
+  for (int i = 0; i < progarray->length; ++i)
+    {
+      if (i > 0)
+        *cmdLineCurPos++ = _T(' ');
+        
+      jint len = elts[i]->length();
+      JV_TEMP_STRING_WIN32(thiselt, elts[i]);
+      _tcscpy(cmdLineCurPos, thiselt);
+      cmdLineCurPos += len;
+    }
+  *cmdLineCurPos = _T('\0');
+
+  // Get the environment, if any. Unconditionally
+  // create a UNICODE environment, even on ANSI
+  // builds.
+  LPWSTR env = NULL;
+  if (envp)
+    {
+      elts = elements (envp);
+
+      int envLen = 0;
+      for (int i = 0; i < envp->length; ++i)
+        envLen += (elts[i]->length() + 1);
+
+      env = (LPWSTR) _Jv_Malloc ((envLen + 1) * sizeof(WCHAR));
+
+      int j = 0;
+      for (int i = 0; i < envp->length; ++i)
+        {
+          jstring elt = elts[i];
+          jint len = elt->length();
+          
+          wcsncpy(env + j, (LPCWSTR) JvGetStringChars(elt), len);
+          
+          j += len;
+          
+          // Insert the null terminator and skip past it.
+          env[j++] = 0;
+        }
+      *(env + j) = 0;
+    }
+
+  // Get the working directory path, if specified.
+  JV_TEMP_STRING_WIN32 (wdir, dir ? dir->getPath () : 0);
+
+  errorStream = NULL;
+  inputStream = NULL;
+  outputStream = NULL;
+
+  java::lang::Throwable *exc = NULL;
+
+  try
+    {
+      // We create anonymous pipes to communicate with the child
+      // on each of standard streams.
+      ChildProcessPipe aChildStdIn(ChildProcessPipe::INPUT);
+      ChildProcessPipe aChildStdOut(ChildProcessPipe::OUTPUT);
+      ChildProcessPipe aChildStdErr(ChildProcessPipe::OUTPUT);
+
+      outputStream = new FileOutputStream (new FileChannelImpl (
+                           (jint) aChildStdIn.getParentHandle (),
+			   FileChannelImpl::WRITE));
+      inputStream = new FileInputStream (new FileChannelImpl (
+                           (jint) aChildStdOut.getParentHandle (),
+			   FileChannelImpl::READ));
+      errorStream = new FileInputStream (new FileChannelImpl (
+                           (jint) aChildStdErr.getParentHandle (),
+			   FileChannelImpl::READ));
+
+      // Now create the child process.
+      PROCESS_INFORMATION pi;
+      STARTUPINFO si;
+
+      ZeroMemory (&pi, sizeof (PROCESS_INFORMATION));
+
+      ZeroMemory (&si, sizeof (STARTUPINFO));
+      si.cb = sizeof (STARTUPINFO);
+
+      // Explicitly specify the handles to the standard streams.
+      si.dwFlags |= STARTF_USESTDHANDLES;
+
+      si.hStdInput = aChildStdIn.getChildHandle();
+      si.hStdOutput = aChildStdOut.getChildHandle();
+      si.hStdError = aChildStdErr.getChildHandle();
+
+      // Spawn the process. CREATE_NO_WINDOW only applies when
+      // starting a console application; it suppresses the
+      // creation of a console window. This flag is ignored on
+      // Win9X.
+      
+      if (CreateProcess (NULL,
+                         cmdLine,
+                         NULL,
+                         NULL,
+                         1,
+                         CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
+                         env,
+                         wdir,
+                         &si,
+                         &pi) == 0)
+        {
+          DWORD dwErrorCode = GetLastError ();
+          throw new IOException (
+            _Jv_WinStrError (_T("Error creating child process"), dwErrorCode));
+        }
+
+      procHandle = (jint ) pi.hProcess;
+
+      _Jv_Free (cmdLine);
+      if (env != NULL)
+        _Jv_Free (env);
+    }
+  catch (java::lang::Throwable *thrown)
+    {
+      cleanup ();
+      exc = thrown;
+    }
+
+  if (exc != NULL)
+    throw exc;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/ref/Reference.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/ref/Reference.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/ref/Reference.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/ref/Reference.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,210 @@
+/* java.lang.ref.Reference
+   Copyright (C) 1999, 2002, 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.lang.ref;
+
+/**
+ * This is the base class of all references.  A reference allows
+ * refering to an object without preventing the garbage collector to
+ * collect it.  The only way to get the referred object is via the
+ * <code>get()</code>-method.  This method will return
+ * <code>null</code> if the object was collected. <br>
+ *
+ * A reference may be registered with a queue.  When a referred
+ * element gets collected the reference will be put on the queue, so
+ * that you will be notified. <br>
+ *
+ * There are currently three types of references:  soft reference,
+ * weak reference and phantom reference. <br>
+ *
+ * Soft references will be cleared if the garbage collector is told
+ * to free some memory and there are no unreferenced or weakly referenced
+ * objects.  It is useful for caches. <br>
+ *
+ * Weak references will be cleared as soon as the garbage collector
+ * determines that the refered object is only weakly reachable.  They
+ * are useful as keys in hashtables (see <code>WeakHashtable</code>) as
+ * you get notified when nobody has the key anymore.
+ *
+ * Phantom references don't prevent finalization.  If an object is only
+ * phantom reachable, it will be finalized, and the reference will be
+ * enqueued, but not cleared.  Since you mustn't access an finalized
+ * object, the <code>get</code> method of a phantom reference will never
+ * work.  It is useful to keep track, when an object is finalized.
+ *
+ * @author Jochen Hoenicke
+ * @see java.util.WeakHashtable
+ */
+public abstract class Reference
+{
+  /**
+   * The underlying object.  This field is handled in a special way by
+   * the garbage collector.
+   * GCJ LOCAL:
+   * This is a RawData because it must be disguised from the GC.
+   * END GCJ LOCAL
+   */
+  gnu.gcj.RawData referent;
+
+  /**
+   * This is like REFERENT but is not scanned by the GC.  We keep a
+   * copy around so that we can clean up our internal data structure
+   * even after clear() is called.
+   * GCJ LOCAL:
+   * This field doesn't exist in Classpath.
+   * END GCJ LOCAL
+   */
+  gnu.gcj.RawData copy;
+
+  /**
+   * Set to true if {@link #clear()} is called.
+   * GCJ LOCAL:
+   * This field doesn't exist in Classpath.  It is used internally in
+   * natReference.cc, which enqueues the reference unless it is true
+   * (has been cleared).
+   * END GCJ LOCAL
+   */
+  boolean cleared = false;
+
+  /**
+   * The queue this reference is registered on. This is null, if this
+   * wasn't registered to any queue or reference was already enqueued.
+   */
+  ReferenceQueue queue;
+
+  /**
+   * Link to the next entry on the queue.  If this is null, this
+   * reference is not enqueued.  Otherwise it points to the next
+   * reference.  The last reference on a queue will point to itself
+   * (not to null, that value is used to mark a not enqueued
+   * reference).  
+   */
+  Reference nextOnQueue;
+
+  /**
+   * This lock should be taken by the garbage collector, before
+   * determining reachability.  It will prevent the get()-method to
+   * return the reference so that reachability doesn't change.
+   */
+  static Object lock = new Object();
+
+  /**
+   * Creates a new reference that is not registered to any queue.
+   * Since it is package private, it is not possible to overload this
+   * class in a different package.  
+   * @param referent the object we refer to.
+   */
+  Reference(Object ref)
+  {
+    create (ref);
+  }
+
+  /**
+   * Creates a reference that is registered to a queue.  Since this is
+   * package private, it is not possible to overload this class in a
+   * different package.  
+   * @param referent the object we refer to.
+   * @param q the reference queue to register on.
+   * @exception NullPointerException if q is null.
+   */
+  Reference(Object ref, ReferenceQueue q)
+  {
+    if (q == null)
+      throw new NullPointerException();
+    queue = q;
+    create (ref);
+  }
+
+  /**
+   * Notifies the VM that a new Reference has been created.
+   */
+  private native void create (Object o);
+
+  /**
+   * Returns the object, this reference refers to.
+   * @return the object, this reference refers to, or null if the 
+   * reference was cleared.
+   */
+  public Object get()
+  {
+    synchronized (lock)
+      {
+	return referent;
+      }
+  }
+
+  /**
+   * Clears the reference, so that it doesn't refer to its object
+   * anymore.  For soft and weak references this is called by the
+   * garbage collector.  For phantom references you should call 
+   * this when enqueuing the reference.
+   */
+  public void clear()
+  {
+    // Must synchronize so changes are visible in finalizer thread.
+    synchronized (lock)
+      {
+        referent = null;
+        cleared = true;
+      }
+  }
+
+  /**
+   * Tells if the object is enqueued on a reference queue.
+   * @return true if it is enqueued, false otherwise.
+   */
+  public boolean isEnqueued()
+  {
+    return nextOnQueue != null;
+  }
+
+  /**
+   * Enqueue an object on a reference queue.  This is normally executed
+   * by the garbage collector.
+   */
+  public boolean enqueue() 
+  {
+    if (queue != null && nextOnQueue == null)
+      {
+	queue.enqueue(this);
+	queue = null;
+	return true;
+      }
+    return false;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/ref/natReference.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/ref/natReference.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/ref/natReference.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/ref/natReference.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,370 @@
+// natReference.cc - Native code for References
+
+/* Copyright (C) 2001, 2002, 2003, 2005  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+// Written by Tom Tromey <tromey at redhat.com>
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/lang/Throwable.h>
+#include <java/lang/ref/Reference.h>
+#include <java/lang/ref/SoftReference.h>
+#include <java/lang/ref/WeakReference.h>
+#include <java/lang/ref/PhantomReference.h>
+#include <java/lang/ref/ReferenceQueue.h>
+
+static void finalize_reference (jobject ref);
+static void finalize_referred_to_object (jobject obj);
+
+
+
+enum weight
+{
+  SOFT = 0,
+  WEAK = 1,
+  FINALIZE = 2,
+  PHANTOM = 3,
+
+  // This is used to mark the head of a list.
+  HEAD = 4,
+
+  // This is used to mark a deleted item.
+  DELETED = 5
+};
+
+// Objects of this type are used in the hash table to keep track of
+// the mapping between a finalizable object and the various References
+// which refer to it.
+struct object_list
+{
+  // The reference object.  This is NULL for FINALIZE weight.
+  jobject reference;
+
+  // The weight of this object.
+  enum weight weight;
+
+  // Next in list.
+  object_list *next;
+};
+
+// Hash table used to hold mapping from object to References.  The
+// object_list item in the hash holds the object itself in the
+// reference field; chained to it are all the references sorted in
+// order of weight (lowest first).
+static object_list *hash = NULL;
+
+// Number of slots used in HASH.
+static int hash_count = 0;
+
+// Number of slots total in HASH.  Must be power of 2.
+static int hash_size = 0;
+
+#define DELETED_REFERENCE  ((jobject) -1)
+
+static object_list *
+find_slot (jobject key)
+{
+  jint hcode = _Jv_HashCode (key);
+  /* step must be non-zero, and relatively prime with hash_size. */
+  jint step = (hcode ^ (hcode >> 16)) | 1;
+  int start_index = hcode & (hash_size - 1);
+  int index = start_index;
+  int deleted_index = -1;
+  do
+    {
+      object_list *ptr = &hash[index];
+      if (ptr->reference == key)
+	return ptr;
+      else if (ptr->reference == NULL)
+	{
+	  if (deleted_index == -1)
+	    return ptr;
+	  else
+	    return &hash[deleted_index];
+	}
+      else if (ptr->weight == DELETED)
+	{
+	  deleted_index = index;
+	  JvAssert (ptr->reference == DELETED_REFERENCE);
+	}
+      index = (index + step) & (hash_size - 1);
+    }
+  while (index != start_index);
+  // Note that we can have INDEX == START_INDEX if the table has no
+  // NULL entries but does have DELETED entries.
+  JvAssert (deleted_index >= 0);
+  return &hash[deleted_index];
+}
+
+static void
+rehash ()
+{
+  if (hash == NULL)
+    {
+      hash_size = 1024;
+      hash = (object_list *) _Jv_Malloc (hash_size * sizeof (object_list));
+      memset (hash, 0, hash_size * sizeof (object_list));
+    }
+  else
+    {
+      object_list *old = hash;
+      int i = hash_size;
+
+      hash_size *= 2;
+      hash = (object_list *) _Jv_Malloc (hash_size * sizeof (object_list));
+      memset (hash, 0, hash_size * sizeof (object_list));
+
+      while (--i >= 0)
+	{
+	  if (old[i].reference == NULL || old[i].weight == DELETED)
+	    continue;
+	  object_list *newslot = find_slot (old[i].reference);
+	  *newslot = old[i];
+	}
+
+      _Jv_Free (old);
+    }
+}
+
+// Remove a Reference.
+static void
+remove_from_hash (jobject obj)
+{
+  java::lang::ref::Reference *ref
+    = reinterpret_cast<java::lang::ref::Reference *> (obj);
+  object_list *head = find_slot (ref->copy);
+
+  // We might have found a new slot.  We can just ignore that here.
+  if (head->reference != ref->copy)
+    return;
+
+  object_list **link = &head->next;
+  head = head->next;
+
+  while (head && head->reference != ref)
+    {
+      link = &head->next;
+      head = head->next;
+    }
+
+  // Remove the slot.
+  if (head)
+    {
+      *link = head->next;
+      _Jv_Free (head);
+    }
+}
+
+// Return list head if object is in hash, NULL otherwise.
+object_list *
+in_hash (jobject obj)
+{
+  // The hash table might not yet be initialized.
+  if (hash == NULL)
+    return NULL;
+  object_list *head = find_slot (obj);
+  if (head->reference != obj)
+    return NULL;
+  return head;
+}
+
+// FIXME what happens if an object's finalizer creates a Reference to
+// the object, and the object has never before been added to the hash?
+// Madness!
+
+// Add an item to the hash table.  If the item is new, we also add a
+// finalizer item.  We keep items in the hash table until they are
+// completely collected; this lets us know when an item is new, even
+// if it has been resurrected after its finalizer has been run.
+static void
+add_to_hash (java::lang::ref::Reference *the_reference)
+{
+  JvSynchronize sync (java::lang::ref::Reference::lock);
+
+  if (3 * hash_count >= 2 * hash_size)
+    rehash ();
+
+  // Use `copy' here because the `referent' field has been cleared.
+  jobject referent = the_reference->copy;
+  object_list *item = find_slot (referent);
+  if (item->reference == NULL || item->reference == DELETED_REFERENCE)
+    {
+      // New item, so make an entry for the finalizer.
+      item->reference = referent;
+      item->weight = HEAD;
+
+      item->next = (object_list *) _Jv_Malloc (sizeof (object_list));
+      item->next->reference = NULL;
+      item->next->weight = FINALIZE;
+      item->next->next = NULL;
+      ++hash_count;
+    }
+
+  object_list *n = (object_list *) _Jv_Malloc (sizeof (object_list));
+  n->reference = the_reference;
+
+  enum weight w = PHANTOM;
+  if (java::lang::ref::SoftReference::class$.isInstance (the_reference))
+    w = SOFT;
+  else if (java::lang::ref::WeakReference::class$.isInstance (the_reference))
+    w = WEAK;
+  n->weight = w;
+
+  object_list **link = &item->next;
+  object_list *iter = *link;
+  while (iter && iter->weight < n->weight)
+    {
+      link = &iter->next;
+      iter = *link;
+    }
+  n->next = *link;
+  *link = n;
+}
+
+// Add a FINALIZE entry if one doesn't exist.
+static void
+maybe_add_finalize (object_list *entry, jobject obj)
+{
+  object_list **link = &entry->next;
+  object_list *iter = *link;
+  while (iter && iter->weight < FINALIZE)
+    {
+      link = &iter->next;
+      iter = *link;
+    }
+
+  // We want at most one FINALIZE entry in the queue.
+  if (iter && iter->weight == FINALIZE)
+    return;
+
+  object_list *n = (object_list *) _Jv_Malloc (sizeof (object_list));
+  n->reference = obj;
+  n->weight = FINALIZE;
+  n->next = *link;
+  *link = n;
+}
+
+// This is called when an object is ready to be finalized.  This
+// actually implements the appropriate Reference semantics.
+static void
+finalize_referred_to_object (jobject obj)
+{
+  JvSynchronize sync (java::lang::ref::Reference::lock);
+
+  object_list *list = find_slot (obj);
+  object_list *head = list->next;
+  if (head == NULL)
+    {
+      // We have a truly dead object: the object's finalizer has been
+      // run, all the object's references have been processed, and the
+      // object is unreachable.  There is, at long last, no way to
+      // resurrect it.
+      list->reference = DELETED_REFERENCE;
+      list->weight = DELETED;
+      --hash_count;
+      return;
+    }
+
+  enum weight w = head->weight;
+  if (w == FINALIZE)
+    {
+      // Update the list first, as _Jv_FinalizeString might end up
+      // looking at this data structure.
+      list->next = head->next;
+      _Jv_Free (head);
+
+      // If we have a Reference A to a Reference B, and B is
+      // finalized, then we have to take special care to make sure
+      // that B is properly deregistered.  This is super gross.  FIXME
+      // will it fail if B's finalizer resurrects B?
+      if (java::lang::ref::Reference::class$.isInstance (obj))
+	finalize_reference (obj);
+      else if (obj->getClass() == &java::lang::String::class$)
+	_Jv_FinalizeString (obj);
+      else
+	_Jv_FinalizeObject (obj);
+    }
+  else if (w != SOFT || _Jv_GCCanReclaimSoftReference (obj))
+    {
+      // If we just decided to reclaim a soft reference, we might as
+      // well do all the weak references at the same time.
+      if (w == SOFT)
+	w = WEAK;
+
+      while (head && head->weight <= w)
+	{
+	  java::lang::ref::Reference *ref
+	    = reinterpret_cast<java::lang::ref::Reference *> (head->reference);
+	  if (! ref->cleared)
+	    ref->enqueue ();
+
+	  object_list *next = head->next;
+	  _Jv_Free (head);
+	  head = next;
+	}
+      list->next = head;
+    }
+
+  // Re-register this finalizer.  We always re-register because we
+  // can't know until the next collection cycle whether or not the
+  // object is truly unreachable.
+  _Jv_RegisterFinalizer (obj, finalize_referred_to_object);
+}
+
+// This is called when a Reference object is finalized.  If there is a
+// Reference pointing to this Reference then that case is handled by
+// finalize_referred_to_object.
+static void
+finalize_reference (jobject ref)
+{
+  JvSynchronize sync (java::lang::ref::Reference::lock);
+  remove_from_hash (ref);
+  // The user might have a subclass of Reference with a finalizer.
+  _Jv_FinalizeObject (ref);
+}
+
+void
+_Jv_RegisterStringFinalizer (jobject str)
+{
+  // This function might be called before any other Reference method,
+  // so we must ensure the class is initialized.
+  _Jv_InitClass (&java::lang::ref::Reference::class$);
+  JvSynchronize sync (java::lang::ref::Reference::lock);
+  // If the object is in our hash table, then we might need to add a
+  // new FINALIZE entry.  Otherwise, we just register an ordinary
+  // finalizer.
+  object_list *entry = in_hash (str);
+  if (entry)
+    maybe_add_finalize (entry, str);
+  else
+    _Jv_RegisterFinalizer ((void *) str, _Jv_FinalizeString);
+}
+
+void
+::java::lang::ref::Reference::create (jobject ref)
+{
+  // Nothing says you can't make a Reference with a NULL referent.
+  // But there's nothing to do in such a case.
+  referent = reinterpret_cast<gnu::gcj::RawData *> (ref);
+  copy = referent;
+  if (referent != NULL)
+    {
+      JvSynchronize sync (java::lang::ref::Reference::lock);
+      // `this' is a new Reference object.  We register a new
+      // finalizer for pointed-to object and we arrange a special
+      // finalizer for ourselves as well.
+      _Jv_RegisterFinalizer (this, finalize_reference);
+      _Jv_RegisterFinalizer (referent, finalize_referred_to_object);
+      gnu::gcj::RawData **p = &referent;
+     _Jv_GCRegisterDisappearingLink ((jobject *) p);
+      add_to_hash (this);
+    }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Array.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Array.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Array.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Array.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,458 @@
+/* java.lang.reflect.Array - manipulate arrays by reflection
+   Copyright (C) 1998, 1999, 2001, 2003, 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.classpath.Configuration;
+
+/**
+ * Array holds static helper functions that allow you to create and
+ * manipulate arrays by reflection. Operations know how to perform widening
+ * conversions, but throw {@link IllegalArgumentException} if you attempt
+ * a narrowing conversion. Also, when accessing primitive arrays, this
+ * class performs object wrapping and unwrapping as necessary.<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. Note also that the shorthand <code>Object[].class</code>
+ * is a convenient way to get array Classes.<p>
+ *
+ * <B>Performance note:</B> This class performs best when it does not have
+ * to convert primitive types.  The further along the chain it has to convert,
+ * the worse performance will be.  You're best off using the array as whatever
+ * type it already is, and then converting the result.  You will do even
+ * worse if you do this and use the generic set() function.
+ *
+ * @author John Keiser
+ * @author Eric Blake (ebb9 at email.byu.edu)
+ * @author Per Bothner (bothner at cygnus.com)
+ * @see java.lang.Boolean#TYPE
+ * @see java.lang.Byte#TYPE
+ * @see java.lang.Short#TYPE
+ * @see java.lang.Character#TYPE
+ * @see java.lang.Integer#TYPE
+ * @see java.lang.Long#TYPE
+ * @see java.lang.Float#TYPE
+ * @see java.lang.Double#TYPE
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Array
+{
+  static
+  {
+    if (Configuration.INIT_LOAD_LIBRARY)
+      {
+        System.loadLibrary("javalangreflect");
+      }
+  }
+
+  /**
+   * This class is uninstantiable.
+   */
+  private Array()
+  {
+  }
+
+  /**
+   * Creates a new single-dimensioned array.
+   * @param componentType the type of the array to create
+   * @param length the length of the array to create
+   * @return the created array, cast to an Object
+   * @throws NullPointerException if <code>componentType</code> is null
+   * @throws IllegalArgumentException if <code>componentType</code> is
+   *         <code>Void.TYPE</code>
+   * @throws NegativeArraySizeException when length is less than 0
+   * @throws OutOfMemoryError if memory allocation fails
+   */
+  public static native Object newInstance(Class componentType, int length);
+
+  /**
+   * Creates a new multi-dimensioned array.  The new array has the same
+   * component type as the argument class, and the number of dimensions
+   * in the new array is the sum of the dimensions of the argument class
+   * and the length of the argument dimensions. Virtual Machine limitations
+   * forbid too many dimensions (usually 255 is the maximum); but even
+   * 50 dimensions of 2 elements in each dimension would exceed your memory
+   * long beforehand!
+   *
+   * @param componentType the type of the array to create.
+   * @param dimensions the dimensions of the array to create.  Each element
+   *        in <code>dimensions</code> makes another dimension of the new
+   *        array.  Thus, <code>Array.newInstance(java.lang.Boolean,
+   *        new int[]{1,2,3})</code> is the same as
+   *        <code>new java.lang.Boolean[1][2][3]</code>
+   * @return the created array, cast to an Object
+   * @throws NullPointerException if componentType or dimension is null
+   * @throws IllegalArgumentException if the the size of
+   *         <code>dimensions</code> is 0 or exceeds the maximum number of
+   *         array dimensions in the VM; or if componentType is Void.TYPE
+   * @throws NegativeArraySizeException when any of the dimensions is less
+   *         than 0
+   * @throws OutOfMemoryError if memory allocation fails
+   */
+  public static native Object newInstance(Class elementType, int[] dimensions);
+
+  /**
+   * Gets the array length.
+   * @param array the array
+   * @return the length of the array
+   * @throws IllegalArgumentException if <code>array</code> is not an array
+   * @throws NullPointerException if <code>array</code> is null
+   */
+  public static native int getLength(Object array);
+
+  /**
+   * Gets an element of an array.  Primitive elements will be wrapped in
+   * the corresponding class type.
+   *
+   * @param array the array to access
+   * @param index the array index to access
+   * @return the element at <code>array[index]</code>
+   * @throws IllegalArgumentException if <code>array</code> is not an array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #getBoolean(Object, int)
+   * @see #getByte(Object, int)
+   * @see #getChar(Object, int)
+   * @see #getShort(Object, int)
+   * @see #getInt(Object, int)
+   * @see #getLong(Object, int)
+   * @see #getFloat(Object, int)
+   * @see #getDouble(Object, int)
+   */
+  public static native Object get(Object array, int index);
+
+  /**
+   * Gets an element of a boolean array.
+   *
+   * @param array the array to access
+   * @param index the array index to access
+   * @return the boolean element at <code>array[index]</code>
+   * @throws IllegalArgumentException  if <code>array</code> is not a boolean
+   *         array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #get(Object, int)
+   */
+  public static native boolean getBoolean(Object array, int index);
+  
+  /**
+   * Gets an element of a byte array.
+   *
+   * @param array the array to access
+   * @param index the array index to access
+   * @return the byte element at <code>array[index]</code>
+   * @throws IllegalArgumentException  if <code>array</code> is not a byte
+   *         array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #get(Object, int)
+   */
+  public static native byte getByte(Object array, int index);
+
+  /**
+   * Gets an element of a char array.
+   *
+   * @param array the array to access
+   * @param index the array index to access
+   * @return the char element at <code>array[index]</code>
+   * @throws IllegalArgumentException  if <code>array</code> is not a char
+   *         array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #get(Object, int)
+   */
+  public static native char getChar(Object array, int index);
+
+  /**
+   * Gets an element of a short array.
+   *
+   * @param array the array to access
+   * @param index the array index to access
+   * @return the short element at <code>array[index]</code>
+   * @throws IllegalArgumentException  if <code>array</code> is not a byte
+   *         or char array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #get(Object, int)
+   */
+  public static native short getShort(Object array, int index);
+
+  /**
+   * Gets an element of an int array.
+   *
+   * @param array the array to access
+   * @param index the array index to access
+   * @return the int element at <code>array[index]</code>
+   * @throws IllegalArgumentException  if <code>array</code> is not a byte,
+   *         char, short, or int array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #get(Object, int)
+   */
+  public static native int getInt(Object array, int index);
+
+  /**
+   * Gets an element of a long array.
+   *
+   * @param array the array to access
+   * @param index the array index to access
+   * @return the long element at <code>array[index]</code>
+   * @throws IllegalArgumentException  if <code>array</code> is not a byte,
+   *         char, short, int, or long array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #get(Object, int)
+   */
+  public static native long getLong(Object array, int index);
+
+  /**
+   * Gets an element of a float array.
+   *
+   * @param array the array to access
+   * @param index the array index to access
+   * @return the float element at <code>array[index]</code>
+   * @throws IllegalArgumentException  if <code>array</code> is not a byte,
+   *         char, short, int, long, or float array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #get(Object, int)
+   */
+  public static native float getFloat(Object array, int index);
+
+  /**
+   * Gets an element of a double array.
+   *
+   * @param array the array to access
+   * @param index the array index to access
+   * @return the double element at <code>array[index]</code>
+   * @throws IllegalArgumentException  if <code>array</code> is not a byte,
+   *         char, short, int, long, float, or double array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #get(Object, int)
+   */
+  public static native double getDouble(Object array, int index);
+
+  private static native Class getElementType(Object array, int index);
+
+  private static native void set(Object array, int index,
+				  Object value, Class elType);
+
+  /**
+   * Sets an element of an array. If the array is primitive, then the new
+   * value is unwrapped and widened.
+   *
+   * @param array the array to set a value of
+   * @param index the array index to set the value to
+   * @param value the value to set
+   * @throws IllegalArgumentException if <code>array</code> is not an array,
+   *         or the array is primitive and unwrapping value fails, or the
+   *         value is not assignable to the array component type
+   * @throws NullPointerException if array is null, or if array is primitive
+   *         and value is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #setBoolean(Object, int, boolean)
+   * @see #setByte(Object, int, byte)
+   * @see #setChar(Object, int, char)
+   * @see #setShort(Object, int, short)
+   * @see #setInt(Object, int, int)
+   * @see #setLong(Object, int, long)
+   * @see #setFloat(Object, int, float)
+   * @see #setDouble(Object, int, double)
+   */
+  public static void set(Object array, int index, Object value)
+  {
+    Class elType = getElementType(array, index);
+    if (! elType.isPrimitive())
+      set(array, index, value, elType);
+    else if (value instanceof Byte)
+      setByte(array, index, ((Byte) value).byteValue());
+    else if (value instanceof Short)
+      setShort(array, index, ((Short) value).shortValue());
+    else if (value instanceof Integer)
+      setInt(array, index, ((Integer) value).intValue());
+    else if (value instanceof Long)
+      setLong(array, index, ((Long) value).longValue());
+    else if (value instanceof Float)
+      setFloat(array, index, ((Float) value).floatValue());
+    else if (value instanceof Double)
+      setDouble(array, index, ((Double) value).doubleValue());
+    else if (value instanceof Character)
+      setChar(array, index, ((Character) value).charValue());
+    else if (value instanceof Boolean)
+      setBoolean(array, index, ((Boolean) value).booleanValue());
+    else
+      throw new IllegalArgumentException();
+  }
+
+  /**
+   * Sets an element of a boolean array.
+   *
+   * @param array the array to set a value of
+   * @param index the array index to set the value to
+   * @param value the value to set
+   * @throws IllegalArgumentException if <code>array</code> is not a boolean
+   *         array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #set(Object, int, Object)
+   */
+  public static native void setBoolean(Object array, int index, boolean value);
+
+  /**
+   * Sets an element of a byte array.
+   *
+   * @param array the array to set a value of
+   * @param index the array index to set the value to
+   * @param value the value to set
+   * @throws IllegalArgumentException if <code>array</code> is not a byte,
+   *         short, int, long, float, or double array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #set(Object, int, Object)
+   */
+  public static native void setByte(Object array, int index, byte value);
+
+  /**
+   * Sets an element of a char array.
+   *
+   * @param array the array to set a value of
+   * @param index the array index to set the value to
+   * @param value the value to set
+   * @throws IllegalArgumentException if <code>array</code> is not a char,
+   *         int, long, float, or double array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #set(Object, int, Object)
+   */
+  public static native void setChar(Object array, int index, char value);
+
+  /**
+   * Sets an element of a short array.
+   *
+   * @param array the array to set a value of
+   * @param index the array index to set the value to
+   * @param value the value to set
+   * @throws IllegalArgumentException if <code>array</code> is not a short,
+   *         int, long, float, or double array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #set(Object, int, Object)
+   */
+  public static native void setShort(Object array, int index, short value);
+
+  /**
+   * Sets an element of an int array.
+   *
+   * @param array the array to set a value of
+   * @param index the array index to set the value to
+   * @param value the value to set
+   * @throws IllegalArgumentException if <code>array</code> is not an int,
+   *         long, float, or double array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #set(Object, int, Object)
+   */
+  public static native void setInt(Object array, int index, int value);
+
+  /**
+   * Sets an element of a long array.
+   *
+   * @param array the array to set a value of
+   * @param index the array index to set the value to
+   * @param value the value to set
+   * @throws IllegalArgumentException if <code>array</code> is not a long,
+   *         float, or double array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #set(Object, int, Object)
+   */
+  public static native void setLong(Object array, int index, long value);
+
+  /**
+   * Sets an element of a float array.
+   *
+   * @param array the array to set a value of
+   * @param index the array index to set the value to
+   * @param value the value to set
+   * @throws IllegalArgumentException if <code>array</code> is not a float
+   *         or double array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #set(Object, int, Object)
+   */
+  public static native void setFloat(Object array, int index, float value);
+
+  /**
+   * Sets an element of a double array.
+   *
+   * @param array the array to set a value of
+   * @param index the array index to set the value to
+   * @param value the value to set
+   * @throws IllegalArgumentException if <code>array</code> is not a double
+   *         array
+   * @throws NullPointerException if <code>array</code> is null
+   * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+   *         bounds
+   * @see #set(Object, int, Object)
+   */
+  public static native void setDouble(Object array, int index, double value);
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Constructor.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Constructor.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Constructor.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Constructor.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,398 @@
+/* java.lang.reflect.Constructor - reflection of Java constructors
+   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+ 
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.java.lang.reflect.MethodSignatureParser;
+
+/**
+ * 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 at email.byu.edu>
+ * @author Tom Tromey <tromey at redhat.com>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getConstructor(Class[])
+ * @see java.lang.Class#getDeclaredConstructor(Class[])
+ * @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, GenericDeclaration
+{
+  private static final int CONSTRUCTOR_MODIFIERS
+    = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
+
+  /**
+   * This class is uninstantiable except from native code.
+   */
+  private Constructor ()
+  {
+  }
+
+  /**
+   * Gets the class that declared this constructor.
+   * @return the class that declared this member
+   */
+  public Class getDeclaringClass()
+  {
+    return declaringClass;
+  }
+
+  /**
+   * 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 declaringClass.getName();
+  }
+
+  /**
+   * Return the raw modifiers for this constructor.  In particular
+   * this will include the synthetic and varargs bits.
+   * @return the constructor's modifiers
+   */
+  private native int getModifiersInternal();
+
+  /**
+   * 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 int getModifiers ()
+  {
+    return getModifiersInternal() & CONSTRUCTOR_MODIFIERS;
+  }
+
+  /**
+   * Return true if this constructor is synthetic, false otherwise.
+   * A synthetic member is one which is created by the compiler,
+   * and which does not appear in the user's source code.
+   * @since 1.5
+   */
+  public boolean isSynthetic()
+  {
+    return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+  }
+
+  /**
+   * Return true if this is a varargs constructor, that is if
+   * the constructor takes a variable number of arguments.
+   * @since 1.5
+   */
+  public boolean isVarArgs()
+  {
+    return (getModifiersInternal() & Modifier.VARARGS) != 0;
+  }
+
+  /**
+   * 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 Class[] getParameterTypes ()
+  {
+    if (parameter_types == null)
+      getType ();
+    return (Class[]) parameter_types.clone();
+  }
+
+  /**
+   * 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 Class[] getExceptionTypes ()
+  {
+    if (exception_types == null)
+      getType();
+    return (Class[]) exception_types.clone();
+  }
+
+  /**
+   * 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.
+   *
+   * @param o the object to compare to
+   * @return <code>true</code> if they are equal; <code>false</code> if not.
+   */
+  public boolean equals (Object obj)
+  {
+    if (! (obj instanceof Constructor))
+      return false;
+    Constructor c = (Constructor) obj;
+    return declaringClass == c.declaringClass && offset == c.offset;
+  }
+
+  /**
+   * 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 declaringClass.getName().hashCode();
+  }
+
+  /**
+   * Get a String representation of the Constructor. A Constructor's String
+   * representation is "<modifier> <classname>(<paramtypes>)
+   * throws <exceptions>", 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()
+  {
+    if (parameter_types == null)
+      getType ();
+    StringBuffer b = new StringBuffer ();
+    int mods = getModifiers();
+    if (mods != 0)
+      {
+	Modifier.toString(mods, b);
+	b.append(" ");
+      }
+    Method.appendClassName (b, declaringClass);
+    b.append("(");
+    for (int i = 0; i < parameter_types.length; ++i)
+      {
+	Method.appendClassName (b, parameter_types[i]);
+	if (i < parameter_types.length - 1)
+	  b.append(",");
+      }
+    b.append(")");
+    return b.toString();
+  }
+
+  /* FIXME[GENERICS]: Add X extends GenericDeclaration and TypeVariable<X> */
+  static void addTypeParameters(StringBuilder sb, TypeVariable[] typeArgs)
+  {
+    if (typeArgs.length == 0)
+      return;
+    sb.append('<');
+    for (int i = 0; i < typeArgs.length; ++i)
+      {
+        if (i > 0)
+          sb.append(',');
+        sb.append(typeArgs[i]);
+      }
+    sb.append("> ");
+  }
+
+  public String toGenericString()
+  {
+    StringBuilder sb = new StringBuilder(128);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    addTypeParameters(sb, getTypeParameters());
+    sb.append(getDeclaringClass().getName()).append('(');
+    Type[] types = getGenericParameterTypes();
+    if (types.length > 0)
+      {
+        sb.append(types[0]);
+        for (int i = 1; i < types.length; ++i)
+          sb.append(',').append(types[i]);
+      }
+    sb.append(')');
+    types = getGenericExceptionTypes();
+    if (types.length > 0)
+      {
+        sb.append(" throws ").append(types[0]);
+        for (int i = 1; i < types.length; i++)
+          sb.append(',').append(types[i]);
+      }
+    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 native Object newInstance (Object[] args)
+    throws InstantiationException, IllegalAccessException,
+    IllegalArgumentException, InvocationTargetException;
+
+  /**
+   * Returns an array of <code>TypeVariable</code> objects that represents
+   * the type variables declared by this constructor, in declaration order.
+   * An array of size zero is returned if this constructor has no type
+   * variables.
+   *
+   * @return the type variables associated with this constructor.
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  /* FIXME[GENERICS]: Add <Constructor<T>> */
+  public TypeVariable[] getTypeParameters()
+  {
+    String sig = getSignature();
+    if (sig == null)
+      return new TypeVariable[0];
+    MethodSignatureParser p = new MethodSignatureParser(this, sig);
+    return p.getTypeParameters();
+  }
+
+  /**
+   * Return the String in the Signature attribute for this constructor. If there
+   * is no Signature attribute, return null.
+   */
+  private String getSignature()
+  {
+    // FIXME: libgcj doesn't record this information yet.
+    return null;
+  }
+
+  /**
+   * Returns an array of <code>Type</code> objects that represents
+   * the exception types declared by this constructor, in declaration order.
+   * An array of size zero is returned if this constructor declares no
+   * exceptions.
+   *
+   * @return the exception types declared by this constructor. 
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type[] getGenericExceptionTypes()
+  {
+    String sig = getSignature();
+    if (sig == null)
+      return getExceptionTypes();
+    MethodSignatureParser p = new MethodSignatureParser(this, sig);
+    return p.getGenericExceptionTypes();
+  }
+
+  /**
+   * Returns an array of <code>Type</code> objects that represents
+   * the parameter list for this constructor, in declaration order.
+   * An array of size zero is returned if this constructor takes no
+   * parameters.
+   *
+   * @return a list of the types of the constructor's parameters
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type[] getGenericParameterTypes()
+  {
+    String sig = getSignature();
+    if (sig == null)
+      return getParameterTypes();
+    MethodSignatureParser p = new MethodSignatureParser(this, sig);
+    return p.getGenericParameterTypes();
+  }
+
+  // Update cached values from method descriptor in class.
+  private native void getType ();
+
+  // Declaring class.
+  private Class declaringClass;
+
+  // Exception types.
+  private Class[] exception_types;
+  // Parameter types.
+  private Class[] parameter_types;
+
+  // Offset in bytes from the start of declaringClass's methods array.
+  private int offset;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Field.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Field.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Field.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Field.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,801 @@
+/* java.lang.reflect.Field - reflection of Java fields
+   Copyright (C) 1998, 2001, 2005, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+ 
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.java.lang.ClassHelper;
+
+import gnu.java.lang.reflect.FieldSignatureParser;
+
+/**
+ * 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 at email.byu.edu>
+ * @author Per Bothner <bothner at cygnus.com>
+ * @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;
+
+  // Offset in bytes from the start of declaringClass's fields array.
+  private int offset;
+
+  // The Class (or primitive TYPE) of this field.
+  private Class type;
+
+  private static final int FIELD_MODIFIERS
+    = Modifier.FINAL | Modifier.PRIVATE | Modifier.PROTECTED
+      | Modifier.PUBLIC | Modifier.STATIC | Modifier.TRANSIENT
+      | Modifier.VOLATILE;
+
+  // This is instantiated by Class sometimes, but it uses C++ and
+  // avoids the Java protection check.
+  Field ()
+  {
+  }
+
+  /**
+   * 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 native String getName();
+
+  /**
+   * Return the raw modifiers for this field.
+   * @return the field's modifiers
+   */
+  private native int getModifiersInternal();
+
+  /**
+   * 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 int getModifiers()
+  {
+    return getModifiersInternal() & FIELD_MODIFIERS;
+  }
+
+  /**
+   * Return true if this field is synthetic, false otherwise.
+   * @since 1.5
+   */
+  public boolean isSynthetic()
+  {
+    return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+  }
+
+  /**
+   * Return true if this field represents an enum constant,
+   * false otherwise.
+   * @since 1.5
+   */
+  public boolean isEnumConstant()
+  {
+    return (getModifiersInternal() & Modifier.ENUM) != 0;
+  }
+
+  /**
+   * 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 fld)
+  {
+    if (! (fld instanceof Field))
+      return false;
+    Field f = (Field) fld;
+    return declaringClass == f.declaringClass && offset == f.offset;
+  }
+
+  /**
+   * 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 "<modifiers> <type>
+   * <class>.<fieldname>".<br> Example:
+   * <code>public transient boolean gnu.parse.Parser.parseComplete</code>
+   *
+   * @return the String representation of the Field
+   */
+  public String toString ()
+  {
+    StringBuffer sbuf = new StringBuffer ();
+    int mods = getModifiers();
+    if (mods != 0)
+      {
+	Modifier.toString(mods, sbuf);
+	sbuf.append(' ');
+      }
+    Method.appendClassName (sbuf, getType ());
+    sbuf.append(' ');
+    Method.appendClassName (sbuf, getDeclaringClass());
+    sbuf.append('.');
+    sbuf.append(getName());
+    return sbuf.toString();
+  }
+
+  public String toGenericString()
+  {
+    StringBuilder sb = new StringBuilder(64);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    sb.append(getGenericType()).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 Object get(Object obj)
+    throws IllegalAccessException
+  {
+    return get(null, obj);
+  }
+
+  /**
+   * 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 boolean getBoolean(Object obj)
+    throws IllegalAccessException
+  {
+    return getBoolean(null, obj);
+  }
+
+  /**
+   * 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 byte getByte(Object obj)
+    throws IllegalAccessException
+  {
+    return getByte(null, obj);
+  }
+
+  /**
+   * 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 char getChar(Object obj)
+    throws IllegalAccessException
+  {
+    return getChar(null, obj);
+  }
+
+  /**
+   * 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 short getShort(Object obj)
+    throws IllegalAccessException
+  {
+    return getShort(null, obj);
+  }
+
+  /**
+   * 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 int getInt(Object obj)
+    throws IllegalAccessException
+  {
+    return getInt(null, obj);
+  }
+
+  /**
+   * 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 long getLong(Object obj)
+    throws IllegalAccessException
+  {
+    return getLong(null, obj);
+  }
+
+  /**
+   * 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 float getFloat(Object obj)
+    throws IllegalAccessException
+  {
+    return getFloat(null, obj);
+  }
+
+  /**
+   * 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 double getDouble(Object obj)
+    throws IllegalAccessException
+  {
+    return getDouble(null, obj);
+  }
+
+  private native boolean getBoolean (Class caller, Object obj)
+    throws IllegalArgumentException, IllegalAccessException;
+
+  private native char getChar (Class caller, Object obj)
+    throws IllegalArgumentException, IllegalAccessException;
+
+  private native byte getByte (Class caller, Object obj)
+    throws IllegalArgumentException, IllegalAccessException;
+
+  private native short getShort (Class caller, Object obj)
+    throws IllegalArgumentException, IllegalAccessException;
+
+  private native int getInt (Class caller, Object obj)
+    throws IllegalArgumentException, IllegalAccessException;
+
+  private native long getLong (Class caller, Object obj)
+    throws IllegalArgumentException, IllegalAccessException;
+
+  private native float getFloat (Class caller, Object obj)
+    throws IllegalArgumentException, IllegalAccessException;
+
+  private native double getDouble (Class caller, Object obj)
+    throws IllegalArgumentException, IllegalAccessException;
+
+  private native Object get (Class caller, Object obj)
+    throws IllegalArgumentException, 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 void set(Object object, Object value)
+    throws IllegalAccessException
+  {
+    set(null, object, value);
+  }
+
+  /**
+   * 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 void setBoolean(Object obj, boolean b)
+    throws IllegalAccessException
+  {
+    setBoolean(null, obj, b, true);
+  }
+
+  /**
+   * 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 void setByte(Object obj, byte b)
+    throws IllegalAccessException
+  {
+    setByte(null, obj, b, true);
+  }
+
+  /**
+   * 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 void setChar(Object obj, char c)
+    throws IllegalAccessException
+  {
+    setChar(null, obj, c, true);
+  }
+
+  /**
+   * 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 void setShort(Object obj,  short s)
+    throws IllegalAccessException
+  {
+    setShort(null, obj, s, true);
+  }
+
+  /**
+   * 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 void setInt(Object obj, int i)
+    throws IllegalAccessException
+  {
+    setInt(null, obj, i, true);
+  }
+
+  /**
+   * 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 void setLong(Object obj, long l)
+    throws IllegalArgumentException, IllegalAccessException
+  {
+    setLong(null, obj, l, true);
+  }
+
+  /**
+   * 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 void setFloat(Object obj, float f)
+    throws IllegalAccessException
+  {
+    setFloat(null, obj, f, true);
+  }
+
+  /**
+   * 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 void setDouble(Object obj, double d)
+    throws IllegalAccessException
+  {
+    setDouble(null, obj, d, true);
+  }
+
+  /**
+   * Return the generic type of the field. If the field type is not a generic
+   * type, the method returns the same as <code>getType()</code>.
+   *
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type getGenericType()
+  {
+    String signature = getSignature();
+    if (signature == null)
+      return getType();
+    FieldSignatureParser p = new FieldSignatureParser(getDeclaringClass(),
+                                                      signature);
+    return p.getFieldType();
+  }
+
+  /**
+   * Return the String in the Signature attribute for this field. If there
+   * is no Signature attribute, return null.
+   */
+  private String getSignature()
+  {
+    // FIXME: libgcj doesn't record Signature attributes yet.
+    return null;
+  }
+
+  native void setByte (Class caller, Object obj, byte b, boolean checkFinal)
+    throws IllegalArgumentException, IllegalAccessException;
+
+  native void setShort (Class caller, Object obj, short s, boolean checkFinal)
+    throws IllegalArgumentException, IllegalAccessException;
+
+  native void setInt (Class caller, Object obj, int i, boolean checkFinal)  
+    throws IllegalArgumentException, IllegalAccessException;
+
+  native void setLong (Class caller, Object obj, long l, boolean checkFinal)
+    throws IllegalArgumentException, IllegalAccessException;
+
+  native void setFloat (Class caller, Object obj, float f, boolean checkFinal)
+    throws IllegalArgumentException, IllegalAccessException;
+
+  native void setDouble (Class caller, Object obj, double d,
+			 boolean checkFinal)
+    throws IllegalArgumentException, IllegalAccessException;
+
+  native void setChar (Class caller, Object obj, char c, boolean checkFinal)
+    throws IllegalArgumentException, IllegalAccessException;
+
+  native void setBoolean (Class caller, Object obj, boolean b,
+			  boolean checkFinal)
+    throws IllegalArgumentException, IllegalAccessException;
+
+  native void set (Class caller, Object obj, Object val, Class type, 
+		   boolean checkFinal)
+    throws IllegalArgumentException, IllegalAccessException;
+
+  private void set (Class caller, Object object, Object value)
+    throws IllegalArgumentException, IllegalAccessException
+  {
+    Class type = getType();
+    if (! type.isPrimitive())
+      set(caller, object, value, type, true);
+    else if (value instanceof Byte)
+      setByte(caller, object, ((Byte) value).byteValue(), true);
+    else if (value instanceof Short)
+      setShort (caller, object, ((Short) value).shortValue(), true);
+    else if (value instanceof Integer)
+      setInt(caller, object, ((Integer) value).intValue(), true);
+    else if (value instanceof Long)
+      setLong(caller, object, ((Long) value).longValue(), true);
+    else if (value instanceof Float)
+      setFloat(caller, object, ((Float) value).floatValue(), true);
+    else if (value instanceof Double)
+      setDouble(caller, object, ((Double) value).doubleValue(), true);
+    else if (value instanceof Character)
+      setChar(caller, object, ((Character) value).charValue(), true);
+    else if (value instanceof Boolean)
+      setBoolean(caller, object, ((Boolean) value).booleanValue(), true);
+    else
+      throw new IllegalArgumentException();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Method.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Method.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Method.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Method.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,444 @@
+// Method.java - Represent method of class or interface.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+ 
+package java.lang.reflect;
+
+import gnu.gcj.RawData;
+import gnu.java.lang.reflect.MethodSignatureParser;
+
+/**
+ * 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 at email.byu.edu>
+ * @author Tom Tromey <tromey at redhat.com>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getMethod(String,Class[])
+ * @see java.lang.Class#getDeclaredMethod(String,Class[])
+ * @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, GenericDeclaration
+{
+  private static final int METHOD_MODIFIERS
+    = Modifier.ABSTRACT | Modifier.FINAL | Modifier.NATIVE
+      | Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC
+      | Modifier.STATIC | Modifier.STRICT | Modifier.SYNCHRONIZED;
+
+  /**
+   * This class is uninstantiable.
+   */
+  private Method ()
+  {
+  }
+
+  /**
+   * 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 native String getName ();
+
+  /**
+   * Return the raw modifiers for this method.
+   * @return the method's modifiers
+   */
+  private native int getModifiersInternal();
+
+  /**
+   * 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 int getModifiers()
+  {
+    return getModifiersInternal() & METHOD_MODIFIERS;
+  }
+
+  /**
+   * Return true if this method is a bridge method.  A bridge method
+   * is generated by the compiler in some situations involving
+   * generics and inheritance.
+   * @since 1.5
+   */
+  public boolean isBridge()
+  {
+    return (getModifiersInternal() & Modifier.BRIDGE) != 0;
+  }
+
+  /**
+   * Return true if this method is synthetic, false otherwise.
+   * @since 1.5
+   */
+  public boolean isSynthetic()
+  {
+    return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+  }
+
+  /**
+   * Return true if this is a varargs method, that is if
+   * the method takes a variable number of arguments.
+   * @since 1.5
+   */
+  public boolean isVarArgs()
+  {
+    return (getModifiersInternal() & Modifier.VARARGS) != 0;
+  }
+
+  /**
+   * Gets the return type of this method.
+   * @return the type of this method
+   */
+  public Class getReturnType ()
+  {
+    if (return_type == null)
+      getType();
+    return return_type;
+  }
+
+  /**
+   * 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 Class[] getParameterTypes ()
+  {
+    if (parameter_types == null)
+      getType();
+    return (Class[]) parameter_types.clone();
+  }
+
+  /**
+   * 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 Class[] getExceptionTypes ()
+  {
+    if (exception_types == null)
+      getType();
+    return (Class[]) exception_types.clone();
+  }
+
+  /**
+   * Compare two objects to see if they are semantically equivalent.
+   * Two Methods are semantically equivalent if they have the same declaring
+   * class, name, and parameter list.  This ignores different exception
+   * clauses or return types.
+   *
+   * @param o the object to compare to
+   * @return <code>true</code> if they are equal; <code>false</code> if not
+   */
+  public boolean equals (Object obj)
+  {
+    if (! (obj instanceof Method))
+      return false;
+    Method m = (Method) obj;
+    return declaringClass == m.declaringClass && offset == m.offset;
+  }
+
+  /**
+   * 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 "<modifiers> <returntype>
+   * <methodname>(<paramtypes>) throws <exceptions>", 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()
+  {
+    if (parameter_types == null)
+      getType ();
+
+    StringBuffer b = new StringBuffer ();
+    int mods = getModifiers();
+    if (mods != 0)
+      {
+	Modifier.toString(mods, b);
+	b.append(" ");
+      }
+    appendClassName (b, return_type);
+    b.append(" ");
+    appendClassName (b, declaringClass);
+    b.append(".");
+    b.append(getName());
+    b.append("(");
+    for (int i = 0; i < parameter_types.length; ++i)
+      {
+	appendClassName (b, parameter_types[i]);
+	if (i < parameter_types.length - 1)
+	  b.append(",");
+      }
+    b.append(")");
+    if (exception_types.length > 0)
+      {
+	b.append(" throws ");
+	for (int i = 0; i < exception_types.length; ++i)
+	  {
+	    appendClassName (b, exception_types[i]);
+	    if (i < exception_types.length - 1)
+	      b.append(",");
+	  }
+      }
+    return b.toString();
+  }
+
+  public String toGenericString()
+  {
+    // 128 is a reasonable buffer initial size for constructor
+    StringBuilder sb = new StringBuilder(128);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    Constructor.addTypeParameters(sb, getTypeParameters());
+    sb.append(getGenericReturnType()).append(' ');
+    sb.append(getDeclaringClass().getName()).append('.');
+    sb.append(getName()).append('(');
+    Type[] types = getGenericParameterTypes();
+    if (types.length > 0)
+      {
+        sb.append(types[0]);
+        for (int i = 1; i < types.length; i++)
+          sb.append(',').append(types[i]);
+      }
+    sb.append(')');
+    types = getGenericExceptionTypes();
+    if (types.length > 0)
+      {
+        sb.append(" throws ").append(types[0]);
+        for (int i = 1; i < types.length; i++)
+          sb.append(',').append(types[i]);
+      }
+    return sb.toString();
+  }
+
+  /**
+   * 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 native Object invoke (Object obj, Object[] args)
+    throws IllegalAccessException, IllegalArgumentException,
+    InvocationTargetException;
+
+  /**
+   * Returns an array of <code>TypeVariable</code> objects that represents
+   * the type variables declared by this constructor, in declaration order.
+   * An array of size zero is returned if this class has no type
+   * variables.
+   *
+   * @return the type variables associated with this class. 
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  /* FIXME[GENERICS]: Should be TypeVariable<Method>[] */
+  public TypeVariable[] getTypeParameters()
+  {
+    String sig = getSignature();
+    if (sig == null)
+      return new TypeVariable[0];
+    MethodSignatureParser p = new MethodSignatureParser(this, sig);
+    return p.getTypeParameters();
+  }
+
+  /**
+   * Return the String in the Signature attribute for this method. If there
+   * is no Signature attribute, return null.
+   */
+  private String getSignature()
+  {
+    // FIXME: libgcj doesn't record this information yet.
+    return null;
+  }
+
+  /**
+   * Returns an array of <code>Type</code> objects that represents
+   * the exception types declared by this method, in declaration order.
+   * An array of size zero is returned if this method declares no
+   * exceptions.
+   *
+   * @return the exception types declared by this method. 
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type[] getGenericExceptionTypes()
+  {
+    String sig = getSignature();
+    if (sig == null)
+      return getExceptionTypes();
+    MethodSignatureParser p = new MethodSignatureParser(this, sig);
+    return p.getGenericExceptionTypes();
+  }
+
+  /**
+   * Returns an array of <code>Type</code> objects that represents
+   * the parameter list for this method, in declaration order.
+   * An array of size zero is returned if this method takes no
+   * parameters.
+   *
+   * @return a list of the types of the method's parameters
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type[] getGenericParameterTypes()
+  {
+    String sig = getSignature();
+    if (sig == null)
+      return getParameterTypes();
+    MethodSignatureParser p = new MethodSignatureParser(this, sig);
+    return p.getGenericParameterTypes();
+  }
+
+  /**
+   * Returns the return type of this method.
+   *
+   * @return the return type of this method
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type getGenericReturnType()
+  {
+    String sig = getSignature();
+    if (sig == null)
+      return getReturnType();
+    MethodSignatureParser p = new MethodSignatureParser(this, sig);
+    return p.getGenericReturnType();
+  }
+
+  private native void getType ();
+
+  // Append a class name to a string buffer.  We try to print the
+  // fully-qualified name, the way that a Java programmer would expect
+  // it to be written.  Weirdly, Class has no appropriate method for
+  // this.
+  static void appendClassName (StringBuffer buf, Class k)
+  {
+    if (k.isArray ())
+      {
+	appendClassName (buf, k.getComponentType ());
+	buf.append ("[]");
+      }
+    else
+      {
+	// This is correct for primitive and reference types.  Really
+	// we'd like `Main$Inner' to be printed as `Main.Inner', I
+	// think, but that is a pain.
+	buf.append (k.getName ());
+      }
+  }
+
+  // Declaring class.
+  private Class declaringClass;
+
+  // Exception types.
+  private Class[] exception_types;
+  // Name cache.  (Initially null.)
+  private String name;
+  // Parameter types.
+  private Class[] parameter_types;
+  // Return type.
+  private Class return_type;
+
+  // Offset in bytes from the start of declaringClass's methods array.
+  private int offset;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Modifier.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Modifier.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Modifier.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/reflect/Modifier.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,375 @@
+/* java.lang.reflect.Modifier
+   Copyright (C) 1998, 1999, 2001, 2002, 2005, 2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+ 
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+/**
+ * Modifier is a helper class with static methods to determine whether an
+ * int returned from getModifiers() represents static, public, protected,
+ * native, final, etc... and provides an additional method to print
+ * out all of the modifiers in an int in order.
+ * <p>
+ * The methods in this class use the bitmask values in the VM spec to
+ * determine the modifiers of an int. This means that a VM must return a
+ * standard mask, conformant with the VM spec.  I don't know if this is how
+ * Sun does it, but I'm willing to bet money that it is.
+ *
+ * @author John Keiser
+ * @author Tom Tromey (tromey at cygnus.com)
+ * @author Eric Blake (ebb9 at email.byu.edu)
+ * @see Member#getModifiers()
+ * @see Method#getModifiers()
+ * @see Field#getModifiers()
+ * @see Constructor#getModifiers()
+ * @see Class#getModifiers()
+ * @since 1.1
+ */
+public class Modifier
+{
+  /** <STRONG>This constructor really shouldn't be here ... there are no
+   * instance methods or variables of this class, so instantiation is
+   * worthless.  However, this function is in the 1.1 spec, so it is added
+   * for completeness.</STRONG>
+   */
+  public Modifier()
+  {
+  }
+
+  /**
+   * Public: accessible from any other class.
+   */
+  public static final int PUBLIC = 0x0001;
+
+  /**
+   * Private: accessible only from the same enclosing class.
+   */
+  public static final int PRIVATE = 0x0002;
+
+  /**
+   * Protected: accessible only to subclasses, or within the package.
+   */
+  public static final int PROTECTED = 0x0004;
+
+  /**
+   * Static:<br><ul>
+   * <li>Class: no enclosing instance for nested class.</li>
+   * <li>Field or Method: can be accessed or invoked without an
+   *     instance of the declaring class.</li>
+   * </ul>
+   */
+  public static final int STATIC = 0x0008;
+
+  /**
+   * Final:<br><ul>
+   * <li>Class: no subclasses allowed.</li>
+   * <li>Field: cannot be changed.</li>
+   * <li>Method: cannot be overriden.</li>
+   * </ul>
+   */
+  public static final int FINAL = 0x0010;
+
+  /**
+   * Synchronized: Method: lock the class while calling this method.
+   */
+  public static final int SYNCHRONIZED = 0x0020;
+
+  /**
+   * Volatile: Field: cannot be cached.
+   */
+  public static final int VOLATILE = 0x0040;
+
+  /**
+   * Transient: Field: not serialized or deserialized.
+   */
+  public static final int TRANSIENT = 0x0080;
+
+  /**
+   * Native: Method: use JNI to call this method.
+   */
+  public static final int NATIVE = 0x0100;
+
+  /**
+   * Interface: Class: is an interface.
+   */
+  public static final int INTERFACE = 0x0200;
+
+  /**
+   * Abstract:<br><ul>
+   * <li>Class: may not be instantiated.</li>
+   * <li>Method: may not be called.</li>
+   * </ul>
+   */
+  public static final int ABSTRACT = 0x0400;
+
+  /**
+   * Strictfp: Method: expressions are FP-strict.<p>
+   * Also used as a modifier for classes, to mean that all initializers
+   * and constructors are FP-strict, but does not show up in
+   * Class.getModifiers.
+   */
+  public static final int STRICT = 0x0800;
+
+
+  /**
+   * Super - treat invokespecial as polymorphic so that super.foo() works
+   * according to the JLS. This is a reuse of the synchronized constant
+   * to patch a hole in JDK 1.0. *shudder*.
+   */
+  static final int SUPER = 0x0020;
+
+  /**
+   * All the flags, only used by code in this package.
+   */
+  static final int ALL_FLAGS = 0xfff;
+
+  /**
+   * Flag indicating a bridge method.
+   */
+  static final int BRIDGE = 0x40;
+
+  /**
+   * Flag indicating a varargs method.
+   */
+  static final int VARARGS = 0x80;
+
+  /**
+   * Flag indicating a synthetic member.
+   */
+  static final int SYNTHETIC = 0x1000;
+
+  /**
+   * Flag indicating an enum constant or an enum class.
+   */
+  static final int ENUM = 0x4000;
+
+  /**
+   * GCJ-LOCAL: This access flag is set on methods we declare
+   * internally but which must not be visible to reflection.
+   */
+  static final int INVISIBLE = 0x8000;
+
+  /**
+   * GCJ-LOCAL: This access flag is set on interpreted classes.
+   */
+  static final int INTERPRETED = 0x1000;
+
+  /**
+   * Check whether the given modifier is abstract.
+   * @param mod the modifier.
+   * @return <code>true</code> if abstract, <code>false</code> otherwise.
+   */
+  public static boolean isAbstract(int mod)
+  {
+    return (mod & ABSTRACT) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is final.
+   * @param mod the modifier.
+   * @return <code>true</code> if final, <code>false</code> otherwise.
+   */
+  public static boolean isFinal(int mod)
+  {
+    return (mod & FINAL) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is an interface.
+   * @param mod the modifier.
+   * @return <code>true</code> if an interface, <code>false</code> otherwise.
+   */
+  public static boolean isInterface(int mod)
+  {
+    return (mod & INTERFACE) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is native.
+   * @param mod the modifier.
+   * @return <code>true</code> if native, <code>false</code> otherwise.
+   */
+  public static boolean isNative(int mod)
+  {
+    return (mod & NATIVE) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is private.
+   * @param mod the modifier.
+   * @return <code>true</code> if private, <code>false</code> otherwise.
+   */
+  public static boolean isPrivate(int mod)
+  {
+    return (mod & PRIVATE) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is protected.
+   * @param mod the modifier.
+   * @return <code>true</code> if protected, <code>false</code> otherwise.
+   */
+  public static boolean isProtected(int mod)
+  {
+    return (mod & PROTECTED) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is public.
+   * @param mod the modifier.
+   * @return <code>true</code> if public, <code>false</code> otherwise.
+   */
+  public static boolean isPublic(int mod)
+  {
+    return (mod & PUBLIC) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is static.
+   * @param mod the modifier.
+   * @return <code>true</code> if static, <code>false</code> otherwise.
+   */
+  public static boolean isStatic(int mod)
+  {
+    return (mod & STATIC) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is strictfp.
+   * @param mod the modifier.
+   * @return <code>true</code> if strictfp, <code>false</code> otherwise.
+   */
+  public static boolean isStrict(int mod)
+  {
+    return (mod & STRICT) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is synchronized.
+   * @param mod the modifier.
+   * @return <code>true</code> if synchronized, <code>false</code> otherwise.
+   */
+  public static boolean isSynchronized(int mod)
+  {
+    return (mod & SYNCHRONIZED) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is transient.
+   * @param mod the modifier.
+   * @return <code>true</code> if transient, <code>false</code> otherwise.
+   */
+  public static boolean isTransient(int mod)
+  {
+    return (mod & TRANSIENT) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is volatile.
+   * @param mod the modifier.
+   * @return <code>true</code> if volatile, <code>false</code> otherwise.
+   */
+  public static boolean isVolatile(int mod)
+  {
+    return (mod & VOLATILE) != 0;
+  }
+
+  /**
+   * Get a string representation of all the modifiers represented by the
+   * given int. The keywords are printed in this order:
+   * <code><public|protected|private> abstract static final transient
+   * volatile synchronized native strictfp interface</code>.
+   *
+   * @param mod the modifier.
+   * @return the String representing the modifiers.
+   */
+  public static String toString(int mod)
+  {
+    return toString(mod, new StringBuffer()).toString();
+  }
+
+  /**
+   * Package helper method that can take a StringBuilder.
+   * @param mod the modifier
+   * @param r the StringBuilder to which the String representation is appended
+   * @return r, with information appended
+   */
+  static StringBuilder toString(int mod, StringBuilder r)
+  {
+    r.append(toString(mod, new StringBuffer()));
+    return r;
+  }
+
+  /**
+   * Package helper method that can take a StringBuffer.
+   * @param mod the modifier
+   * @param r the StringBuffer to which the String representation is appended
+   * @return r, with information appended
+   */
+  static StringBuffer toString(int mod, StringBuffer r)
+  {
+    if (isPublic(mod))
+      r.append("public ");
+    if (isProtected(mod))
+      r.append("protected ");
+    if (isPrivate(mod))
+      r.append("private ");
+    if (isAbstract(mod))
+      r.append("abstract ");
+    if (isStatic(mod))
+      r.append("static ");
+    if (isFinal(mod))
+      r.append("final ");
+    if (isTransient(mod))
+      r.append("transient ");
+    if (isVolatile(mod))
+      r.append("volatile ");
+    if (isSynchronized(mod))
+      r.append("synchronized ");
+    if (isNative(mod))
+      r.append("native ");
+    if (isStrict(mod))
+      r.append("strictfp ");
+    if (isInterface(mod))
+      r.append("interface ");
+    
+    // Trim trailing space.
+    if ((mod & ALL_FLAGS) != 0)
+      r.setLength(r.length() - 1);
+    return r;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/reflect/VMProxy.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/reflect/VMProxy.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/reflect/VMProxy.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/reflect/VMProxy.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,143 @@
+/* VMProxy.java -- VM interface for proxy class
+   Copyright (C) 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+final class VMProxy
+{
+  /**
+   * Set to true if the VM provides a native method to implement
+   * Proxy.getProxyClass completely, including argument verification.
+   * If this is true, HAVE_NATIVE_GET_PROXY_DATA and
+   * HAVE_NATIVE_GENERATE_PROXY_CLASS should be false.
+   * @see java.lang.reflect.Proxy
+   */
+  static boolean HAVE_NATIVE_GET_PROXY_CLASS = false;
+
+  /**
+   * Set to true if the VM provides a native method to implement
+   * the first part of Proxy.getProxyClass: generation of the array
+   * of methods to convert, and verification of the arguments.
+   * If this is true, HAVE_NATIVE_GET_PROXY_CLASS should be false.
+   * @see java.lang.reflect.Proxy
+   */
+  static boolean HAVE_NATIVE_GET_PROXY_DATA = false;
+
+  /**
+   * Set to true if the VM provides a native method to implement
+   * the second part of Proxy.getProxyClass: conversion of an array of
+   * methods into an actual proxy class.
+   * If this is true, HAVE_NATIVE_GET_PROXY_CLASS should be false.
+   * @see java.lang.reflect.Proxy
+   */
+  static boolean HAVE_NATIVE_GENERATE_PROXY_CLASS = false;
+
+  /**
+   * Optional native method to replace (and speed up) the pure Java
+   * implementation of getProxyClass.  Only needed if
+   * VMProxy.HAVE_NATIVE_GET_PROXY_CLASS is true, this does the
+   * work of both getProxyData and generateProxyClass with no
+   * intermediate form in Java. The native code may safely assume that
+   * this class must be created, and does not already exist.
+   *
+   * @param loader the class loader to define the proxy class in; null
+   *        implies the bootstrap class loader
+   * @param interfaces the interfaces the class will extend
+   * @return the generated proxy class
+   * @throws IllegalArgumentException if the constraints for getProxyClass
+   *         were violated, except for problems with null
+   * @throws NullPointerException if `interfaces' is null or contains
+   *         a null entry, or if handler is null
+   * @see Configuration#HAVE_NATIVE_GET_PROXY_CLASS
+   * @see #getProxyClass(ClassLoader, Class[])
+   * @see #getProxyData(ClassLoader, Class[])
+   * @see #generateProxyClass(ProxyData)
+   */
+  static Class getProxyClass(ClassLoader loader, Class[] interfaces)
+  {
+    return null;
+  }
+
+  /**
+   * Optional native method to replace (and speed up) the pure Java
+   * implementation of getProxyData.  Only needed if
+   * Configuration.HAVE_NATIVE_GET_PROXY_DATA is true. The native code
+   * may safely assume that a new ProxyData object must be created which
+   * does not duplicate any existing ones.
+   *
+   * @param loader the class loader to define the proxy class in; null
+   *        implies the bootstrap class loader
+   * @param interfaces the interfaces the class will extend
+   * @return all data that is required to make this proxy class
+   * @throws IllegalArgumentException if the constraints for getProxyClass
+   *         were violated, except for problems with null
+   * @throws NullPointerException if `interfaces' is null or contains
+   *         a null entry, or if handler is null
+   * @see Configuration.HAVE_NATIVE_GET_PROXY_DATA
+   * @see #getProxyClass(ClassLoader, Class[])
+   * @see #getProxyClass(ClassLoader, Class[])
+   * @see ProxyType#getProxyData()
+   */
+  static Proxy.ProxyData getProxyData(ClassLoader loader, Class[] interfaces)
+  {
+    return null;
+  }
+
+  /**
+   * Optional native method to replace (and speed up) the pure Java
+   * implementation of generateProxyClass.  Only needed if
+   * Configuration.HAVE_NATIVE_GENERATE_PROXY_CLASS is true. The native
+   * code may safely assume that a new Class must be created, and that
+   * the ProxyData object does not describe any existing class.
+   *
+   * @param loader the class loader to define the proxy class in; null
+   *        implies the bootstrap class loader
+   * @param data the struct of information to convert to a Class. This
+   *        has already been verified for all problems except exceeding
+   *        VM limitations
+   * @return the newly generated class
+   * @throws IllegalArgumentException if VM limitations are exceeded
+   * @see #getProxyClass(ClassLoader, Class[])
+   * @see #getProxyClass(ClassLoader, Class[])
+   * @see ProxyData#generateProxyClass(ClassLoader)
+   */
+  static Class generateProxyClass(ClassLoader loader, Proxy.ProxyData data)
+  {
+    return null;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/reflect/natArray.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/reflect/natArray.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/reflect/natArray.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/reflect/natArray.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,360 @@
+// natField.cc - Implementation of java.lang.reflect.Field native methods.
+
+/* Copyright (C) 1999, 2000, 2001, 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <jvm.h>
+#include <gcj/cni.h>
+#include <java-stack.h>
+#include <java/lang/reflect/Array.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+
+jobject
+java::lang::reflect::Array::newInstance (jclass componentType, jint length)
+{
+  if (componentType->isPrimitive())
+    {
+      // We could check for this in _Jv_NewPrimArray, but that seems
+      // like needless overhead when the only real route to this
+      // problem is here.
+      if (componentType == JvPrimClass (void))
+	throw new java::lang::IllegalArgumentException ();
+      return _Jv_NewPrimArray (componentType, length);
+    }
+  else
+    // FIXME: class loader?
+    return JvNewObjectArray (length, componentType, NULL);
+}
+
+jobject
+java::lang::reflect::Array::newInstance (jclass componentType,
+					 jintArray dimensions)
+{
+  jint ndims = dimensions->length;
+  if (ndims == 0)
+    throw new java::lang::IllegalArgumentException ();
+  jint* dims = elements (dimensions);
+  if (ndims == 1)
+    return newInstance (componentType, dims[0]);
+
+  Class *caller = _Jv_StackTrace::GetCallingClass (&Array::class$);
+  ClassLoader *caller_loader = NULL;
+  if (caller)
+    caller_loader = caller->getClassLoaderInternal();
+
+  jclass arrayType = componentType;
+  for (int i = 0;  i < ndims;  i++)
+    arrayType = _Jv_GetArrayClass (arrayType, caller_loader);
+
+  return _Jv_NewMultiArray (arrayType, ndims, dims);
+}
+
+jint
+java::lang::reflect::Array::getLength (jobject array)
+{
+  jclass arrayType = array->getClass();
+  if (! arrayType->isArray ())
+    throw new java::lang::IllegalArgumentException;
+  return ((__JArray*) array)->length;
+}
+
+jclass
+java::lang::reflect::Array::getElementType (jobject array, jint index)
+{
+  jclass arrayType = array->getClass();
+  if (! arrayType->isArray ())
+    throw new java::lang::IllegalArgumentException;
+  jint length = ((__JArray*) array)->length;
+  if ((_Jv_uint) index >= (_Jv_uint) length)
+    _Jv_ThrowBadArrayIndex(index);
+  return arrayType->getComponentType ();
+}
+
+jboolean
+java::lang::reflect::Array::getBoolean (jobject array, jint index)
+{
+  jclass elementType = getElementType (array, index);
+  if (elementType == JvPrimClass (boolean))
+    return elements ((jbooleanArray) array) [index];
+  throw new java::lang::IllegalArgumentException;
+}
+
+jchar
+java::lang::reflect::Array::getChar (jobject array, jint index)
+{
+  jclass elementType = getElementType (array, index);
+  if (elementType == JvPrimClass (char))
+    return elements ((jcharArray) array) [index];
+  throw new java::lang::IllegalArgumentException;
+}
+
+jbyte
+java::lang::reflect::Array::getByte (jobject array, jint index)
+{
+  jclass elementType = getElementType (array, index);
+  if (elementType == JvPrimClass (byte))
+    return elements ((jbyteArray) array) [index];
+  throw new java::lang::IllegalArgumentException;
+}
+
+jshort
+java::lang::reflect::Array::getShort (jobject array, jint index)
+{
+  jclass elementType = getElementType (array, index);
+  if (elementType == JvPrimClass (short))
+    return elements ((jshortArray) array) [index];
+  if (elementType == JvPrimClass (byte))
+    return elements ((jbyteArray) array) [index];
+  throw new java::lang::IllegalArgumentException;
+}
+
+jint
+java::lang::reflect::Array::getInt (jobject array, jint index)
+{
+  jclass elementType = getElementType (array, index);
+  if (elementType == JvPrimClass (int))
+    return elements ((jintArray) array) [index];
+  if (elementType == JvPrimClass (short))
+    return elements ((jshortArray) array) [index];
+  if (elementType == JvPrimClass (byte))
+    return elements ((jbyteArray) array) [index];
+  if (elementType == JvPrimClass (char))
+    return elements ((jcharArray) array) [index];
+  throw new java::lang::IllegalArgumentException;
+}
+
+jlong
+java::lang::reflect::Array::getLong (jobject array, jint index)
+{
+  jclass elementType = getElementType (array, index);
+  if (elementType == JvPrimClass (long))
+    return elements ((jlongArray) array) [index];
+  if (elementType == JvPrimClass (int))
+    return elements ((jintArray) array) [index];
+  if (elementType == JvPrimClass (short))
+    return elements ((jshortArray) array) [index];
+  if (elementType == JvPrimClass (byte))
+    return elements ((jbyteArray) array) [index];
+  if (elementType == JvPrimClass (char))
+    return elements ((jcharArray) array) [index];
+  throw new java::lang::IllegalArgumentException;
+}
+
+jfloat
+java::lang::reflect::Array::getFloat (jobject array, jint index)
+{
+  jclass elementType = getElementType (array, index);
+  if (elementType == JvPrimClass (float))
+    return elements ((jfloatArray) array) [index];
+  if (elementType == JvPrimClass (long))
+    return elements ((jlongArray) array) [index];
+  if (elementType == JvPrimClass (int))
+    return elements ((jintArray) array) [index];
+  if (elementType == JvPrimClass (short))
+    return elements ((jshortArray) array) [index];
+  if (elementType == JvPrimClass (byte))
+    return elements ((jbyteArray) array) [index];
+  if (elementType == JvPrimClass (char))
+    return elements ((jcharArray) array) [index];
+  throw new java::lang::IllegalArgumentException;
+}
+
+jdouble
+java::lang::reflect::Array::getDouble (jobject array, jint index)
+{
+  jclass elementType = getElementType (array, index);
+  if (elementType == JvPrimClass (double))
+    return elements ((jdoubleArray) array) [index];
+  if (elementType == JvPrimClass (float))
+    return elements ((jfloatArray) array) [index];
+  if (elementType == JvPrimClass (long))
+    return elements ((jlongArray) array) [index];
+  if (elementType == JvPrimClass (int))
+    return elements ((jintArray) array) [index];
+  if (elementType == JvPrimClass (short))
+    return elements ((jshortArray) array) [index];
+  if (elementType == JvPrimClass (byte))
+    return elements ((jbyteArray) array) [index];
+  if (elementType == JvPrimClass (char))
+    return elements ((jcharArray) array) [index];
+  throw new java::lang::IllegalArgumentException;
+}
+
+jobject
+java::lang::reflect::Array::get (jobject array, jint index)
+{
+  jclass elementType = getElementType (array, index);
+  if (! elementType->isPrimitive ())
+    return elements ((jobjectArray) array) [index];
+  if (elementType == JvPrimClass (double))
+    return new java::lang::Double (elements ((jdoubleArray) array) [index]);
+  if (elementType == JvPrimClass (float))
+    return new java::lang::Float (elements ((jfloatArray) array) [index]);
+  if (elementType == JvPrimClass (long))
+    return new java::lang::Long (elements ((jlongArray) array) [index]);
+  if (elementType == JvPrimClass (int))
+    return new java::lang::Integer (elements ((jintArray) array) [index]);
+  if (elementType == JvPrimClass (short))
+    return new java::lang::Short (elements ((jshortArray) array) [index]);
+  if (elementType == JvPrimClass (byte))
+    return new java::lang::Byte (elements ((jbyteArray) array) [index]);
+  if (elementType == JvPrimClass (char))
+    return new java::lang::Character (elements ((jcharArray) array) [index]);
+  if (elementType == JvPrimClass (boolean))
+    {
+      _Jv_InitClass (&java::lang::Boolean::class$);
+      if (elements ((jbooleanArray) array) [index])
+	return java::lang::Boolean::TRUE;
+      else
+	return java::lang::Boolean::FALSE;
+    }
+  throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setChar (jobject array, jint index, jchar value)
+{
+  jclass elementType = getElementType (array, index);
+  if (elementType == JvPrimClass (char))
+    elements ((jcharArray) array) [index] = value;
+  else if (elementType == JvPrimClass (int))
+    elements ((jintArray) array) [index] = value;
+  else if (elementType == JvPrimClass (long))
+    elements ((jlongArray) array) [index] = value;
+  else if (elementType == JvPrimClass (float))
+    elements ((jfloatArray) array) [index] = value;
+  else if (elementType == JvPrimClass (double))
+    elements ((jdoubleArray) array) [index] = value;
+  else
+    throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setByte (jobject array, jint index, jbyte value)
+{
+  jclass elementType = getElementType (array, index);
+  if (elementType == JvPrimClass (byte))
+    elements ((jbyteArray) array) [index] = value;
+  else if (elementType == JvPrimClass (short))
+    elements ((jshortArray) array) [index] = value;
+  else if (elementType == JvPrimClass (int))
+    elements ((jintArray) array) [index] = value;
+  else if (elementType == JvPrimClass (long))
+    elements ((jlongArray) array) [index] = value;
+  else if (elementType == JvPrimClass (float))
+    elements ((jfloatArray) array) [index] = value;
+  else if (elementType == JvPrimClass (double))
+    elements ((jdoubleArray) array) [index] = value;
+  else
+    throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setShort (jobject array, jint index, jshort value)
+{
+  jclass elementType = getElementType (array, index);
+  if (elementType == JvPrimClass (short))
+    elements ((jshortArray) array) [index] = value;
+  else if (elementType == JvPrimClass (int))
+    elements ((jintArray) array) [index] = value;
+  else if (elementType == JvPrimClass (long))
+    elements ((jlongArray) array) [index] = value;
+  else if (elementType == JvPrimClass (float))
+    elements ((jfloatArray) array) [index] = value;
+  else if (elementType == JvPrimClass (double))
+    elements ((jdoubleArray) array) [index] = value;
+  else
+    throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setInt (jobject array, jint index, jint value)
+{
+  jclass elementType = getElementType (array, index);
+  if (elementType == JvPrimClass (int))
+    elements ((jintArray) array) [index] = value;
+  else if (elementType == JvPrimClass (long))
+    elements ((jlongArray) array) [index] = value;
+  else if (elementType == JvPrimClass (float))
+    elements ((jfloatArray) array) [index] = value;
+  else if (elementType == JvPrimClass (double))
+    elements ((jdoubleArray) array) [index] = value;
+  else
+    throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setLong (jobject array, jint index, jlong value)
+{
+  jclass elementType = getElementType (array, index);
+  if (elementType == JvPrimClass (long))
+    elements ((jlongArray) array) [index] = value;
+  else if (elementType == JvPrimClass (float))
+    elements ((jfloatArray) array) [index] = value;
+  else if (elementType == JvPrimClass (double))
+    elements ((jdoubleArray) array) [index] = value;
+  else
+    throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setFloat (jobject array, jint index, jfloat value)
+{
+  jclass elementType = getElementType (array, index);
+  if (elementType == JvPrimClass (float))
+    elements ((jfloatArray) array) [index] = value;
+  else if (elementType == JvPrimClass (double))
+    elements ((jdoubleArray) array) [index] = value;
+  else
+    throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setDouble (jobject array, jint index, jdouble value)
+{
+  jclass elementType = getElementType (array, index);
+  if (elementType == JvPrimClass (double))
+    elements ((jdoubleArray) array) [index] = value;
+  else
+    throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setBoolean (jobject array,
+					jint index, jboolean value)
+{
+  jclass elementType = getElementType (array, index);
+  if (elementType == JvPrimClass (boolean))
+    elements ((jbooleanArray) array) [index] = value;
+  else
+    throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::set (jobject array, jint index,
+				 jobject value, jclass elType)
+{
+  // We don't have to call getElementType here, or check INDEX,
+  // because it was already done in the Java wrapper.
+  if (value != NULL && ! _Jv_IsInstanceOf (value, elType))
+    throw new java::lang::IllegalArgumentException;
+  elements ((jobjectArray) array) [index] = value;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/reflect/natConstructor.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/reflect/natConstructor.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/reflect/natConstructor.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/reflect/natConstructor.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,72 @@
+// natConstructor.cc - Native code for Constructor class.
+
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2006  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-stack.h>
+
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/IllegalAccessException.h>
+#include <java/lang/reflect/Constructor.h>
+#include <java/lang/reflect/Method.h>
+#include <java/lang/reflect/InvocationTargetException.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/InstantiationException.h>
+#include <gcj/method.h>
+
+jint
+java::lang::reflect::Constructor::getModifiersInternal ()
+{
+  return _Jv_FromReflectedConstructor (this)->accflags;
+}
+
+void
+java::lang::reflect::Constructor::getType ()
+{
+  _Jv_GetTypesFromSignature (_Jv_FromReflectedConstructor (this),
+			     declaringClass,
+			     &parameter_types,
+			     NULL);
+
+  // FIXME: for now we have no way to get exception information.
+  exception_types = 
+    (JArray<jclass> *) JvNewObjectArray (0, &java::lang::Class::class$, NULL);
+}
+
+jobject
+java::lang::reflect::Constructor::newInstance (jobjectArray args)
+{
+  using namespace java::lang::reflect;
+
+  if (parameter_types == NULL)
+    getType ();
+
+  jmethodID meth = _Jv_FromReflectedConstructor (this);
+
+  // Check accessibility, if required.
+  if (! (Modifier::isPublic (meth->accflags) || this->isAccessible()))
+    {
+      Class *caller = _Jv_StackTrace::GetCallingClass (&Constructor::class$);
+      if (! _Jv_CheckAccess(caller, declaringClass, meth->accflags))
+	throw new IllegalAccessException;
+    }
+
+  if (Modifier::isAbstract (declaringClass->getModifiers()))
+    throw new InstantiationException;
+
+  _Jv_InitClass (declaringClass);
+
+  // In the constructor case the return type is the type of the
+  // constructor.
+  return _Jv_CallAnyMethodA (NULL, declaringClass, meth, true,
+			     parameter_types, args);
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/reflect/natField.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/reflect/natField.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/reflect/natField.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/reflect/natField.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,439 @@
+// natField.cc - Implementation of java.lang.reflect.Field native methods.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <jvm.h>
+#include <java-stack.h>
+#include <java/lang/reflect/Field.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IllegalAccessException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+
+jint
+java::lang::reflect::Field::getModifiersInternal ()
+{
+  return _Jv_FromReflectedField (this)->flags;
+}
+
+jstring
+java::lang::reflect::Field::getName ()
+{
+  if (name == NULL)
+    name = _Jv_NewStringUtf8Const (_Jv_FromReflectedField (this)->name);
+  return name;
+}
+
+jclass
+java::lang::reflect::Field::getType ()
+{
+  if (type == NULL)
+    {
+      jfieldID fld = _Jv_FromReflectedField (this);
+      JvSynchronize sync (declaringClass);
+      _Jv_Linker::resolve_field (fld, declaringClass->getClassLoaderInternal ());
+      type = fld->type;
+    }
+  return type;
+}
+
+static void*
+getAddr (java::lang::reflect::Field* field, jclass caller, jobject obj,
+         jboolean checkFinal)
+{
+  // FIXME: we know CALLER is NULL here.  At one point we planned to
+  // have the compiler insert the caller as a hidden argument in some
+  // calls.  However, we never implemented that, so we have to find
+  // the caller by hand instead.
+  
+  using namespace java::lang::reflect;
+  
+  jfieldID fld = _Jv_FromReflectedField (field);
+  _Jv_ushort flags = fld->getModifiers();
+
+  // Setting a final field is usually not allowed.
+  if (checkFinal
+      // As of 1.5, you can set a non-static final field if it is
+      // accessible.
+      && (! field->isAccessible()
+	  || (field->getModifiers() & java::lang::reflect::Modifier::STATIC))
+      && (field->getModifiers() & java::lang::reflect::Modifier::FINAL))
+    throw new java::lang::IllegalAccessException(JvNewStringUTF 
+      ("Field is final"));
+  
+  // Check accessibility, if required.
+  if (! (Modifier::isPublic (flags) || field->isAccessible()))
+    {
+      caller = _Jv_StackTrace::GetCallingClass (&Field::class$);
+      if (! _Jv_CheckAccess (caller, field->getDeclaringClass(), flags))
+	throw new java::lang::IllegalAccessException;
+    }
+
+  if (flags & Modifier::STATIC)
+    {
+      jclass fldClass = field->getDeclaringClass ();
+      JvInitClass(fldClass);
+      return fld->u.addr;
+    }
+  else
+    {
+      if (obj == NULL)
+	throw new java::lang::NullPointerException;
+      if (! _Jv_IsInstanceOf (obj, field->getDeclaringClass()))
+	throw new java::lang::IllegalArgumentException;
+      return (void*) ((char*) obj + fld->getOffset ());
+    }
+}
+
+static jboolean
+getBoolean (jclass cls, void* addr)
+{
+  if (cls == JvPrimClass (boolean))
+    return * (jboolean *) addr;
+  throw new java::lang::IllegalArgumentException;
+}
+
+static jchar
+getChar (jclass cls, void* addr)
+{
+  if (cls == JvPrimClass (char))
+    return * (jchar *) addr;
+  throw new java::lang::IllegalArgumentException;
+}
+
+static jbyte
+getByte (jclass cls, void* addr)
+{
+  if (cls == JvPrimClass (byte))
+    return * (jbyte *) addr;
+  throw new java::lang::IllegalArgumentException;
+}
+
+static jshort
+getShort (jclass cls, void* addr)
+{
+  if (cls == JvPrimClass (short))
+    return * (jshort *) addr;
+  if (cls == JvPrimClass (byte))
+    return * (jbyte *) addr;
+  throw new java::lang::IllegalArgumentException;
+}
+
+static jint
+getInt (jclass cls, void* addr)
+{
+  if (cls == JvPrimClass (int))
+    return * (jint *) addr;
+  if (cls == JvPrimClass (short))
+    return * (jshort *) addr;
+  if (cls == JvPrimClass (char))
+    return * (jchar *) addr;
+  if (cls == JvPrimClass (byte))
+    return * (jbyte *) addr;
+  throw new java::lang::IllegalArgumentException;
+}
+
+static jlong
+getLong (jclass cls, void* addr)
+{
+  if (cls == JvPrimClass (long))
+    return * (jlong *) addr;
+  return ::getInt(cls, addr);
+}
+
+static jfloat
+getFloat (jclass cls, void* addr)
+{
+  if (cls == JvPrimClass (float))
+    return * (jfloat *) addr;
+  if (cls == JvPrimClass (long))
+    return * (jlong *) addr;
+  return ::getInt(cls, addr);
+}
+
+static jdouble
+getDouble (jclass cls, void* addr)
+{
+  if (cls == JvPrimClass (double))
+    return * (jdouble *) addr;
+  if (cls == JvPrimClass (float))
+    return * (jfloat *) addr;
+  if (cls == JvPrimClass (long))
+    return * (jlong *) addr;
+  return ::getInt(cls, addr);
+}
+
+jboolean
+java::lang::reflect::Field::getBoolean (jclass caller, jobject obj)
+{
+  return ::getBoolean (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jchar
+java::lang::reflect::Field::getChar (jclass caller, jobject obj)
+{
+  return ::getChar (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jbyte
+java::lang::reflect::Field::getByte (jclass caller, jobject obj)
+{
+  return ::getByte (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jshort
+java::lang::reflect::Field::getShort (jclass caller, jobject obj)
+{
+  return ::getShort (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jint
+java::lang::reflect::Field::getInt (jclass caller, jobject obj)
+{
+  return ::getInt (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jlong
+java::lang::reflect::Field::getLong (jclass caller, jobject obj)
+{
+  return ::getLong (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jfloat
+java::lang::reflect::Field::getFloat (jclass caller, jobject obj)
+{
+  return ::getFloat (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jdouble
+java::lang::reflect::Field::getDouble (jclass caller, jobject obj)
+{
+  return ::getDouble (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jobject
+java::lang::reflect::Field::get (jclass caller, jobject obj)
+{
+  jclass type = this->getType();
+  void* addr = getAddr (this, caller, obj, false);
+  if (! type->isPrimitive ())
+    return * (jobject*) addr;
+  if (type == JvPrimClass (double))
+    return new java::lang::Double (* (jdouble*) addr);
+  if (type == JvPrimClass (float))
+    return new java::lang::Float (* (jfloat*) addr);
+  if (type == JvPrimClass (long))
+    return new java::lang::Long (* (jlong*) addr);
+  if (type == JvPrimClass (int))
+    return new java::lang::Integer (* (jint*) addr);
+  if (type == JvPrimClass (short))
+    return new java::lang::Short (* (jshort*) addr);
+  if (type == JvPrimClass (byte))
+    return new java::lang::Byte (* (jbyte*) addr);
+  if (type == JvPrimClass (char))
+    return new java::lang::Character (* (jchar*) addr);
+  if (type == JvPrimClass (boolean))
+    {
+      _Jv_InitClass (&java::lang::Boolean::class$);
+      if (* (jboolean*) addr)
+	return java::lang::Boolean::TRUE;
+      else
+	return java::lang::Boolean::FALSE;
+    }
+  throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setBoolean (jclass type, void *addr, jboolean value)
+{
+  if (type == JvPrimClass (boolean))
+    * (jboolean *) addr = value;
+  else
+    throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setChar (jclass type, void *addr, jchar value)
+{
+  if (type == JvPrimClass (char))
+    * (jchar *) addr = value;
+  else if (type == JvPrimClass (int))
+    * (jint *) addr = value;
+  else if (type == JvPrimClass (long))
+    * (jlong *) addr = value;
+  else if (type == JvPrimClass (float))
+    * (jfloat *) addr = value;
+  else if (type == JvPrimClass (double))
+    * (jdouble *) addr = value;
+  else
+    throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setByte (jclass type, void *addr, jbyte value)
+{
+  if (type == JvPrimClass (byte))
+    * (jbyte *) addr = value;
+  else if (type == JvPrimClass (short))
+    * (jshort *) addr = value;
+  else if (type == JvPrimClass (int))
+    * (jint *) addr = value;
+  else if (type == JvPrimClass (long))
+    * (jlong *) addr = value;
+  else if (type == JvPrimClass (float))
+    * (jfloat *) addr = value;
+  else if (type == JvPrimClass (double))
+    * (jdouble *) addr = value;
+  else
+    throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setShort (jclass type, void *addr, jshort value)
+{
+  if (type == JvPrimClass (short))
+    * (jshort *) addr = value;
+  else if (type == JvPrimClass (int))
+    * (jint *) addr = value;
+  else if (type == JvPrimClass (long))
+    * (jlong *) addr = value;
+  else if (type == JvPrimClass (float))
+    * (jfloat *) addr = value;
+  else if (type == JvPrimClass (double))
+    * (jdouble *) addr = value;
+  else
+    throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setInt (jclass type, void *addr, jint value)
+{
+  if (type == JvPrimClass (int))
+    * (jint *) addr = value;
+  else if (type == JvPrimClass (long))
+    * (jlong *) addr = value;
+  else if (type == JvPrimClass (float))
+    * (jfloat *) addr = value;
+  else if (type == JvPrimClass (double))
+    * (jdouble *) addr = value;
+  else
+    throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setLong (jclass type, void *addr, jlong value)
+{
+  if (type == JvPrimClass (long))
+    * (jlong *) addr = value;
+  else if (type == JvPrimClass (float))
+    * (jfloat *) addr = value;
+  else if (type == JvPrimClass (double))
+    * (jdouble *) addr = value;
+  else
+    throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setFloat (jclass type, void *addr, jfloat value)
+{
+  if (type == JvPrimClass (float))
+    * (jfloat *) addr = value;
+  else if (type == JvPrimClass (double))
+    * (jdouble *) addr = value;
+  else
+    throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setDouble (jclass type, void *addr, jdouble value)
+{
+  if (type == JvPrimClass (double))
+    * (jdouble *) addr = value;
+  else
+    throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Field::setBoolean (jclass caller, jobject obj, jboolean b,
+					jboolean checkFinal)
+{
+  ::setBoolean (this->getType(), getAddr (this, caller, obj, checkFinal), b);
+}
+
+void
+java::lang::reflect::Field::setChar (jclass caller, jobject obj, jchar c,
+				     jboolean checkFinal)
+{
+  ::setChar (this->getType(), getAddr (this, caller, obj, checkFinal), c);
+}
+
+void
+java::lang::reflect::Field::setByte (jclass caller, jobject obj, jbyte b,
+				     jboolean checkFinal)
+{
+  ::setByte (this->getType(), getAddr (this, caller, obj, checkFinal), b);
+}
+
+void
+java::lang::reflect::Field::setShort (jclass caller, jobject obj, jshort s,
+				      jboolean checkFinal)
+{
+  ::setShort (this->getType(), getAddr (this, caller, obj, checkFinal), s);
+}
+
+void
+java::lang::reflect::Field::setInt (jclass caller, jobject obj, jint i,
+				    jboolean checkFinal)
+{
+  ::setInt (this->getType(), getAddr (this, caller, obj, checkFinal), i);
+}
+
+void
+java::lang::reflect::Field::setLong (jclass caller, jobject obj, jlong l,
+				     jboolean checkFinal)
+{
+  ::setLong (this->getType(), getAddr (this, caller, obj, checkFinal), l);
+}
+
+void
+java::lang::reflect::Field::setFloat (jclass caller, jobject obj, jfloat f,
+				      jboolean checkFinal)
+{
+  ::setFloat (this->getType(), getAddr (this, caller, obj, checkFinal), f);
+}
+
+void
+java::lang::reflect::Field::setDouble (jclass caller, jobject obj, jdouble d,
+				       jboolean checkFinal)
+{
+  ::setDouble (this->getType(), getAddr (this, caller, obj, checkFinal), d);
+}
+
+void
+java::lang::reflect::Field::set (jclass caller, jobject object, jobject value,
+				 jclass type, jboolean checkFinal)
+{
+  void* addr = getAddr (this, caller, object, checkFinal);
+  if (value != NULL && ! _Jv_IsInstanceOf (value, type))
+    throw new java::lang::IllegalArgumentException;
+  * (jobject*) addr = value;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/lang/reflect/natMethod.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/lang/reflect/natMethod.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/lang/reflect/natMethod.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/lang/reflect/natMethod.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,654 @@
+// natMethod.cc - Native code for Method class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001 , 2002, 2003, 2004, 2005, 2006 Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <jni.h>
+#include <java-stack.h>
+
+#include <java/lang/reflect/Method.h>
+#include <java/lang/reflect/Constructor.h>
+#include <java/lang/reflect/InvocationTargetException.h>
+#include <java/lang/reflect/Modifier.h>
+
+#include <java/lang/Void.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/IllegalAccessException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/VirtualMachineError.h>
+#include <java/lang/Class.h>
+#include <gcj/method.h>
+#include <gnu/gcj/RawData.h>
+#include <java/lang/NoClassDefFoundError.h>
+
+#include <stdlib.h>
+
+#if USE_LIBFFI
+#include <ffi.h>
+#else
+#include <java/lang/UnsupportedOperationException.h>
+#endif
+
+struct cpair
+{
+  jclass prim;
+  jclass wrap;
+};
+
+// This is used to determine when a primitive widening conversion is
+// allowed.
+static cpair primitives[] =
+{
+#define BOOLEAN 0
+  { JvPrimClass (boolean), &java::lang::Boolean::class$ },
+  { JvPrimClass (byte), &java::lang::Byte::class$ },
+#define SHORT 2
+  { JvPrimClass (short), &java::lang::Short::class$ },
+#define CHAR 3
+  { JvPrimClass (char), &java::lang::Character::class$ },
+  { JvPrimClass (int), &java::lang::Integer::class$ },
+  { JvPrimClass (long), &java::lang::Long::class$ },
+  { JvPrimClass (float), &java::lang::Float::class$ },
+  { JvPrimClass (double), &java::lang::Double::class$ },
+  { NULL, NULL }
+};
+
+static inline jboolean
+can_widen (jclass from, jclass to)
+{
+  int fromx = -1, tox = -1;
+
+  for (int i = 0; primitives[i].prim; ++i)
+    {
+      if (primitives[i].wrap == from)
+	fromx = i;
+      if (primitives[i].prim == to)
+	tox = i;
+    }
+
+  // Can't handle a miss.
+  if (fromx == -1 || tox == -1)
+    return false;
+  // Boolean arguments may not be widened.
+  if (fromx == BOOLEAN && tox != BOOLEAN)
+    return false;
+  // Nothing promotes to char.
+  if (tox == CHAR && fromx != CHAR)
+    return false;
+
+  return fromx <= tox;
+}
+
+#ifdef USE_LIBFFI
+static inline ffi_type *
+get_ffi_type (jclass klass)
+{
+  // A special case.
+  if (klass == NULL)
+    return &ffi_type_pointer;
+
+  ffi_type *r;
+  if (klass == JvPrimClass (byte))
+    r = &ffi_type_sint8;
+  else if (klass == JvPrimClass (short))
+    r = &ffi_type_sint16;
+  else if (klass == JvPrimClass (int))
+    r = &ffi_type_sint32;
+  else if (klass == JvPrimClass (long))
+    r = &ffi_type_sint64;
+  else if (klass == JvPrimClass (float))
+    r = &ffi_type_float;
+  else if (klass == JvPrimClass (double))
+    r = &ffi_type_double;
+  else if (klass == JvPrimClass (boolean))
+    {
+      // On some platforms a bool is a byte, on others an int.
+      if (sizeof (jboolean) == sizeof (jbyte))
+	r = &ffi_type_sint8;
+      else
+	{
+	  JvAssert (sizeof (jboolean) == sizeof (jint));
+	  r = &ffi_type_sint32;
+	}
+    }
+  else if (klass == JvPrimClass (char))
+    r = &ffi_type_uint16;
+  else
+    {
+      JvAssert (! klass->isPrimitive());
+      r = &ffi_type_pointer;
+    }
+
+  return r;
+}
+#endif // USE_LIBFFI
+
+jobject
+java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
+{
+  using namespace java::lang::reflect;
+  jclass iface = NULL;
+  
+  if (parameter_types == NULL)
+    getType ();
+    
+  jmethodID meth = _Jv_FromReflectedMethod (this);
+
+  if (Modifier::isStatic(meth->accflags))
+    {
+      // We have to initialize a static class.  It is safe to do this
+      // here and not in _Jv_CallAnyMethodA because JNI initializes a
+      // class whenever a method lookup is done.
+      _Jv_InitClass (declaringClass);
+    }
+  else
+    {
+      jclass objClass = JV_CLASS (obj);
+      if (! _Jv_IsAssignableFrom (objClass, declaringClass))
+        throw new java::lang::IllegalArgumentException;
+    }
+
+  // Check accessibility, if required.
+  if (! (Modifier::isPublic (meth->accflags) || this->isAccessible()))
+    {
+      Class *caller = _Jv_StackTrace::GetCallingClass (&Method::class$);
+      if (! _Jv_CheckAccess(caller, declaringClass, meth->accflags))
+	throw new IllegalAccessException;
+    }
+
+  if (declaringClass->isInterface())
+    iface = declaringClass;
+  
+  return _Jv_CallAnyMethodA (obj, return_type, meth, false,
+			     parameter_types, args, iface);
+}
+
+jint
+java::lang::reflect::Method::getModifiersInternal ()
+{
+  return _Jv_FromReflectedMethod (this)->accflags;
+}
+
+jstring
+java::lang::reflect::Method::getName ()
+{
+  if (name == NULL)
+    name = _Jv_NewStringUtf8Const (_Jv_FromReflectedMethod (this)->name);
+  return name;
+}
+
+/* Internal method to set return_type and parameter_types fields. */
+
+void
+java::lang::reflect::Method::getType ()
+{
+  _Jv_Method *method = _Jv_FromReflectedMethod (this);
+  _Jv_GetTypesFromSignature (method,
+			     declaringClass,
+			     &parameter_types,
+			     &return_type);
+
+  int count = 0;
+  if (method->throws != NULL)
+    {
+      while (method->throws[count] != NULL)
+	++count;
+    }
+
+  exception_types
+    = (JArray<jclass> *) JvNewObjectArray (count, &java::lang::Class::class$,
+					   NULL);
+  jclass *elts = elements (exception_types);
+  for (int i = 0; i < count; ++i)
+    elts[i] = _Jv_FindClass (method->throws[i],
+			     declaringClass->getClassLoaderInternal ());
+}
+
+void
+_Jv_GetTypesFromSignature (jmethodID method,
+			   jclass declaringClass,
+			   JArray<jclass> **arg_types_out,
+			   jclass *return_type_out)
+{
+
+  _Jv_Utf8Const* sig = method->signature;
+  java::lang::ClassLoader *loader = declaringClass->getClassLoaderInternal();
+  char *ptr = sig->chars();
+  int numArgs = 0;
+  /* First just count the number of parameters. */
+  // FIXME: should do some validation here, e.g., that there is only
+  // one return type.
+  for (; ; ptr++)
+    {
+      switch (*ptr)
+	{
+	case 0:
+	case ')':
+	case 'V':
+	  break;
+	case '[':
+	case '(':
+	  continue;
+	case 'B':
+	case 'C':
+	case 'D':
+	case 'F':
+	case 'S':
+	case 'I':
+	case 'J':
+	case 'Z':
+	  numArgs++;
+	  continue;
+	case 'L':
+	  numArgs++;
+	  do 
+	    ptr++;
+	  while (*ptr != ';' && ptr[1] != '\0');
+	  continue;
+	}
+      break;
+    }
+
+  JArray<jclass> *args = (JArray<jclass> *)
+    JvNewObjectArray (numArgs, &java::lang::Class::class$, NULL);
+  jclass* argPtr = elements (args);
+  for (ptr = sig->chars(); *ptr != '\0'; ptr++)
+    {
+      if (*ptr == '(')
+	continue;
+      if (*ptr == ')')
+	{
+	  argPtr = return_type_out;
+	  continue;
+	}
+
+      char *end_ptr;
+      jclass type = _Jv_FindClassFromSignature (ptr, loader, &end_ptr);
+      if (type == NULL)
+	// FIXME: This isn't ideal.
+	throw new java::lang::NoClassDefFoundError (sig->toString());
+
+      // ARGPTR can be NULL if we are processing the return value of a
+      // call from Constructor.
+      if (argPtr)
+	*argPtr++ = type;
+
+      ptr = end_ptr;
+    }
+  *arg_types_out = args;
+}
+
+// This is a very rough analog of the JNI CallNonvirtual<type>MethodA
+// functions.  It handles both Methods and Constructors, and it can
+// handle any return type.  In the Constructor case, the `obj'
+// argument is unused and should be NULL; also, the `return_type' is
+// the class that the constructor will construct.  RESULT is a pointer
+// to a `jvalue' (see jni.h); for a void method this should be NULL.
+// This function returns an exception (if one was thrown), or NULL if
+// the call went ok.
+void
+_Jv_CallAnyMethodA (jobject obj,
+		    jclass return_type,
+		    jmethodID meth,
+		    jboolean is_constructor,
+		    jboolean is_virtual_call,
+		    JArray<jclass> *parameter_types,
+		    jvalue *args,
+		    jvalue *result,
+		    jboolean is_jni_call,
+		    jclass iface)
+{
+  using namespace java::lang::reflect;
+  
+#ifdef USE_LIBFFI
+  JvAssert (! is_constructor || ! obj);
+  JvAssert (! is_constructor || return_type);
+
+  // See whether call needs an object as the first argument.  A
+  // constructor does need a `this' argument, but it is one we create.
+  jboolean needs_this = false;
+  if (is_constructor
+      || ! Modifier::isStatic(meth->accflags))
+    needs_this = true;
+
+  int param_count = parameter_types->length;
+  if (needs_this)
+    ++param_count;
+
+  ffi_type *rtype;
+  // A constructor itself always returns void.
+  if (is_constructor || return_type == JvPrimClass (void))
+    rtype = &ffi_type_void;
+  else
+    rtype = get_ffi_type (return_type);
+  ffi_type **argtypes = (ffi_type **) __builtin_alloca (param_count
+							* sizeof (ffi_type *));
+
+  jclass *paramelts = elements (parameter_types);
+
+  // Special case for the `this' argument of a constructor.  Note that
+  // the JDK 1.2 docs specify that the new object must be allocated
+  // before argument conversions are done.
+  if (is_constructor)
+    obj = _Jv_AllocObject (return_type);
+
+  const int size_per_arg = sizeof(jvalue);
+  ffi_cif cif;
+
+  char *p = (char *) __builtin_alloca (param_count * size_per_arg);
+		// Overallocate to get correct alignment.
+  void **values = (void **)
+			__builtin_alloca (param_count * sizeof (void *));
+
+  int i = 0;
+  if (needs_this)
+    {
+      // The `NULL' type is `Object'.
+      argtypes[i] = get_ffi_type (NULL);
+      values[i] = p;
+      memcpy (p, &obj, sizeof (jobject));
+      p += size_per_arg;
+      ++i;
+    }
+
+  for (int arg = 0; i < param_count; ++i, ++arg)
+    {
+      int tsize;
+
+      argtypes[i] = get_ffi_type (paramelts[arg]);
+      if (paramelts[arg]->isPrimitive())
+	tsize = paramelts[arg]->size();
+      else
+	tsize = sizeof (jobject);
+
+      // Copy appropriate bits from the jvalue into the ffi array.
+      // FIXME: we could do this copying all in one loop, above, by
+      // over-allocating a bit.
+      // How do we do this without breaking big-endian platforms?
+      values[i] = p;
+      memcpy (p, &args[arg], tsize);
+      p += size_per_arg;
+    }
+
+  if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, param_count,
+		    rtype, argtypes) != FFI_OK)
+    throw new java::lang::VirtualMachineError(JvNewStringLatin1("internal error: ffi_prep_cif failed"));
+
+  using namespace java::lang;
+  using namespace java::lang::reflect;
+
+  union
+  {
+    ffi_arg i;
+    jobject o;
+    jlong l;
+    jfloat f;
+    jdouble d;
+  } ffi_result;
+
+  switch (rtype->type)
+    {
+    case FFI_TYPE_VOID:
+      break;
+    case FFI_TYPE_SINT8:
+      result->b = 0;
+      break;
+    case FFI_TYPE_SINT16:
+      result->s = 0;
+      break;
+    case FFI_TYPE_UINT16:
+      result->c = 0;
+      break;
+    case FFI_TYPE_SINT32:
+      result->i = 0;
+      break;
+    case FFI_TYPE_SINT64:
+      result->j = 0;
+      break;
+    case FFI_TYPE_FLOAT:
+      result->f = 0;
+      break;
+    case FFI_TYPE_DOUBLE:
+      result->d = 0;
+      break;
+    case FFI_TYPE_POINTER:
+      result->l = 0;
+      break;
+    default:
+      JvFail ("Unknown ffi_call return type");
+      break;
+    }
+
+  void *ncode;
+
+  // FIXME: If a vtable index is -1 at this point it is invalid, so we
+  // have to use the ncode.  
+  //
+  // This can happen because methods in final classes don't have
+  // vtable entries, but _Jv_isVirtualMethod() doesn't know that.  We
+  // could solve this problem by allocating a vtable index for methods
+  // in final classes.
+  if (is_virtual_call 
+      && ! Modifier::isFinal (meth->accflags)
+      && (_Jv_ushort)-1 != meth->index)
+    {
+      _Jv_VTable *vtable = *(_Jv_VTable **) obj;
+      if (iface == NULL)
+	{
+	  if (is_jni_call && Modifier::isAbstract (meth->accflags))
+	    {
+	      // With JNI we don't know if this is an interface call
+	      // or a call to an abstract method.  Look up the method
+	      // by name, the slow way.
+	      _Jv_Method *concrete_meth
+		= _Jv_LookupDeclaredMethod (vtable->clas,
+					    meth->name,
+					    meth->signature,
+					    NULL);
+	      if (concrete_meth == NULL
+		  || concrete_meth->ncode == NULL
+		  || Modifier::isAbstract(concrete_meth->accflags))
+		throw new java::lang::IncompatibleClassChangeError
+		  (_Jv_GetMethodString (vtable->clas, meth));
+	      ncode = concrete_meth->ncode;
+	    }
+	  else
+	    ncode = vtable->get_method (meth->index);
+	}
+      else
+	ncode = _Jv_LookupInterfaceMethodIdx (vtable->clas, iface,
+					      meth->index);
+    }
+  else
+    {
+      ncode = meth->ncode;
+    }
+
+  try
+    {
+      ffi_call (&cif, (void (*)()) ncode, &ffi_result, values);
+    }
+  catch (Throwable *ex)
+    {
+      // For JNI we just throw the real error.  For reflection, we
+      // wrap the underlying method's exception in an
+      // InvocationTargetException.
+      if (! is_jni_call)
+	ex = new InvocationTargetException (ex);
+      throw ex;
+    }
+
+  // Since ffi_call returns integer values promoted to a word, use
+  // a narrowing conversion for jbyte, jchar, etc. results.
+  // Note that boolean is handled either by the FFI_TYPE_SINT8 or
+  // FFI_TYPE_SINT32 case.
+  if (is_constructor)
+    result->l = obj;
+  else
+    {
+      switch (rtype->type)
+	{
+	case FFI_TYPE_VOID:
+	  break;
+	case FFI_TYPE_SINT8:
+	  result->b = (jbyte)ffi_result.i;
+	  break;
+	case FFI_TYPE_SINT16:
+	  result->s = (jshort)ffi_result.i;
+	  break;
+	case FFI_TYPE_UINT16:
+	  result->c = (jchar)ffi_result.i;
+	  break;
+	case FFI_TYPE_SINT32:
+	  result->i = (jint)ffi_result.i;
+	  break;
+	case FFI_TYPE_SINT64:
+	  result->j = (jlong)ffi_result.l;
+	  break;
+	case FFI_TYPE_FLOAT:
+	  result->f = (jfloat)ffi_result.f;
+	  break;
+	case FFI_TYPE_DOUBLE:
+	  result->d = (jdouble)ffi_result.d;
+	  break;
+	case FFI_TYPE_POINTER:
+	  result->l = (jobject)ffi_result.o;
+	  break;
+	default:
+	  JvFail ("Unknown ffi_call return type");
+	  break;
+	}
+    }
+#else
+  throw new java::lang::UnsupportedOperationException(JvNewStringLatin1("reflection not available in this build"));
+#endif // USE_LIBFFI
+}
+
+// This is another version of _Jv_CallAnyMethodA, but this one does
+// more checking and is used by the reflection (and not JNI) code.
+jobject
+_Jv_CallAnyMethodA (jobject obj,
+		    jclass return_type,
+		    jmethodID meth,
+		    jboolean is_constructor,
+		    JArray<jclass> *parameter_types,
+		    jobjectArray args,
+		    jclass iface)
+{
+  if (parameter_types->length == 0 && args == NULL)
+    {
+      // The JDK accepts this, so we do too.
+    }
+  else if (parameter_types->length != args->length)
+    throw new java::lang::IllegalArgumentException;
+
+  int param_count = parameter_types->length;
+
+  jclass *paramelts = elements (parameter_types);
+  jobject *argelts = args == NULL ? NULL : elements (args);
+  jvalue argvals[param_count];
+
+#define COPY(Where, What, Type) \
+  do { \
+    Type val = (What); \
+    memcpy ((Where), &val, sizeof (Type)); \
+  } while (0)
+
+  for (int i = 0; i < param_count; ++i)
+    {
+      jclass k = argelts[i] ? argelts[i]->getClass() : NULL;
+      if (paramelts[i]->isPrimitive())
+	{
+	  if (! argelts[i]
+	      || ! k
+	      || ! can_widen (k, paramelts[i]))
+	    throw new java::lang::IllegalArgumentException;
+	    
+	  if (paramelts[i] == JvPrimClass (boolean))
+	    COPY (&argvals[i],
+		  ((java::lang::Boolean *) argelts[i])->booleanValue(),
+		  jboolean);
+	  else if (paramelts[i] == JvPrimClass (char))
+	    COPY (&argvals[i],
+		  ((java::lang::Character *) argelts[i])->charValue(),
+		  jchar);
+          else
+	    {
+	      java::lang::Number *num = (java::lang::Number *) argelts[i];
+	      if (paramelts[i] == JvPrimClass (byte))
+		COPY (&argvals[i], num->byteValue(), jbyte);
+	      else if (paramelts[i] == JvPrimClass (short))
+		COPY (&argvals[i], num->shortValue(), jshort);
+	      else if (paramelts[i] == JvPrimClass (int))
+		COPY (&argvals[i], num->intValue(), jint);
+	      else if (paramelts[i] == JvPrimClass (long))
+		COPY (&argvals[i], num->longValue(), jlong);
+	      else if (paramelts[i] == JvPrimClass (float))
+		COPY (&argvals[i], num->floatValue(), jfloat);
+	      else if (paramelts[i] == JvPrimClass (double))
+		COPY (&argvals[i], num->doubleValue(), jdouble);
+	    }
+	}
+      else
+	{
+	  if (argelts[i] && ! paramelts[i]->isAssignableFrom (k))
+	    throw new java::lang::IllegalArgumentException;
+	  COPY (&argvals[i], argelts[i], jobject);
+	}
+    }
+
+  jvalue ret_value;
+  _Jv_CallAnyMethodA (obj, return_type, meth, is_constructor,
+  		      _Jv_isVirtualMethod (meth),
+		      parameter_types, argvals, &ret_value,
+		      false, iface);
+
+  jobject r;
+#define VAL(Wrapper, Field)  (new Wrapper (ret_value.Field))
+  if (is_constructor)
+    r = ret_value.l;
+  else  if (return_type == JvPrimClass (byte))
+    r = VAL (java::lang::Byte, b);
+  else if (return_type == JvPrimClass (short))
+    r = VAL (java::lang::Short, s);
+  else if (return_type == JvPrimClass (int))
+    r = VAL (java::lang::Integer, i);
+  else if (return_type == JvPrimClass (long))
+    r = VAL (java::lang::Long, j);
+  else if (return_type == JvPrimClass (float))
+    r = VAL (java::lang::Float, f);
+  else if (return_type == JvPrimClass (double))
+    r = VAL (java::lang::Double, d);
+  else if (return_type == JvPrimClass (boolean))
+    r = VAL (java::lang::Boolean, z);
+  else if (return_type == JvPrimClass (char))
+    r = VAL (java::lang::Character, c);
+  else if (return_type == JvPrimClass (void))
+    r = NULL;
+  else
+    {
+      JvAssert (return_type == NULL || ! return_type->isPrimitive());
+      r = ret_value.l;
+    }
+
+  return r;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/net/InetAddress.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/net/InetAddress.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/net/InetAddress.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/net/InetAddress.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,819 @@
+/* InetAddress.java -- Class to model an Internet address
+   Copyright (C) 1998, 1999, 2002, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.net;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+/**
+ * This class models an Internet address.  It does not have a public
+ * constructor.  Instead, new instances of this objects are created
+ * using the static methods getLocalHost(), getByName(), and
+ * getAllByName().
+ *
+ * <p>This class fulfills the function of the C style functions gethostname(),
+ * gethostbyname(), and gethostbyaddr().  It resolves Internet DNS names
+ * into their corresponding numeric addresses and vice versa.</p>
+ *
+ * @author Aaron M. Renn (arenn at urbanophile.com)
+ * @author Per Bothner
+ * @author Gary Benson (gbenson at redhat.com)
+ *
+ * @specnote This class is not final since JK 1.4
+ */
+public class InetAddress implements Serializable
+{
+  private static final long serialVersionUID = 3286316764910316507L;
+
+  /**
+   * Stores static localhost address object.
+   */
+  static InetAddress LOCALHOST;
+  static
+  {
+    try
+      {
+	LOCALHOST = getByAddress("localhost", new byte[] {127, 0, 0, 1});
+	// Some soon-to-be-removed native code synchronizes on this.
+	loopbackAddress = LOCALHOST;
+      }
+    catch (UnknownHostException e)
+      {
+	throw new RuntimeException("should never happen", e);
+      }
+  }    
+
+  /**
+   * Dummy InetAddress, used to bind socket to any (all) network interfaces.
+   */
+  static InetAddress ANY_IF;
+  static
+  {
+    byte[] addr;
+    try
+      {
+	addr = VMInetAddress.lookupInaddrAny();
+      }
+    catch (UnknownHostException e)
+      {
+	// Make one up and hope it works.
+	addr = new byte[] {0, 0, 0, 0};
+      }
+    try
+      {
+	ANY_IF = getByAddress(addr);
+      }
+    catch (UnknownHostException e)
+      {
+	throw new RuntimeException("should never happen", e);
+      }
+    ANY_IF.hostName = ANY_IF.getHostName();
+  }
+  
+  /**
+   * The Serialized Form specifies that an int 'address' is saved/restored.
+   * This class uses a byte array internally so we'll just do the conversion
+   * at serialization time and leave the rest of the algorithm as is.
+   */
+  private int address;
+
+  /**
+   * An array of octets representing an IP address.
+   */
+  transient byte[] addr;
+
+  /**
+   * The name of the host for this address.
+   */
+  String hostName;
+
+  /**
+   * Needed for serialization.
+   */
+  private int family;
+
+  /**
+   * Constructor.  Prior to the introduction of IPv6 support in 1.4,
+   * methods such as InetAddress.getByName() would return InetAddress
+   * objects.  From 1.4 such methods returned either Inet4Address or
+   * Inet6Address objects, but for compatibility Inet4Address objects
+   * are serialized as InetAddresses.  As such, there are only two
+   * places where it is appropriate to invoke this constructor: within
+   * subclasses constructors and within Inet4Address.writeReplace().
+   *
+   * @param ipaddr The IP number of this address as an array of bytes
+   * @param hostname The hostname of this IP address.
+   * @param family The address family of this IP address.
+   */
+  InetAddress(byte[] ipaddr, String hostname, int family)
+  {
+    addr = (null == ipaddr) ? null : (byte[]) ipaddr.clone();
+    hostName = hostname;
+    this.family = family;
+  }
+
+  /**
+   * Returns true if this address is a multicast address, false otherwise.
+   * An address is multicast if the high four bits are "1110".  These are
+   * also known as "Class D" addresses.
+   *
+   * <p>This method cannot be abstract for backward compatibility reasons. By
+   * default it always throws {@link UnsupportedOperationException} unless
+   * overridden.</p>
+   * 
+   * @return true if mulitcast, false if not
+   *
+   * @since 1.1
+   */
+  public boolean isMulticastAddress()
+  {
+    // This method is masked on Posix systems, where all InetAddress
+    // objects are created using InetAddress.getByAddress() which 
+    // returns either Inet4Address or Inet6Address objects.  Certain
+    // native methods on Win32 use "new InetAddress" in which case
+    // this method will be visible.
+    try
+      {
+	return getByAddress(hostName, addr).isMulticastAddress();
+      }
+    catch (UnknownHostException e)
+      {
+	throw new RuntimeException("should never happen", e);
+      }
+  }
+
+  /**
+   * Utility routine to check if the InetAddress in a wildcard address
+   *
+   * <p>This method cannot be abstract for backward compatibility reasons. By
+   * default it always throws {@link UnsupportedOperationException} unless
+   * overridden.</p>
+   * 
+   * @since 1.4
+   */
+  public boolean isAnyLocalAddress()
+  {
+    // This is inefficient, but certain methods on Win32 create
+    // InetAddress objects using "new InetAddress" rather than
+    // "InetAddress.getByAddress" so we provide a method body.
+    // This code is never executed on Posix systems.
+    try
+      {
+	return getByAddress(hostName, addr).isAnyLocalAddress();
+      }
+    catch (UnknownHostException e)
+      {
+	throw new RuntimeException("should never happen", e);
+      }
+  }
+
+  /**
+   * Utility routine to check if the InetAddress is a loopback address
+   *
+   * <p>This method cannot be abstract for backward compatibility reasons. By
+   * default it always throws {@link UnsupportedOperationException} unless
+   * overridden.</p>
+   * 
+   * @since 1.4
+   */
+  public boolean isLoopbackAddress()
+  {
+    // This method is masked on Posix systems, where all InetAddress
+    // objects are created using InetAddress.getByAddress() which 
+    // returns either Inet4Address or Inet6Address objects.  Certain
+    // native methods on Win32 use "new InetAddress" in which case
+    // this method will be visible.
+    try
+      {
+	return getByAddress(hostName, addr).isLoopbackAddress();
+      }
+    catch (UnknownHostException e)
+      {
+	throw new RuntimeException("should never happen", e);
+      }
+  }
+
+  /**
+   * Utility routine to check if InetAddress is a link local address
+   *
+   * <p>This method cannot be abstract for backward compatibility reasons. By
+   * default it always throws {@link UnsupportedOperationException} unless
+   * overridden.</p>
+   * 
+   * @since 1.4
+   */
+  public boolean isLinkLocalAddress()
+  {
+    // This method is masked on Posix systems, where all InetAddress
+    // objects are created using InetAddress.getByAddress() which 
+    // returns either Inet4Address or Inet6Address objects.  Certain
+    // native methods on Win32 use "new InetAddress" in which case
+    // this method will be visible.
+    try
+      {
+	return getByAddress(hostName, addr).isLinkLocalAddress();
+      }
+    catch (UnknownHostException e)
+      {
+	throw new RuntimeException("should never happen", e);
+      }
+  }
+
+  /**
+   * Utility routine to check if InetAddress is a site local address
+   *
+   * <p>This method cannot be abstract for backward compatibility reasons. By
+   * default it always throws {@link UnsupportedOperationException} unless
+   * overridden.</p>
+   * 
+   * @since 1.4
+   */
+  public boolean isSiteLocalAddress()
+  {
+    // This method is masked on Posix systems, where all InetAddress
+    // objects are created using InetAddress.getByAddress() which 
+    // returns either Inet4Address or Inet6Address objects.  Certain
+    // native methods on Win32 use "new InetAddress" in which case
+    // this method will be visible.
+    try
+      {
+	return getByAddress(hostName, addr).isSiteLocalAddress();
+      }
+    catch (UnknownHostException e)
+      {
+	throw new RuntimeException("should never happen", e);
+      }
+  }
+
+  /**
+   * Utility routine to check if InetAddress is a global multicast address
+   *
+   * <p>This method cannot be abstract for backward compatibility reasons. By
+   * default it always throws {@link UnsupportedOperationException} unless
+   * overridden.</p>
+   * 
+   * @since 1.4
+   */
+  public boolean isMCGlobal()
+  {
+    // This method is masked on Posix systems, where all InetAddress
+    // objects are created using InetAddress.getByAddress() which 
+    // returns either Inet4Address or Inet6Address objects.  Certain
+    // native methods on Win32 use "new InetAddress" in which case
+    // this method will be visible.
+    try
+      {
+	return getByAddress(hostName, addr).isMCGlobal();
+      }
+    catch (UnknownHostException e)
+      {
+	throw new RuntimeException("should never happen", e);
+      }
+  }
+
+  /**
+   * Utility routine to check if InetAddress is a node local multicast address.
+   *
+   * <p>This method cannot be abstract for backward compatibility reasons. By
+   * default it always throws {@link UnsupportedOperationException} unless
+   * overridden.</p>
+   * 
+   * @since 1.4
+   */
+  public boolean isMCNodeLocal()
+  {
+    // This method is masked on Posix systems, where all InetAddress
+    // objects are created using InetAddress.getByAddress() which 
+    // returns either Inet4Address or Inet6Address objects.  Certain
+    // native methods on Win32 use "new InetAddress" in which case
+    // this method will be visible.
+    try
+      {
+	return getByAddress(hostName, addr).isMCNodeLocal();
+      }
+    catch (UnknownHostException e)
+      {
+	throw new RuntimeException("should never happen", e);
+      }
+  }
+
+  /**
+   * Utility routine to check if InetAddress is a link local multicast address.
+   *
+   * <p>This method cannot be abstract for backward compatibility reasons. By
+   * default it always throws {@link UnsupportedOperationException} unless
+   * overridden.</p>
+   * 
+   * @since 1.4
+   */
+  public boolean isMCLinkLocal()
+  {
+    // This method is masked on Posix systems, where all InetAddress
+    // objects are created using InetAddress.getByAddress() which 
+    // returns either Inet4Address or Inet6Address objects.  Certain
+    // native methods on Win32 use "new InetAddress" in which case
+    // this method will be visible.
+    try
+      {
+	return getByAddress(hostName, addr).isMCLinkLocal();
+      }
+    catch (UnknownHostException e)
+      {
+	throw new RuntimeException("should never happen", e);
+      }
+  }
+
+  /**
+   * Utility routine to check if InetAddress is a site local multicast address.
+   *
+   * <p>This method cannot be abstract for backward compatibility reasons. By
+   * default it always throws {@link UnsupportedOperationException} unless
+   * overridden.</p>
+   * 
+   * @since 1.4
+   */
+  public boolean isMCSiteLocal()
+  {
+    // This method is masked on Posix systems, where all InetAddress
+    // objects are created using InetAddress.getByAddress() which 
+    // returns either Inet4Address or Inet6Address objects.  Certain
+    // native methods on Win32 use "new InetAddress" in which case
+    // this method will be visible.
+    try
+      {
+	return getByAddress(hostName, addr).isMCSiteLocal();
+      }
+    catch (UnknownHostException e)
+      {
+	throw new RuntimeException("should never happen", e);
+      }
+  }
+
+  /**
+   * Utility routine to check if InetAddress is a organization local
+   * multicast address.
+   *
+   * <p>This method cannot be abstract for backward compatibility reasons. By
+   * default it always throws {@link UnsupportedOperationException} unless
+   * overridden.</p>
+   * 
+   * @since 1.4
+   */
+  public boolean isMCOrgLocal()
+  {
+    // This method is masked on Posix systems, where all InetAddress
+    // objects are created using InetAddress.getByAddress() which 
+    // returns either Inet4Address or Inet6Address objects.  Certain
+    // native methods on Win32 use "new InetAddress" in which case
+    // this method will be visible.
+    try
+      {
+	return getByAddress(hostName, addr).isMCOrgLocal();
+      }
+    catch (UnknownHostException e)
+      {
+	throw new RuntimeException("should never happen", e);
+      }
+  }
+
+  /**
+   * Returns the hostname for this address.  This will return the IP address
+   * as a String if there is no hostname available for this address
+   *
+   * @return The hostname for this address
+   */
+  public String getHostName()
+  {
+    if (hostName == null)
+      hostName = getCanonicalHostName();
+
+    return hostName;
+  }
+
+  /**
+   * Returns the canonical hostname represented by this InetAddress
+   */
+  String internalGetCanonicalHostName()
+  {
+    try
+      {
+	return ResolverCache.getHostByAddr(addr);
+      }
+    catch (UnknownHostException e)
+      {
+	return getHostAddress();
+      }
+  }
+
+  /**
+   * Returns the canonical hostname represented by this InetAddress
+   * 
+   * @since 1.4
+   */
+  public String getCanonicalHostName()
+  {
+    String hostname = internalGetCanonicalHostName();
+
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      {
+        try
+	  {
+            sm.checkConnect(hostname, -1);
+	  }
+	catch (SecurityException e)
+	  {
+	    return getHostAddress();
+	  }
+      }
+
+    return hostname;
+  }
+
+  /**
+   * Returns the IP address of this object as a byte array.
+   *
+   * @return IP address
+   */
+  public byte[] getAddress()
+  {
+    // An experiment shows that JDK1.2 returns a different byte array each
+    // time.  This makes sense, in terms of security.
+    return (byte[]) addr.clone();
+  }
+
+  /**
+   * Returns the IP address of this object as a String.
+   *
+   * <p>This method cannot be abstract for backward compatibility reasons. By
+   * default it always throws {@link UnsupportedOperationException} unless
+   * overridden.</p>
+   * 
+   * @return The IP address of this object in String form
+   *
+   * @since 1.0.2
+   */
+  public String getHostAddress()
+  {
+    // This method is masked on Posix systems, where all InetAddress
+    // objects are created using InetAddress.getByAddress() which 
+    // returns either Inet4Address or Inet6Address objects.  Certain
+    // native methods on Win32 use "new InetAddress" in which case
+    // this method will be visible.
+    try
+      {
+	return getByAddress(hostName, addr).getHostAddress();
+      }
+    catch (UnknownHostException e)
+      {
+	throw new RuntimeException("should never happen", e);
+      }
+  }
+
+  /**
+   * Returns a hash value for this address.  Useful for creating hash
+   * tables.  Overrides Object.hashCode()
+   *
+   * @return A hash value for this address.
+   */
+  public int hashCode()
+  {
+    // There hashing algorithm is not specified, but a simple experiment
+    // shows that it is equal to the address, as a 32-bit big-endian integer.
+    int hash = 0;
+    int len = addr.length;
+    int i = len > 4 ? len - 4 : 0;
+
+    for (; i < len; i++)
+      hash = (hash << 8) | (addr[i] & 0xff);
+
+    return hash;
+  }
+
+  /**
+   * Tests this address for equality against another InetAddress.  The two
+   * addresses are considered equal if they contain the exact same octets.
+   * This implementation overrides Object.equals()
+   *
+   * @param obj The address to test for equality
+   *
+   * @return true if the passed in object's address is equal to this one's,
+   * false otherwise
+   */
+  public boolean equals(Object obj)
+  {
+    if (! (obj instanceof InetAddress))
+      return false;
+
+    // "The Java Class Libraries" 2nd edition says "If a machine has
+    // multiple names instances of InetAddress for different name of
+    // that same machine are not equal.  This is because they have
+    // different host names."  This violates the description in the
+    // JDK 1.2 API documentation.  A little experimentation
+    // shows that the latter is correct.
+    byte[] addr2 = ((InetAddress) obj).addr;
+
+    if (addr.length != addr2.length)
+      return false;
+
+    for (int i = 0; i < addr.length; i++)
+      if (addr[i] != addr2[i])
+	return false;
+
+    return true;
+  }
+
+  /**
+   * Converts this address to a String.  This string contains the IP in
+   * dotted decimal form. For example: "127.0.0.1"  This method is equivalent
+   * to getHostAddress() and overrides Object.toString()
+   *
+   * @return This address in String form
+   */
+  public String toString()
+  {
+    String addr = getHostAddress();
+    String host = (hostName != null) ? hostName : "";
+    return host + "/" + addr;
+  }
+
+  /**
+   * Returns an InetAddress object given the raw IP address.
+   *
+   * The argument is in network byte order: the highest order byte of the
+   * address is in getAddress()[0].
+   *
+   * @param addr The IP address to create the InetAddress object from
+   *
+   * @exception UnknownHostException If IP address has illegal length
+   *
+   * @since 1.4
+   */
+  public static InetAddress getByAddress(byte[] addr)
+    throws UnknownHostException
+  {
+    return getByAddress(null, addr);
+  }
+
+  /**
+   * Creates an InetAddress based on the provided host name and IP address.
+   * No name service is checked for the validity of the address.
+   *
+   * @param host The hostname of the InetAddress object to create
+   * @param addr The IP address to create the InetAddress object from
+   *
+   * @exception UnknownHostException If IP address is of illegal length
+   *
+   * @since 1.4
+   */
+  public static InetAddress getByAddress(String host, byte[] addr)
+    throws UnknownHostException
+  {
+    if (addr.length == 4)
+      return new Inet4Address(addr, host);
+
+    if (addr.length == 16)
+      {
+	for (int i = 0; i < 12; i++)
+	  {
+	    if (addr[i] != (i < 10 ? 0 : (byte) 0xFF))
+	      return new Inet6Address(addr, host);
+	  }
+	  
+	byte[] ip4addr = new byte[4];
+	ip4addr[0] = addr[12];
+	ip4addr[1] = addr[13];
+	ip4addr[2] = addr[14];
+	ip4addr[3] = addr[15];
+	return new Inet4Address(ip4addr, host);
+      }
+
+    throw new UnknownHostException("IP address has illegal length");
+  }
+
+  /**
+   * Returns an InetAddress object representing the IP address of
+   * the given literal IP address in dotted decimal format such as
+   * "127.0.0.1".  This is used by SocketPermission.setHostPort()
+   * to parse literal IP addresses without performing a DNS lookup.
+   *
+   * @param literal The literal IP address to create the InetAddress
+   * object from
+   *
+   * @return The address of the host as an InetAddress object, or
+   * null if the IP address is invalid.
+   */
+  static InetAddress getByLiteral(String literal)
+  {
+    byte[] address = VMInetAddress.aton(literal);
+    if (address == null)
+      return null;
+    
+    try
+      {
+	return getByAddress(address);
+      }
+    catch (UnknownHostException e)
+      {
+	throw new RuntimeException("should never happen", e);
+      }
+  }
+
+  /**
+   * Returns an InetAddress object representing the IP address of the given
+   * hostname.  This name can be either a hostname such as "www.urbanophile.com"
+   * or an IP address in dotted decimal format such as "127.0.0.1".  If the
+   * hostname is null or "", the hostname of the local machine is supplied by
+   * default.  This method is equivalent to returning the first element in
+   * the InetAddress array returned from GetAllByName.
+   *
+   * @param hostname The name of the desired host, or null for the local 
+   * loopback address.
+   *
+   * @return The address of the host as an InetAddress object.
+   *
+   * @exception UnknownHostException If no IP address for the host could
+   * be found
+   * @exception SecurityException If a security manager exists and its
+   * checkConnect method doesn't allow the operation
+   */
+  public static InetAddress getByName(String hostname)
+    throws UnknownHostException
+  {
+    InetAddress[] addresses = getAllByName(hostname);
+    return addresses[0];
+  }
+
+  /**
+   * Returns an array of InetAddress objects representing all the host/ip
+   * addresses of a given host, given the host's name.  This name can be
+   * either a hostname such as "www.urbanophile.com" or an IP address in
+   * dotted decimal format such as "127.0.0.1".  If the value is null, the
+   * hostname of the local machine is supplied by default.
+   *
+   * @param hostname The name of the desired host, or null for the
+   * local loopback address.
+   *
+   * @return All addresses of the host as an array of InetAddress objects.
+   *
+   * @exception UnknownHostException If no IP address for the host could
+   * be found
+   * @exception SecurityException If a security manager exists and its
+   * checkConnect method doesn't allow the operation
+   */
+  public static InetAddress[] getAllByName(String hostname)
+    throws UnknownHostException
+  {
+    // If null or the empty string is supplied, the loopback address
+    // is returned.
+    if (hostname == null || hostname.length() == 0)
+      return new InetAddress[] {LOCALHOST};
+
+    // Check if hostname is an IP address
+    InetAddress address = getByLiteral(hostname);
+    if (address != null)
+      return new InetAddress[] {address};
+
+    // Perform security check before resolving
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      sm.checkConnect(hostname, -1);
+
+    // Resolve the hostname
+    byte[][] iplist = ResolverCache.getHostByName(hostname);
+    if (iplist.length == 0)
+      throw new UnknownHostException(hostname);
+
+    InetAddress[] addresses = new InetAddress[iplist.length];
+    for (int i = 0; i < iplist.length; i++)
+      addresses[i] = getByAddress(hostname, iplist[i]);
+
+    return addresses;
+  }
+
+  /**
+   * Returns an InetAddress object representing the address of the current
+   * host.
+   *
+   * @return The local host's address
+   *
+   * @exception UnknownHostException If no IP address for the host could
+   * be found
+   */
+  public static InetAddress getLocalHost() throws UnknownHostException
+  {
+    String hostname = VMInetAddress.getLocalHostname();
+    try
+      {
+	return getByName(hostname);
+      }
+    catch (SecurityException e)
+      {
+	return LOCALHOST;
+      }
+  }
+
+  /**
+   * Inet4Address objects are serialized as InetAddress objects.
+   * This deserializes them back into Inet4Address objects.
+   */
+  private Object readResolve() throws ObjectStreamException
+  {
+    return new Inet4Address(addr, hostName);
+  }
+
+  private void readObject(ObjectInputStream ois)
+    throws IOException, ClassNotFoundException
+  {
+    ois.defaultReadObject();
+    addr = new byte[4];
+    addr[3] = (byte) address;
+
+    for (int i = 2; i >= 0; --i)
+      addr[i] = (byte) (address >>= 8);
+  }
+
+  private void writeObject(ObjectOutputStream oos) throws IOException
+  {
+    // Build a 32 bit address from the last 4 bytes of a 4 byte IPv4 address
+    // or a 16 byte IPv6 address.
+    int len = addr.length;
+    int i = len - 4;
+
+    for (; i < len; i++)
+      address = address << 8 | (addr[i] & 0xff);
+
+    oos.defaultWriteObject();
+  }
+
+  // The native methods remain here for now;
+  // methods in VMInetAddress map onto them.
+  static native byte[] aton(String hostname);
+  static native InetAddress[] lookup (String hostname,
+				      InetAddress ipaddr, boolean all);
+  static native int getFamily (byte[] ipaddr);
+  static native String getLocalHostname();
+
+  // Some soon-to-be-removed native code synchronizes on this.
+  static InetAddress loopbackAddress;
+  
+  // Some soon-to-be-removed code uses this old and broken method.
+  InetAddress(byte[] ipaddr, String hostname)
+  {
+    addr = (null == ipaddr) ? null : (byte[]) ipaddr.clone();
+    hostName = hostname;
+
+    if (ipaddr != null)
+      family = getFamily(ipaddr);
+  }
+
+  // Some soon-to-be-removed native code uses these old methods.
+  private static InetAddress[] allocArray (int count)
+  {
+    return new InetAddress [count];
+  }  
+  private static SecurityException checkConnect (String hostname)
+  {
+    return null;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/net/URL.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/net/URL.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/net/URL.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/net/URL.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,974 @@
+/* URL.java -- Uniform Resource Locator Class
+   Copyright (C) 1998, 1999, 2000, 2002, 2003, 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.net;
+
+import gnu.java.net.URLParseError;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+import java.util.StringTokenizer;
+
+
+/*
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status:  Believed complete and correct.
+ */
+
+/**
+  * This final class represents an Internet Uniform Resource Locator (URL).
+  * For details on the syntax of URL's and what they can be used for,
+  * refer to RFC 1738, available from <a
+  * href="http://ds.internic.net/rfcs/rfc1738.txt">
+  * http://ds.internic.net/rfcs/rfc1738.txt</a>
+  * <p>
+  * There are a great many protocols supported by URL's such as "http",
+  * "ftp", and "file".  This object can handle any arbitrary URL for which
+  * a URLStreamHandler object can be written.  Default protocol handlers
+  * are provided for the "http" and "ftp" protocols.  Additional protocols
+  * handler implementations may be provided in the future.  In any case,
+  * an application or applet can install its own protocol handlers that
+  * can be "chained" with other protocol hanlders in the system to extend
+  * the base functionality provided with this class. (Note, however, that
+  * unsigned applets cannot access properties by default or install their
+  * own protocol handlers).
+  * <p>
+  * This chaining is done via the system property java.protocol.handler.pkgs
+  * If this property is set, it is assumed to be a "|" separated list of
+  * package names in which to attempt locating protocol handlers.  The
+  * protocol handler is searched for by appending the string
+  * ".<protocol>.Handler" to each packed in the list until a hander is
+  * found. If a protocol handler is not found in this list of packages, or if
+  * the property does not exist, then the default protocol handler of
+  * "gnu.java.net.<protocol>.Handler" is tried.  If this is
+  * unsuccessful, a MalformedURLException is thrown.
+  * <p>
+  * All of the constructor methods of URL attempt to load a protocol
+  * handler and so any needed protocol handlers must be installed when
+  * the URL is constructed.
+  * <p>
+  * Here is an example of how URL searches for protocol handlers.  Assume
+  * the value of java.protocol.handler.pkgs is "com.foo|com.bar" and the
+  * URL is "news://comp.lang.java.programmer".  URL would looking the
+  * following places for protocol handlers:
+  * <p><pre>
+  * com.foo.news.Handler
+  * com.bar.news.Handler
+  * gnu.java.net.news.Handler
+  * </pre><p>
+  * If the protocol handler is not found in any of those locations, a
+  * MalformedURLException would be thrown.
+  * <p>
+  * Please note that a protocol handler must be a subclass of
+  * URLStreamHandler.
+  * <p>
+  * Normally, this class caches protocol handlers.  Once it finds a handler
+  * for a particular protocol, it never tries to look up a new handler
+  * again.  However, if the system property
+  * gnu.java.net.nocache_protocol_handlers is set, then this
+  * caching behavior is disabled.  This property is specific to this
+  * implementation.  Sun's JDK may or may not do protocol caching, but it
+  * almost certainly does not examine this property.
+  * <p>
+  * Please also note that an application can install its own factory for
+  * loading protocol handlers (see setURLStreamHandlerFactory).  If this is
+  * done, then the above information is superseded and the behavior of this
+  * class in loading protocol handlers is dependent on that factory.
+  *
+  * @author Aaron M. Renn (arenn at urbanophile.com)
+  * @author Warren Levy (warrenl at cygnus.com)
+  *
+  * @see URLStreamHandler
+  */
+public final class URL implements Serializable
+{
+  private static final String DEFAULT_SEARCH_PATH =
+    "gnu.java.net.protocol|gnu.inet";
+
+  // Cached System ClassLoader
+  private static ClassLoader systemClassLoader;
+
+  /**
+   * The name of the protocol for this URL.
+   * The protocol is always stored in lower case.
+   */
+  private String protocol;
+
+  /**
+   * The "authority" portion of the URL.
+   */
+  private String authority;
+
+  /**
+   * The hostname or IP address of this protocol.
+   * This includes a possible user. For example <code>joe at some.host.net</code>.
+   */
+  private String host;
+
+  /**
+   * The user information necessary to establish the connection.
+   */
+  private String userInfo;
+
+  /**
+   * The port number of this protocol or -1 if the port number used is
+   * the default for this protocol.
+   */
+  private int port = -1; // Initialize for constructor using context.
+
+  /**
+   * The "file" portion of the URL. It is defined as <code>path[?query]</code>.
+   */
+  private String file;
+
+  /**
+   * The anchor portion of the URL.
+   */
+  private String ref;
+
+  /**
+   * This is the hashCode for this URL
+   */
+  private int hashCode;
+
+  /**
+   * The protocol handler in use for this URL
+   */
+  transient URLStreamHandler ph;
+
+  /**
+   * If an application installs its own protocol handler factory, this is
+   * where we keep track of it.
+   */
+  private static URLStreamHandlerFactory factory;
+  private static final long serialVersionUID = -7627629688361524110L;
+
+  /**
+   * This a table where we cache protocol handlers to avoid the overhead
+   * of looking them up each time.
+   */
+  private static HashMap ph_cache = new HashMap();
+
+  /**
+   * Whether or not to cache protocol handlers.
+   */
+  private static boolean cache_handlers;
+
+  static
+    {
+      String s = System.getProperty("gnu.java.net.nocache_protocol_handlers");
+
+      if (s == null)
+	cache_handlers = true;
+      else
+	cache_handlers = false;
+    }
+
+  /**
+   * Constructs a URL and loads a protocol handler for the values passed as
+   * arguments.
+   *
+   * @param protocol The protocol for this URL ("http", "ftp", etc)
+   * @param host The hostname or IP address to connect to
+   * @param port The port number to use, or -1 to use the protocol's
+   * default port
+   * @param file The "file" portion of the URL.
+   *
+   * @exception MalformedURLException If a protocol handler cannot be loaded or
+   * a parse error occurs.
+   */
+  public URL(String protocol, String host, int port, String file)
+    throws MalformedURLException
+  {
+    this(protocol, host, port, file, null);
+  }
+
+  /**
+   * Constructs a URL and loads a protocol handler for the values passed in
+   * as arugments.  Uses the default port for the protocol.
+   *
+   * @param protocol The protocol for this URL ("http", "ftp", etc)
+   * @param host The hostname or IP address for this URL
+   * @param file The "file" portion of this URL.
+   *
+   * @exception MalformedURLException If a protocol handler cannot be loaded or
+   * a parse error occurs.
+   */
+  public URL(String protocol, String host, String file)
+    throws MalformedURLException
+  {
+    this(protocol, host, -1, file, null);
+  }
+
+  /**
+   * This method initializes a new instance of <code>URL</code> with the
+   * specified protocol, host, port, and file.  Additionally, this method
+   * allows the caller to specify a protocol handler to use instead of
+   * the default.  If this handler is specified, the caller must have
+   * the "specifyStreamHandler" permission (see <code>NetPermission</code>)
+   * or a <code>SecurityException</code> will be thrown.
+   *
+   * @param protocol The protocol for this URL ("http", "ftp", etc)
+   * @param host The hostname or IP address to connect to
+   * @param port The port number to use, or -1 to use the protocol's default
+   * port
+   * @param file The "file" portion of the URL.
+   * @param ph The protocol handler to use with this URL.
+   *
+   * @exception MalformedURLException If no protocol handler can be loaded
+   * for the specified protocol.
+   * @exception SecurityException If the <code>SecurityManager</code> exists
+   * and does not allow the caller to specify its own protocol handler.
+   *
+   * @since 1.2
+   */
+  public URL(String protocol, String host, int port, String file,
+             URLStreamHandler ph) throws MalformedURLException
+  {
+    if (protocol == null)
+      throw new MalformedURLException("null protocol");
+    protocol = protocol.toLowerCase();
+    this.protocol = protocol;
+
+    if (ph != null)
+      {
+	SecurityManager s = System.getSecurityManager();
+	if (s != null)
+	  s.checkPermission(new NetPermission("specifyStreamHandler"));
+
+	this.ph = ph;
+      }
+    else
+      this.ph = getURLStreamHandler(protocol);
+
+    if (this.ph == null)
+      throw new MalformedURLException("Protocol handler not found: "
+                                      + protocol);
+
+    this.host = host;
+    this.port = port;
+    this.authority = (host != null) ? host : "";
+    if (port >= 0 && host != null)
+	this.authority += ":" + port;
+
+    int hashAt = file.indexOf('#');
+    if (hashAt < 0)
+      {
+	this.file = file;
+	this.ref = null;
+      }
+    else
+      {
+	this.file = file.substring(0, hashAt);
+	this.ref = file.substring(hashAt + 1);
+      }
+    hashCode = hashCode(); // Used for serialization.
+  }
+
+  /**
+   * Initializes a URL from a complete string specification such as
+   * "http://www.urbanophile.com/arenn/".  First the protocol name is parsed
+   * out of the string.  Then a handler is located for that protocol and
+   * the parseURL() method of that protocol handler is used to parse the
+   * remaining fields.
+   *
+   * @param spec The complete String representation of a URL
+   *
+   * @exception MalformedURLException If a protocol handler cannot be found
+   * or the URL cannot be parsed
+   */
+  public URL(String spec) throws MalformedURLException
+  {
+    this((URL) null, spec != null ? spec : "", (URLStreamHandler) null);
+  }
+
+  /**
+   * This method parses a String representation of a URL within the
+   * context of an existing URL.  Principally this means that any
+   * fields not present the URL are inheritied from the context URL.
+   * This allows relative URL's to be easily constructed.  If the
+   * context argument is null, then a complete URL must be specified
+   * in the URL string.  If the protocol parsed out of the URL is
+   * different from the context URL's protocol, then then URL String
+   * is also expected to be a complete URL.
+   *
+   * @param context The context on which to parse the specification
+   * @param spec The string to parse an URL
+   *
+   * @exception MalformedURLException If a protocol handler cannot be found
+   * for the URL cannot be parsed
+   */
+  public URL(URL context, String spec) throws MalformedURLException
+  {
+    this(context, spec, (URLStreamHandler) null);
+  }
+
+  /**
+   * Creates an URL from given arguments
+   * This method parses a String representation of a URL within the
+   * context of an existing URL.  Principally this means that any fields
+   * not present the URL are inheritied from the context URL.  This allows
+   * relative URL's to be easily constructed.  If the context argument is
+   * null, then a complete URL must be specified in the URL string.
+   * If the protocol parsed out of the URL is different
+   * from the context URL's protocol, then then URL String is also
+   * expected to be a complete URL.
+   * <p>
+   * Additionally, this method allows the caller to specify a protocol handler
+   * to use instead of  the default.  If this handler is specified, the caller
+   * must have the "specifyStreamHandler" permission
+   * (see <code>NetPermission</code>) or a <code>SecurityException</code>
+   * will be thrown.
+   *
+   * @param context The context in which to parse the specification
+   * @param spec The string to parse as an URL
+   * @param ph The stream handler for the URL
+   *
+   * @exception MalformedURLException If a protocol handler cannot be found
+   * or the URL cannot be parsed
+   * @exception SecurityException If the <code>SecurityManager</code> exists
+   * and does not allow the caller to specify its own protocol handler.
+   *
+   * @since 1.2
+   */
+  public URL(URL context, String spec, URLStreamHandler ph)
+    throws MalformedURLException
+  {
+    /* A protocol is defined by the doc as the substring before a ':'
+     * as long as the ':' occurs before any '/'.
+     *
+     * If context is null, then spec must be an absolute URL.
+     *
+     * The relative URL need not specify all the components of a URL.
+     * If the protocol, host name, or port number is missing, the value
+     * is inherited from the context.  A bare file component is appended
+     * to the context's file.  The optional anchor is not inherited.
+     */
+
+    // If this is an absolute URL, then ignore context completely.
+    // An absolute URL must have chars prior to "://" but cannot have a colon
+    // right after the "://".  The second colon is for an optional port value
+    // and implies that the host from the context is used if available.
+    int colon;
+    int slash = spec.indexOf('/');
+    if ((colon = spec.indexOf("://", 1)) > 0
+	&& ((colon < slash || slash < 0))
+        && ! spec.regionMatches(colon, "://:", 0, 4))
+      context = null;
+
+    if ((colon = spec.indexOf(':')) > 0
+        && (colon < slash || slash < 0))
+      {
+	// Protocol specified in spec string.
+	protocol = spec.substring(0, colon).toLowerCase();
+	if (context != null && context.protocol.equals(protocol))
+	  {
+	    // The 1.2 doc specifically says these are copied to the new URL.
+	    host = context.host;
+	    port = context.port;
+            userInfo = context.userInfo;
+	    authority = context.authority;
+	  }
+      }
+    else if (context != null)
+      {
+	// Protocol NOT specified in spec string.
+	// Use context fields (except ref) as a foundation for relative URLs.
+	colon = -1;
+	protocol = context.protocol;
+	host = context.host;
+	port = context.port;
+        userInfo = context.userInfo;
+	if (spec.indexOf(":/", 1) < 0)
+	  {
+	    file = context.file;
+	    if (file == null || file.length() == 0)
+	      file = "/";
+	  }
+	authority = context.authority;
+      }
+    else // Protocol NOT specified in spec. and no context available.
+      throw new MalformedURLException("Absolute URL required with null"
+				      + " context: " + spec);
+
+    protocol = protocol.trim();
+
+    if (ph != null)
+      {
+	SecurityManager s = System.getSecurityManager();
+	if (s != null)
+	  s.checkPermission(new NetPermission("specifyStreamHandler"));
+
+	this.ph = ph;
+      }
+    else
+      this.ph = getURLStreamHandler(protocol);
+
+    if (this.ph == null)
+      throw new MalformedURLException("Protocol handler not found: "
+                                      + protocol);
+
+    // JDK 1.2 doc for parseURL specifically states that any '#' ref
+    // is to be excluded by passing the 'limit' as the indexOf the '#'
+    // if one exists, otherwise pass the end of the string.
+    int hashAt = spec.indexOf('#', colon + 1);
+
+    try
+      {
+	this.ph.parseURL(this, spec, colon + 1,
+	                 hashAt < 0 ? spec.length() : hashAt);
+      }
+    catch (URLParseError e)
+      {
+	throw new MalformedURLException(e.getMessage());
+      }
+
+    if (hashAt >= 0)
+      ref = spec.substring(hashAt + 1);
+
+    hashCode = hashCode(); // Used for serialization.
+  }
+
+  /**
+   * Test another URL for equality with this one.  This will be true only if
+   * the argument is non-null and all of the fields in the URL's match
+   * exactly (ie, protocol, host, port, file, and ref).  Overrides
+   * Object.equals(), implemented by calling the equals method of the handler.
+   *
+   * @param obj The URL to compare with
+   *
+   * @return true if the URL is equal, false otherwise
+   */
+  public boolean equals(Object obj)
+  {
+    if (! (obj instanceof URL))
+      return false;
+
+    return ph.equals(this, (URL) obj);
+  }
+
+  /**
+   * Returns the contents of this URL as an object by first opening a
+   * connection, then calling the getContent() method against the connection
+   *
+   * @return A content object for this URL
+   * @exception IOException If opening the connection or getting the
+   * content fails.
+   *
+   * @since 1.3
+   */
+  public Object getContent() throws IOException
+  {
+    return openConnection().getContent();
+  }
+
+  /**
+   * Gets the contents of this URL
+   *
+   * @param classes The allow classes for the content object.
+   *
+   * @return a context object for this URL.
+   *
+   * @exception IOException If an error occurs
+   */
+  public Object getContent(Class[] classes) throws IOException
+  {
+    // FIXME: implement this
+    return getContent();
+  }
+
+  /**
+   * Returns the file portion of the URL.
+   * Defined as <code>path[?query]</code>.
+   * Returns the empty string if there is no file portion.
+   *
+   * @return The filename specified in this URL, or an empty string if empty.
+   */
+  public String getFile()
+  {
+    return file == null ? "" : file;
+  }
+
+  /**
+   * Returns the path of the URL. This is the part of the file before any '?'
+   * character.
+   *
+   * @return The path specified in this URL, or null if empty.
+   *
+   * @since 1.3
+   */
+  public String getPath()
+  {
+    // The spec says we need to return an empty string, but some
+    // applications depends on receiving null when the path is empty.
+    if (file == null)
+      return null;
+    int quest = file.indexOf('?');
+    return quest < 0 ? getFile() : file.substring(0, quest);
+  }
+
+  /**
+   * Returns the authority of the URL
+   *
+   * @return The authority specified in this URL.
+   *
+   * @since 1.3
+   */
+  public String getAuthority()
+  {
+    return authority;
+  }
+
+  /**
+   * Returns the host of the URL
+   *
+   * @return The host specified in this URL.
+   */
+  public String getHost()
+  {
+    int at = (host == null) ? -1 : host.indexOf('@');
+    return at < 0 ? host : host.substring(at + 1, host.length());
+  }
+
+  /**
+   * Returns the port number of this URL or -1 if the default port number is
+   * being used.
+   *
+   * @return The port number
+   *
+   * @see #getDefaultPort()
+   */
+  public int getPort()
+  {
+    return port;
+  }
+
+  /**
+   * Returns the default port of the URL. If the StreamHandler for the URL
+   * protocol does not define a default port it returns -1.
+   *
+   * @return The default port of the current protocol.
+   */
+  public int getDefaultPort()
+  {
+    return ph.getDefaultPort();
+  }
+
+  /**
+   * Returns the protocol of the URL
+   *
+   * @return The specified protocol.
+   */
+  public String getProtocol()
+  {
+    return protocol;
+  }
+
+  /**
+   * Returns the ref (sometimes called the "# reference" or "anchor") portion
+   * of the URL.
+   *
+   * @return The ref
+   */
+  public String getRef()
+  {
+    return ref;
+  }
+
+  /**
+   * Returns the user information of the URL. This is the part of the host
+   * name before the '@'.
+   *
+   * @return the user at a particular host or null when no user defined.
+   */
+  public String getUserInfo()
+  {
+    if (userInfo != null)
+      return userInfo;
+    int at = (host == null) ? -1 : host.indexOf('@');
+    return at < 0 ? null : host.substring(0, at);
+  }
+
+  /**
+   * Returns the query of the URL. This is the part of the file before the
+   * '?'.
+   *
+   * @return the query part of the file, or null when there is no query part.
+   */
+  public String getQuery()
+  {
+    int quest = (file == null) ? -1 : file.indexOf('?');
+    return quest < 0 ? null : file.substring(quest + 1, file.length());
+  }
+
+  /**
+   * Returns a hashcode computed by the URLStreamHandler of this URL
+   *
+   * @return The hashcode for this URL.
+   */
+  public int hashCode()
+  {
+    if (hashCode != 0)
+      return hashCode; // Use cached value if available.
+    else
+      return ph.hashCode(this);
+  }
+
+  /**
+   * Returns a URLConnection object that represents a connection to the remote
+   * object referred to by the URL. The URLConnection is created by calling the
+   * openConnection() method of the protocol handler
+   *
+   * @return A URLConnection for this URL
+   *
+   * @exception IOException If an error occurs
+   */
+  public URLConnection openConnection() throws IOException
+  {
+    return ph.openConnection(this);
+  }
+
+  /**
+   * Opens a connection to this URL and returns an InputStream for reading
+   * from that connection
+   *
+   * @return An <code>InputStream</code> for this URL.
+   *
+   * @exception IOException If an error occurs
+   */
+  public InputStream openStream() throws IOException
+  {
+    return openConnection().getInputStream();
+  }
+
+  /**
+   * Tests whether or not another URL refers to the same "file" as this one.
+   * This will be true if and only if the passed object is not null, is a
+   * URL, and matches all fields but the ref (ie, protocol, host, port,
+   * and file);
+   *
+   * @param url The URL object to test with
+   *
+   * @return true if URL matches this URL's file, false otherwise
+   */
+  public boolean sameFile(URL url)
+  {
+    return ph.sameFile(this, url);
+  }
+
+  /**
+   * Sets the specified fields of the URL. This is not a public method so
+   * that only URLStreamHandlers can modify URL fields. This might be called
+   * by the <code>parseURL()</code> method in that class. URLs are otherwise
+   * constant. If the given protocol does not exist, it will keep the previously
+   * set protocol.
+   *
+   * @param protocol The protocol name for this URL
+   * @param host The hostname or IP address for this URL
+   * @param port The port number of this URL
+   * @param file The "file" portion of this URL.
+   * @param ref The anchor portion of this URL.
+   */
+  protected void set(String protocol, String host, int port, String file,
+                     String ref)
+  {
+    URLStreamHandler protocolHandler = null;
+    protocol = protocol.toLowerCase();
+    if (! this.protocol.equals(protocol))
+      protocolHandler = getURLStreamHandler(protocol);
+    
+    // It is an hidden feature of the JDK. If the protocol does not exist,
+    // we keep the previously initialized protocol.
+    if (protocolHandler != null)
+      {
+	this.ph = protocolHandler;
+	this.protocol = protocol;
+      }
+    this.authority = "";
+    this.port = port;
+    this.host = host;
+    this.file = file;
+    this.ref = ref;
+
+    if (host != null)
+      this.authority += host;
+    if (port >= 0)
+      this.authority += ":" + port;
+
+    hashCode = hashCode(); // Used for serialization.
+  }
+
+  /**
+   * Sets the specified fields of the URL. This is not a public method so
+   * that only URLStreamHandlers can modify URL fields. URLs are otherwise
+   * constant. If the given protocol does not exist, it will keep the previously
+   * set protocol.
+   *
+   * @param protocol The protocol name for this URL.
+   * @param host The hostname or IP address for this URL.
+   * @param port The port number of this URL.
+   * @param authority The authority of this URL.
+   * @param userInfo The user and password (if needed) of this URL.
+   * @param path The "path" portion of this URL.
+   * @param query The query of this URL.
+   * @param ref The anchor portion of this URL.
+   *
+   * @since 1.3
+   */
+  protected void set(String protocol, String host, int port, String authority,
+                     String userInfo, String path, String query, String ref)
+  {
+    URLStreamHandler protocolHandler = null;
+    protocol = protocol.toLowerCase();
+    if (! this.protocol.equals(protocol))
+      protocolHandler = getURLStreamHandler(protocol);
+    
+    // It is an hidden feature of the JDK. If the protocol does not exist,
+    // we keep the previously initialized protocol.
+    if (protocolHandler != null)
+      {
+	this.ph = protocolHandler;
+	this.protocol = protocol;
+      }
+    this.host = host;
+    this.userInfo = userInfo;
+    this.port = port;
+    this.authority = authority;
+    if (query == null)
+      this.file = path;
+    else
+      this.file = path + "?" + query;
+    this.ref = ref;
+    hashCode = hashCode(); // Used for serialization.
+  }
+
+  /**
+   * Sets the URLStreamHandlerFactory for this class.  This factory is
+   * responsible for returning the appropriate protocol handler for
+   * a given URL.
+   *
+   * @param fac The URLStreamHandlerFactory class to use
+   *
+   * @exception Error If the factory is alread set.
+   * @exception SecurityException If a security manager exists and its
+   * checkSetFactory method doesn't allow the operation
+   */
+  public static synchronized void setURLStreamHandlerFactory(URLStreamHandlerFactory fac)
+  {
+    if (factory != null)
+      throw new Error("URLStreamHandlerFactory already set");
+
+    // Throw an exception if an extant security mgr precludes
+    // setting the factory.
+    SecurityManager s = System.getSecurityManager();
+    if (s != null)
+      s.checkSetFactory();
+    factory = fac;
+  }
+
+  /**
+   * Returns a String representing this URL.  The String returned is
+   * created by calling the protocol handler's toExternalForm() method.
+   *
+   * @return A string for this URL
+   */
+  public String toExternalForm()
+  {
+    // Identical to toString().
+    return ph.toExternalForm(this);
+  }
+
+  /**
+   * Returns a String representing this URL.  Identical to toExternalForm().
+   * The value returned is created by the protocol handler's
+   * toExternalForm method.  Overrides Object.toString()
+   *
+   * @return A string for this URL
+   */
+  public String toString()
+  {
+    // Identical to toExternalForm().
+    return ph.toExternalForm(this);
+  }
+
+  /**
+   * This internal method is used in two different constructors to load
+   * a protocol handler for this URL.
+   *
+   * @param protocol The protocol to load a handler for
+   *
+   * @return A URLStreamHandler for this protocol, or null when not found.
+   */
+  private static synchronized URLStreamHandler getURLStreamHandler(String protocol)
+  {
+    URLStreamHandler ph = null;
+
+    // First, see if a protocol handler is in our cache.
+    if (cache_handlers)
+      {
+	if ((ph = (URLStreamHandler) ph_cache.get(protocol)) != null)
+	  return ph;
+      }
+
+    // If a non-default factory has been set, use it to find the protocol.
+    if (factory != null)
+      {
+	ph = factory.createURLStreamHandler(protocol);
+      }
+    else if (protocol.equals("core"))
+      {
+ 	ph = new gnu.java.net.protocol.core.Handler();
+      }
+    else if (protocol.equals("file"))
+      {
+	// This is an interesting case.  It's tempting to think that we
+	// could call Class.forName ("gnu.java.net.protocol.file.Handler") to
+	// get the appropriate class.  Unfortunately, if we do that the
+	// program will never terminate, because getURLStreamHandler is
+	// eventually called by Class.forName.
+	//
+	// Treating "file" as a special case is the minimum that will
+	// fix this problem.  If other protocols are required in a
+	// statically linked application they will need to be handled in
+	// the same way as "file".
+	ph = new gnu.java.net.protocol.file.Handler();
+      }
+
+    // Non-default factory may have returned null or a factory wasn't set.
+    // Use the default search algorithm to find a handler for this protocol.
+    if (ph == null)
+      {
+	// Get the list of packages to check and append our default handler
+	// to it, along with the JDK specified default as a last resort.
+	// Except in very unusual environments the JDK specified one shouldn't
+	// ever be needed (or available).
+	String ph_search_path =
+	  System.getProperty("java.protocol.handler.pkgs");
+
+	// Tack our default package on at the ends.
+	if (ph_search_path != null)
+	  ph_search_path += "|" + DEFAULT_SEARCH_PATH;
+	else
+	  ph_search_path = DEFAULT_SEARCH_PATH;
+
+	// Finally loop through our search path looking for a match.
+	StringTokenizer pkgPrefix = new StringTokenizer(ph_search_path, "|");
+
+	// Cache the systemClassLoader
+	if (systemClassLoader == null)
+	  {
+	    systemClassLoader = (ClassLoader) AccessController.doPrivileged
+	      (new PrivilegedAction() {
+		  public Object run()
+	          {
+		    return ClassLoader.getSystemClassLoader();
+		  }
+		});
+	  }
+
+	do
+	  {
+	    try
+	      {
+		// Try to get a class from the system/application
+		// classloader, initialize it, make an instance
+		// and try to cast it to a URLStreamHandler.
+		String clsName =
+		  (pkgPrefix.nextToken() + "." + protocol + ".Handler");
+		Class c = Class.forName(clsName, true, systemClassLoader);
+		ph = (URLStreamHandler) c.newInstance();
+	      }
+            catch (ThreadDeath death)
+              {
+                throw death;
+              }
+	    catch (Throwable t)
+	      {
+		// Ignored.
+	      }
+	  }
+	 while (ph == null && pkgPrefix.hasMoreTokens());
+      }
+
+    // Update the hashtable with the new protocol handler.
+    if (ph != null && cache_handlers)
+      ph_cache.put(protocol, ph);
+    else
+      ph = null;
+
+    return ph;
+  }
+
+  private void readObject(ObjectInputStream ois)
+    throws IOException, ClassNotFoundException
+  {
+    ois.defaultReadObject();
+    this.ph = getURLStreamHandler(protocol);
+    if (this.ph == null)
+      throw new IOException("Handler for protocol " + protocol + " not found");
+  }
+
+  private void writeObject(ObjectOutputStream oos) throws IOException
+  {
+    oos.defaultWriteObject();
+  }
+
+  /**
+   * Returns the equivalent <code>URI</code> object for this <code>URL</code>.
+   * This is the same as calling <code>new URI(this.toString())</code>.
+   * RFC2396-compliant URLs are guaranteed a successful conversion to
+   * a <code>URI</code> instance.  However, there are some values which
+   * form valid URLs, but which do not also form RFC2396-compliant URIs.
+   *
+   * @throws URISyntaxException if this URL is not RFC2396-compliant,
+   *         and thus can not be successfully converted to a URI.
+   */
+  public URI toURI()
+    throws URISyntaxException
+  {
+    return new URI(toString());
+  }
+
+}

Added: llvm-gcc-4.2/trunk/libjava/java/net/URLClassLoader.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/net/URLClassLoader.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/net/URLClassLoader.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/net/URLClassLoader.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1452 @@
+/* URLClassLoader.java --  ClassLoader that loads classes from one or more URLs
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.net;
+
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilePermission;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.security.SecureClassLoader;
+import java.security.cert.Certificate;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import gnu.gcj.runtime.SharedLibHelper;
+import gnu.gcj.Core;
+import gnu.java.net.protocol.core.CoreInputStream;
+
+/**
+ * A secure class loader that can load classes and resources from
+ * multiple locations.  Given an array of <code>URL</code>s this class
+ * loader will retrieve classes and resources by fetching them from
+ * possible remote locations.  Each <code>URL</code> is searched in
+ * order in which it was added.  If the file portion of the
+ * <code>URL</code> ends with a '/' character then it is interpreted
+ * as a base directory, otherwise it is interpreted as a jar file from
+ * which the classes/resources are resolved.
+ *
+ * <p>New instances can be created by two static
+ * <code>newInstance()</code> methods or by three public
+ * contructors. Both ways give the option to supply an initial array
+ * of <code>URL</code>s and (optionally) a parent classloader (that is
+ * different from the standard system class loader).</p>
+ *
+ * <p>Normally creating a <code>URLClassLoader</code> throws a
+ * <code>SecurityException</code> if a <code>SecurityManager</code> is
+ * installed and the <code>checkCreateClassLoader()</code> method does
+ * not return true.  But the <code>newInstance()</code> methods may be
+ * used by any code as long as it has permission to acces the given
+ * <code>URL</code>s.  <code>URLClassLoaders</code> created by the
+ * <code>newInstance()</code> methods also explicitly call the
+ * <code>checkPackageAccess()</code> method of
+ * <code>SecurityManager</code> if one is installed before trying to
+ * load a class.  Note that only subclasses of
+ * <code>URLClassLoader</code> can add new URLs after the
+ * URLClassLoader had been created. But it is always possible to get
+ * an array of all URLs that the class loader uses to resolve classes
+ * and resources by way of the <code>getURLs()</code> method.</p>
+ *
+ * <p>Open issues:
+ * <ul>
+ *
+ * <li>Should the URLClassLoader actually add the locations found in
+ * the manifest or is this the responsibility of some other
+ * loader/(sub)class?  (see <a
+ * href="http://java.sun.com/products/jdk/1.4/docs/guide/extensions/spec.html">
+ * Extension Mechanism Architecture - Bundles Extensions</a>)</li>
+ *
+ * <li>How does <code>definePackage()</code> and sealing work
+ * precisely?</li>
+ *
+ * <li>We save and use the security context (when a created by
+ * <code>newInstance()</code> but do we have to use it in more
+ * places?</li>
+ *
+ * <li>The use of <code>URLStreamHandler</code>s has not been tested.</li>
+ *
+ * </ul>
+ * </p>
+ *
+ * @since 1.2
+ *
+ * @author Mark Wielaard (mark at klomp.org)
+ * @author Wu Gansha (gansha.wu at intel.com)
+ */
+public class URLClassLoader extends SecureClassLoader
+{
+  // Class Variables
+
+  /**
+   * A global cache to store mappings between URLLoader and URL,
+   * so we can avoid do all the homework each time the same URL
+   * comes.
+   * XXX - Keeps these loaders forever which prevents garbage collection.
+   */
+  private static HashMap urlloaders = new HashMap();
+
+  /**
+   * A cache to store mappings between handler factory and its
+   * private protocol handler cache (also a HashMap), so we can avoid
+   * create handlers each time the same protocol comes.
+   */
+  private static HashMap factoryCache = new HashMap(5);
+
+  // Instance variables
+
+  /** Locations to load classes from */
+  private final Vector urls = new Vector();
+
+  /**
+   * Store pre-parsed information for each url into this vector: each
+   * element is a URL loader.  A jar file has its own class-path
+   * attribute which adds to the URLs that will be searched, but this
+   * does not add to the list of urls.
+   */
+  private final Vector urlinfos = new Vector();
+
+  /** Factory used to get the protocol handlers of the URLs */
+  private final URLStreamHandlerFactory factory;
+
+  /**
+   * The security context when created from <code>newInstance()</code>
+   * or null when created through a normal constructor or when no
+   * <code>SecurityManager</code> was installed.
+   */
+  private final AccessControlContext securityContext;
+
+  // Helper classes
+
+  /**
+   * A <code>URLLoader</code> contains all logic to load resources from a
+   * given base <code>URL</code>.
+   */
+  abstract static class URLLoader
+  {
+    /**
+     * Our classloader to get info from if needed.
+     */
+    final URLClassLoader classloader;
+
+    /**
+     * The base URL from which all resources are loaded.
+     */
+    final URL baseURL;
+
+    /**
+     * A <code>CodeSource</code> without any associated certificates.
+     * It is common for classes to not have certificates associated
+     * with them.  If they come from the same <code>URLLoader</code>
+     * then it is safe to share the associated <code>CodeSource</code>
+     * between them since <code>CodeSource</code> is immutable.
+     */
+    final CodeSource noCertCodeSource;
+
+    URLLoader(URLClassLoader classloader, URL baseURL)
+    {
+      this(classloader, baseURL, baseURL);
+    }
+
+    URLLoader(URLClassLoader classloader, URL baseURL, URL overrideURL)
+    {
+      this.classloader = classloader;
+      this.baseURL = baseURL;
+      this.noCertCodeSource = new CodeSource(overrideURL, null);
+    }
+
+    /**
+     * Returns a <code>Class</code> loaded by this
+     * <code>URLLoader</code>, or <code>null</code> when this loader
+     * either can't load the class or doesn't know how to load classes
+     * at all.
+     */
+    Class getClass(String className)
+    {
+      return null;
+    }
+
+    /**
+     * Returns a <code>Resource</code> loaded by this
+     * <code>URLLoader</code>, or <code>null</code> when no
+     * <code>Resource</code> with the given name exists.
+     */
+    abstract Resource getResource(String s);
+
+    /**
+     * Returns the <code>Manifest</code> associated with the
+     * <code>Resource</code>s loaded by this <code>URLLoader</code> or
+     * <code>null</code> there is no such <code>Manifest</code>.
+     */
+    Manifest getManifest()
+    {
+      return null;
+    }
+
+    Vector getClassPath()
+    {
+      return null;
+    }
+  }
+
+  /**
+   * A <code>Resource</code> represents a resource in some
+   * <code>URLLoader</code>. It also contains all information (e.g.,
+   * <code>URL</code>, <code>CodeSource</code>, <code>Manifest</code> and
+   * <code>InputStream</code>) that is necessary for loading resources
+   * and creating classes from a <code>URL</code>.
+   */
+  abstract static class Resource
+  {
+    final URLLoader loader;
+
+    Resource(URLLoader loader)
+    {
+      this.loader = loader;
+    }
+
+    /**
+     * Returns the non-null <code>CodeSource</code> associated with
+     * this resource.
+     */
+    CodeSource getCodeSource()
+    {
+      Certificate[] certs = getCertificates();
+      if (certs == null)
+        return loader.noCertCodeSource;
+      else
+        return new CodeSource(loader.baseURL, certs);
+    }
+
+    /**
+     * Returns <code>Certificates</code> associated with this
+     * resource, or null when there are none.
+     */
+    Certificate[] getCertificates()
+    {
+      return null;
+    }
+
+    /**
+     * Return a <code>URL</code> that can be used to access this resource.
+     */
+    abstract URL getURL();
+
+    /**
+     * Returns the size of this <code>Resource</code> in bytes or
+     * <code>-1</code> when unknown.
+     */
+    abstract int getLength();
+
+    /**
+     * Returns the non-null <code>InputStream</code> through which
+     * this resource can be loaded.
+     */
+    abstract InputStream getInputStream() throws IOException;
+  }
+
+  /**
+   * A <code>JarURLLoader</code> is a type of <code>URLLoader</code>
+   * only loading from jar url.
+   */
+  static final class JarURLLoader extends URLLoader
+  {
+    final JarFile jarfile; // The jar file for this url
+    final URL baseJarURL; // Base jar: url for all resources loaded from jar
+
+    Vector classPath;	// The "Class-Path" attribute of this Jar's manifest
+
+    public JarURLLoader(URLClassLoader classloader, URL baseURL,
+			URL absoluteUrl)
+    {
+      super(classloader, baseURL, absoluteUrl);
+
+      // Cache url prefix for all resources in this jar url.
+      String external = baseURL.toExternalForm();
+      StringBuffer sb = new StringBuffer(external.length() + 6);
+      sb.append("jar:");
+      sb.append(external);
+      sb.append("!/");
+      String jarURL = sb.toString();
+
+      this.classPath = null;
+      URL baseJarURL = null;
+      JarFile jarfile = null;
+      try
+	{
+	  baseJarURL =
+	    new URL(null, jarURL, classloader.getURLStreamHandler("jar"));
+	  
+	  jarfile =
+	    ((JarURLConnection) baseJarURL.openConnection()).getJarFile();
+	  
+	  Manifest manifest;
+	  Attributes attributes;
+	  String classPathString;
+
+	  if ((manifest = jarfile.getManifest()) != null
+	      && (attributes = manifest.getMainAttributes()) != null
+	      && ((classPathString 
+		   = attributes.getValue(Attributes.Name.CLASS_PATH)) 
+		  != null))
+	    {
+	      this.classPath = new Vector();
+	      
+	      StringTokenizer st = new StringTokenizer(classPathString, " ");
+	      while (st.hasMoreElements ()) 
+		{  
+		  String e = st.nextToken ();
+		  try
+		    {
+		      URL url = new URL(baseURL, e);
+		      this.classPath.add(url);
+		    } 
+		  catch (java.net.MalformedURLException xx)
+		    {
+		      // Give up
+		    }
+		}
+	    }
+	}
+      catch (IOException ioe)
+        {
+	  /* ignored */
+        }
+
+      this.baseJarURL = baseJarURL;
+      this.jarfile = jarfile;
+    }
+
+    /** get resource with the name "name" in the jar url */
+    Resource getResource(String name)
+    {
+      if (jarfile == null)
+        return null;
+
+      if (name.startsWith("/"))
+        name = name.substring(1);
+
+      JarEntry je = jarfile.getJarEntry(name);
+      if (je != null)
+        return new JarURLResource(this, name, je);
+      else
+        return null;
+    }
+
+    Manifest getManifest()
+    {
+      try
+        {
+          return (jarfile == null) ? null : jarfile.getManifest();
+        }
+      catch (IOException ioe)
+        {
+          return null;
+        }
+    }
+
+    Vector getClassPath()
+    {
+      return classPath;
+    }
+  }
+
+  static final class JarURLResource extends Resource
+  {
+    private final JarEntry entry;
+    private final String name;
+
+    JarURLResource(JarURLLoader loader, String name, JarEntry entry)
+    {
+      super(loader);
+      this.entry = entry;
+      this.name = name;
+    }
+
+    InputStream getInputStream() throws IOException
+    {
+      return ((JarURLLoader) loader).jarfile.getInputStream(entry);
+    }
+
+    int getLength()
+    {
+      return (int) entry.getSize();
+    }
+
+    Certificate[] getCertificates()
+    {
+      // We have to get the entry from the jar file again, because the
+      // certificates will not be available until the entire entry has
+      // been read.
+      return ((JarEntry) ((JarURLLoader) loader).jarfile.getEntry(name))
+        .getCertificates();
+    }
+
+    URL getURL()
+    {
+      try
+        {
+          return new URL(((JarURLLoader) loader).baseJarURL, name,
+                         loader.classloader.getURLStreamHandler("jar"));
+        }
+      catch (MalformedURLException e)
+        {
+          InternalError ie = new InternalError();
+          ie.initCause(e);
+          throw ie;
+        }
+    }
+  }
+
+  /**
+   * Loader for remote directories.
+   */
+  static final class RemoteURLLoader extends URLLoader
+  {
+    private final String protocol;
+
+    RemoteURLLoader(URLClassLoader classloader, URL url)
+    {
+      super(classloader, url);
+      protocol = url.getProtocol();
+    }
+
+    /**
+     * Get a remote resource.
+     * Returns null if no such resource exists.
+     */
+    Resource getResource(String name)
+    {
+      try
+        {
+          URL url =
+            new URL(baseURL, name, classloader.getURLStreamHandler(protocol));
+          URLConnection connection = url.openConnection();
+
+          // Open the connection and check the stream
+          // just to be sure it exists.
+          int length = connection.getContentLength();
+          InputStream stream = connection.getInputStream();
+
+          // We can do some extra checking if it is a http request
+          if (connection instanceof HttpURLConnection)
+            {
+              int response =
+                ((HttpURLConnection) connection).getResponseCode();
+              if (response / 100 != 2)
+                return null;
+            }
+
+          if (stream != null)
+            return new RemoteResource(this, name, url, stream, length);
+          else
+            return null;
+        }
+      catch (IOException ioe)
+        {
+          return null;
+        }
+    }
+  }
+
+  /**
+   * A resource from some remote location.
+   */
+  static final class RemoteResource extends Resource
+  {
+    private final URL url;
+    private final InputStream stream;
+    private final int length;
+
+    RemoteResource(RemoteURLLoader loader, String name, URL url,
+                   InputStream stream, int length)
+    {
+      super(loader);
+      this.url = url;
+      this.stream = stream;
+      this.length = length;
+    }
+
+    InputStream getInputStream() throws IOException
+    {
+      return stream;
+    }
+
+    public int getLength()
+    {
+      return length;
+    }
+
+    public URL getURL()
+    {
+      return url;
+    }
+  }
+
+  /**
+   * A <code>SoURLLoader</code> is a type of <code>URLLoader</code>
+   * that loads classes and resources from a shared library.
+   */
+  final static class SoURLLoader extends URLLoader
+  {
+    SharedLibHelper helper;
+
+    SoURLLoader(URLClassLoader classloader, URL url)
+    {
+      this(classloader, url, url);
+    }
+
+    SoURLLoader(URLClassLoader classloader, URL url, URL overrideURL)
+    {
+      super(classloader, url, overrideURL);
+      helper = SharedLibHelper.findHelper(classloader, url.getFile(),
+					  noCertCodeSource, true);
+    }
+
+    Class getClass(String className)
+    {
+      return helper.findClass(className);
+    }
+
+    Resource getResource(String name)
+    {
+      URL url = helper.findResource(name);
+      if (url == null)
+	return null;
+      return new SoResource(this, url);
+    }
+  }
+
+  final static class SoResource extends Resource
+  {
+    SoResource(SoURLLoader loader, URL url)
+    {
+      super(loader);
+      this.url = url;
+    }
+
+    InputStream getInputStream() throws IOException
+    {
+      URLConnection conn = url.openConnection();
+      return conn.getInputStream();
+    }
+
+    public int getLength()
+    {
+      // FIXME we could find this by asking the core object.
+      return -1;
+    }
+
+    public URL getURL ()
+    {
+      return url;
+    }
+
+    final URL url;
+  }
+
+  /**
+   * A <code>FileURLLoader</code> is a type of <code>URLLoader</code>
+   * only loading from file url.
+   */
+  static final class FileURLLoader extends URLLoader
+  {
+    File dir; //the file for this file url
+
+    FileURLLoader(URLClassLoader classloader, URL url, URL absoluteUrl)
+    {
+      super(classloader, url, absoluteUrl);
+      dir = new File(absoluteUrl.getFile());
+    }
+
+    /** get resource with the name "name" in the file url */
+    Resource getResource(String name)
+    {
+      try 
+ 	{
+ 	  File file = new File(dir, name).getCanonicalFile();
+ 	  if (file.exists() && !file.isDirectory())
+ 	    return new FileResource(this, file);
+ 	}
+      catch (IOException e)
+ 	{
+ 	  // Fall through...
+ 	}
+      return null;
+    }
+  }
+
+  static final class FileResource extends Resource
+  {
+    final File file;
+
+    FileResource(FileURLLoader loader, File file)
+    {
+      super(loader);
+      this.file = file;
+    }
+
+    InputStream getInputStream() throws IOException
+    {
+      // Delegate to the URL content handler mechanism to retrieve an
+      // HTML representation of the directory listing if a directory
+      if (file.isDirectory())
+        {
+          URL url = getURL();
+          return url.openStream();
+        }
+      // Otherwise simply return a FileInputStream
+      return new FileInputStream(file);
+    }
+
+    public int getLength()
+    {
+      // Delegate to the URL content handler mechanism to retrieve the
+      // length of the HTML representation of the directory listing if
+      // a directory, or -1 if an exception occurs opening the directory.
+      if (file.isDirectory())
+        {
+          URL url = getURL();
+          try
+            {
+              URLConnection connection = url.openConnection();
+              return connection.getContentLength();
+            }
+          catch (IOException e)
+            {
+              return -1;
+            }
+        }
+      // Otherwise simply return the file length
+      return (int) file.length();
+    }
+
+    public URL getURL()
+    {
+      try
+        {
+          return file.toURL();
+        }
+      catch (MalformedURLException e)
+        {
+          InternalError ie = new InternalError();
+          ie.initCause(e);
+          throw ie;
+        }
+    }
+  }
+
+  /**
+   * A <code>CoreURLLoader</code> is a type of <code>URLLoader</code>
+   * only loading from core url.
+   */
+  static final class CoreURLLoader extends URLLoader
+  {
+    private String dir;
+
+    CoreURLLoader(URLClassLoader classloader, URL url)
+    {
+      super(classloader, url);
+      dir = baseURL.getFile();
+    }
+
+    /** get resource with the name "name" in the core url */
+    Resource getResource(String name)
+    {
+      Core core = Core.find (dir + name);
+      if (core != null)
+        return new CoreResource(this, name, core);
+      return null;
+    }
+  }
+
+  static final class CoreResource extends Resource
+  {
+    private final Core core;
+    private final String name;
+
+    CoreResource(CoreURLLoader loader, String name, Core core)
+    {
+      super(loader);
+      this.core = core;
+      this.name = name;
+    }
+
+    InputStream getInputStream() throws IOException
+    {
+      return new CoreInputStream(core);
+    }
+
+    public int getLength()
+    {
+      return core.length;
+    }
+
+    public URL getURL()
+    {
+      try
+        {
+          return new URL(loader.baseURL, name,
+                         loader.classloader.getURLStreamHandler("core"));
+        }
+      catch (MalformedURLException e)
+        {
+          InternalError ie = new InternalError();
+          ie.initCause(e);
+          throw ie;
+        }
+    }
+  }
+
+  // Constructors
+
+  /**
+   * Creates a URLClassLoader that gets classes from the supplied URLs.
+   * To determine if this classloader may be created the constructor of
+   * the super class (<code>SecureClassLoader</code>) is called first, which
+   * can throw a SecurityException. Then the supplied URLs are added
+   * in the order given to the URLClassLoader which uses these URLs to
+   * load classes and resources (after using the default parent ClassLoader).
+   *
+   * @param urls Locations that should be searched by this ClassLoader when
+   * resolving Classes or Resources.
+   * @exception SecurityException if the SecurityManager disallows the
+   * creation of a ClassLoader.
+   * @see SecureClassLoader
+   */
+  public URLClassLoader(URL[] urls) throws SecurityException
+  {
+    super();
+    this.factory = null;
+    this.securityContext = null;
+    addURLs(urls);
+  }
+
+  /**
+   * Creates a <code>URLClassLoader</code> that gets classes from the supplied
+   * <code>URL</code>s.
+   * To determine if this classloader may be created the constructor of
+   * the super class (<code>SecureClassLoader</code>) is called first, which
+   * can throw a SecurityException. Then the supplied URLs are added
+   * in the order given to the URLClassLoader which uses these URLs to
+   * load classes and resources (after using the supplied parent ClassLoader).
+   * @param urls Locations that should be searched by this ClassLoader when
+   * resolving Classes or Resources.
+   * @param parent The parent class loader used before trying this class
+   * loader.
+   * @exception SecurityException if the SecurityManager disallows the
+   * creation of a ClassLoader.
+   * @exception SecurityException
+   * @see SecureClassLoader
+   */
+  public URLClassLoader(URL[] urls, ClassLoader parent)
+    throws SecurityException
+  {
+    super(parent);
+    this.factory = null;
+    this.securityContext = null;
+    addURLs(urls);
+  }
+
+  // Package-private to avoid a trampoline constructor.
+  /**
+   * Package-private constructor used by the static
+   * <code>newInstance(URL[])</code> method.  Creates an
+   * <code>URLClassLoader</code> with the given parent but without any
+   * <code>URL</code>s yet. This is used to bypass the normal security
+   * check for creating classloaders, but remembers the security
+   * context which will be used when defining classes.  The
+   * <code>URL</code>s to load from must be added by the
+   * <code>newInstance()</code> method in the security context of the
+   * caller.
+   *
+   * @param securityContext the security context of the unprivileged code.
+   */
+  URLClassLoader(ClassLoader parent, AccessControlContext securityContext)
+  {
+    super(parent);
+    this.factory = null;
+    this.securityContext = securityContext;
+  }
+
+  /**
+   * Creates a URLClassLoader that gets classes from the supplied URLs.
+   * To determine if this classloader may be created the constructor of
+   * the super class (<CODE>SecureClassLoader</CODE>) is called first, which
+   * can throw a SecurityException. Then the supplied URLs are added
+   * in the order given to the URLClassLoader which uses these URLs to
+   * load classes and resources (after using the supplied parent ClassLoader).
+   * It will use the supplied <CODE>URLStreamHandlerFactory</CODE> to get the
+   * protocol handlers of the supplied URLs.
+   * @param urls Locations that should be searched by this ClassLoader when
+   * resolving Classes or Resources.
+   * @param parent The parent class loader used before trying this class
+   * loader.
+   * @param factory Used to get the protocol handler for the URLs.
+   * @exception SecurityException if the SecurityManager disallows the
+   * creation of a ClassLoader.
+   * @exception SecurityException
+   * @see SecureClassLoader
+   */
+  public URLClassLoader(URL[] urls, ClassLoader parent,
+                        URLStreamHandlerFactory factory)
+    throws SecurityException
+  {
+    super(parent);
+    this.securityContext = null;
+    this.factory = factory;
+    addURLs(urls);
+
+    // If this factory is still not in factoryCache, add it,
+    //   since we only support three protocols so far, 5 is enough
+    //   for cache initial size
+    synchronized (factoryCache)
+      {
+        if (factory != null && factoryCache.get(factory) == null)
+          factoryCache.put(factory, new HashMap(5));
+      }
+  }
+
+  // Methods
+
+  /**
+   * Adds a new location to the end of the internal URL store.
+   * @param newUrl the location to add
+   */
+  protected void addURL(URL newUrl)
+  {
+    urls.add(newUrl);
+    addURLImpl(newUrl);
+  }
+
+  private void addURLImpl(URL newUrl)
+  {
+    synchronized (this)
+      {
+        if (newUrl == null)
+          return; // Silently ignore...
+
+	// Reset the toString() value.
+	thisString = null;
+
+        // Check global cache to see if there're already url loader
+        // for this url.
+        URLLoader loader = (URLLoader) urlloaders.get(newUrl);
+        if (loader == null)
+          {
+            String file = newUrl.getFile();
+            String protocol = newUrl.getProtocol();
+
+	    // If we have a file: URL, we want to make it absolute
+	    // here, before we decide whether it is really a jar.
+	    URL absoluteURL;
+	    if ("file".equals (protocol))
+	      {
+		File dir = new File(file);
+		URL absUrl;
+		try
+		  {
+		    absoluteURL = dir.getCanonicalFile().toURL();
+		  }
+		catch (IOException ignore)
+		  {
+		    try
+		      {
+			absoluteURL = dir.getAbsoluteFile().toURL();
+		      }
+		    catch (MalformedURLException _)
+		      {
+			// This really should not happen.
+			absoluteURL = newUrl;
+		      }
+		  }
+	      }
+	    else
+	      {
+		// This doesn't hurt, and it simplifies the logic a
+		// little.
+		absoluteURL = newUrl;
+	      }
+
+            // Check that it is not a directory
+	    if ("gcjlib".equals(protocol))
+	      loader = new SoURLLoader(this, newUrl);
+	    else if (! (file.endsWith("/") || file.endsWith(File.separator)))
+              loader = new JarURLLoader(this, newUrl, absoluteURL);
+            else if ("file".equals(protocol))
+	      loader = new FileURLLoader(this, newUrl, absoluteURL);
+	    else if ("core".equals(protocol))
+	      loader = new CoreURLLoader(this, newUrl);
+            else
+              loader = new RemoteURLLoader(this, newUrl);
+
+            // Cache it.
+            urlloaders.put(newUrl, loader);
+          }
+
+	urlinfos.add(loader);
+
+	Vector extraUrls = loader.getClassPath();
+	if (extraUrls != null)
+	  {
+	    Iterator it = extraUrls.iterator();
+	    while (it.hasNext())
+	      {
+		URL url = (URL)it.next();
+		URLLoader extraLoader = (URLLoader) urlloaders.get(url);
+		if (! urlinfos.contains (extraLoader))
+		  addURLImpl(url);
+	      }
+	  }
+
+      }
+  }
+
+  /**
+   * Adds an array of new locations to the end of the internal URL
+   * store.  Called from the the constructors. Should not call to the
+   * protected addURL() method since that can be overridden and
+   * subclasses are not yet in a good state at this point.
+   * jboss 4.0.3 for example depends on this.
+   *
+   * @param newUrls the locations to add
+   */
+  private void addURLs(URL[] newUrls)
+  {
+    for (int i = 0; i < newUrls.length; i++)
+      {
+	urls.add(newUrls[i]);
+	addURLImpl(newUrls[i]);
+      }
+  }
+
+  /**
+   * Look in both Attributes for a given value.  The first Attributes
+   * object, if not null, has precedence.
+   */
+  private String getAttributeValue(Attributes.Name name, Attributes first,
+				   Attributes second)
+  {
+    String result = null;
+    if (first != null)
+      result = first.getValue(name);
+    if (result == null)
+      result = second.getValue(name);
+    return result;
+  }
+
+  /**
+   * Defines a Package based on the given name and the supplied manifest
+   * information. The manifest indicates the title, version and
+   * vendor information of the specification and implementation and whether the
+   * package is sealed. If the Manifest indicates that the package is sealed
+   * then the Package will be sealed with respect to the supplied URL.
+   *
+   * @param name The name of the package
+   * @param manifest The manifest describing the specification,
+   * implementation and sealing details of the package
+   * @param url the code source url to seal the package
+   * @return the defined Package
+   * @throws IllegalArgumentException If this package name already exists
+   * in this class loader
+   */
+  protected Package definePackage(String name, Manifest manifest, URL url)
+    throws IllegalArgumentException
+  {
+    // Compute the name of the package as it may appear in the
+    // Manifest.
+    StringBuffer xform = new StringBuffer(name);
+    for (int i = xform.length () - 1; i >= 0; --i)
+      if (xform.charAt(i) == '.')
+	xform.setCharAt(i, '/');
+    xform.append('/');
+    String xformName = xform.toString();
+
+    Attributes entryAttr = manifest.getAttributes(xformName);
+    Attributes attr = manifest.getMainAttributes();
+
+    String specTitle
+      = getAttributeValue(Attributes.Name.SPECIFICATION_TITLE,
+			  entryAttr, attr);
+    String specVersion
+      = getAttributeValue(Attributes.Name.SPECIFICATION_VERSION,
+			  entryAttr, attr);
+    String specVendor
+      = getAttributeValue(Attributes.Name.SPECIFICATION_VENDOR,
+			  entryAttr, attr);
+    String implTitle
+      = getAttributeValue(Attributes.Name.IMPLEMENTATION_TITLE,
+			  entryAttr, attr);
+    String implVersion
+      = getAttributeValue(Attributes.Name.IMPLEMENTATION_VERSION,
+			  entryAttr, attr);
+    String implVendor
+      = getAttributeValue(Attributes.Name.IMPLEMENTATION_VENDOR,
+			  entryAttr, attr);
+
+    // Look if the Manifest indicates that this package is sealed
+    // XXX - most likely not completely correct!
+    // Shouldn't we also check the sealed attribute of the complete jar?
+    // http://java.sun.com/products/jdk/1.4/docs/guide/extensions/spec.html#bundled
+    // But how do we get that jar manifest here?
+    String sealed = attr.getValue(Attributes.Name.SEALED);
+    if ("false".equals(sealed))
+      // make sure that the URL is null so the package is not sealed
+      url = null;
+
+    return definePackage(name,
+			 specTitle, specVendor, specVersion,
+			 implTitle, implVendor, implVersion,
+			 url);
+  }
+
+  /**
+   * Finds (the first) class by name from one of the locations. The locations
+   * are searched in the order they were added to the URLClassLoader.
+   *
+   * @param className the classname to find
+   * @exception ClassNotFoundException when the class could not be found or
+   * loaded
+   * @return a Class object representing the found class
+   */
+  protected Class findClass(final String className)
+    throws ClassNotFoundException
+  {
+    // Just try to find the resource by the (almost) same name
+    String resourceName = className.replace('.', '/') + ".class";
+    int max = urlinfos.size();
+    Resource resource = null;
+    for (int i = 0; i < max && resource == null; i++)
+      {
+	URLLoader loader = (URLLoader)urlinfos.elementAt(i);
+	if (loader == null)
+	  continue;
+
+	Class k = loader.getClass(className);
+	if (k != null)
+	  return k;
+
+	resource = loader.getResource(resourceName);
+      }
+    if (resource == null)
+      {
+	String message = className + " not found";
+	if (runtimeInitialized())
+	  message += " in " + this;
+	throw new ClassNotFoundException(message);
+      }
+
+    // Try to read the class data, create the CodeSource, Package and
+    // construct the class (and watch out for those nasty IOExceptions)
+    try
+      {
+	byte[] data;
+	InputStream in = resource.getInputStream();
+	try
+	  {
+	    int length = resource.getLength();
+	    if (length != -1)
+	      {
+		// We know the length of the data.
+		// Just try to read it in all at once
+		data = new byte[length];
+		int pos = 0;
+		while (length - pos > 0)
+		  {
+		    int len = in.read(data, pos, length - pos);
+		    if (len == -1)
+		      throw new EOFException("Not enough data reading from: "
+					     + in);
+		    pos += len;
+		  }
+	      }
+	    else
+	      {
+		// We don't know the data length.
+		// Have to read it in chunks.
+		ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
+		byte[] b = new byte[4096];
+		int l = 0;
+		while (l != -1)
+		  {
+		    l = in.read(b);
+		    if (l != -1)
+		      out.write(b, 0, l);
+		  }
+		data = out.toByteArray();
+	      }
+	  }
+	finally
+	  {
+	    in.close();
+	  }
+	final byte[] classData = data;
+
+        // Now get the CodeSource
+        final CodeSource source = resource.getCodeSource();
+
+        // Find out package name
+        String packageName = null;
+        int lastDot = className.lastIndexOf('.');
+        if (lastDot != -1)
+          packageName = className.substring(0, lastDot);
+
+        if (packageName != null && getPackage(packageName) == null)
+          {
+            // define the package
+            Manifest manifest = resource.loader.getManifest();
+            if (manifest == null)
+              definePackage(packageName, null, null, null, null, null, null,
+                            null);
+            else
+              definePackage(packageName, manifest, resource.loader.baseURL);
+          }
+
+        // And finally construct the class!
+        SecurityManager sm = System.getSecurityManager();
+        Class result = null;
+        if (sm != null && securityContext != null)
+          {
+            result = (Class)AccessController.doPrivileged
+              (new PrivilegedAction()
+                {
+                  public Object run()
+                  {
+                    return defineClass(className, classData,
+                                       0, classData.length,
+                                       source);
+                  }
+                }, securityContext);
+          }
+        else
+          result = defineClass(className, classData, 0, classData.length, source);
+
+        // Avoid NullPointerExceptions.
+        Certificate[] resourceCertificates = resource.getCertificates();
+        if(resourceCertificates != null)
+          super.setSigners(result, resourceCertificates);
+        
+        return result;
+      }
+    catch (IOException ioe)
+      {
+	ClassNotFoundException cnfe;
+	cnfe = new ClassNotFoundException(className + " not found in " + this);
+	cnfe.initCause(ioe);
+	throw cnfe;
+      }
+  }
+  
+  // Cached String representation of this URLClassLoader
+  private String thisString;
+  
+  /**
+   * Returns a String representation of this URLClassLoader giving the
+   * actual Class name, the URLs that are searched and the parent
+   * ClassLoader.
+   */
+  public String toString()
+  {
+    synchronized (this)
+      {
+	if (thisString == null)
+	  {
+	    StringBuffer sb = new StringBuffer();
+	    sb.append(this.getClass().getName());
+	    sb.append("{urls=[" );
+	    URL[] thisURLs = getURLs();
+	    for (int i = 0; i < thisURLs.length; i++)
+	      {
+		sb.append(thisURLs[i]);
+		if (i < thisURLs.length - 1)
+		  sb.append(',');
+	      }
+	    sb.append(']');
+	    sb.append(", parent=");
+	    sb.append(getParent());
+	    sb.append('}');
+	    thisString = sb.toString();
+	  }
+	return thisString;
+      }
+  }
+
+  /**
+   * Finds the first occurrence of a resource that can be found. The locations
+   * are searched in the order they were added to the URLClassLoader.
+   *
+   * @param resourceName the resource name to look for
+   * @return the URLResource for the resource if found, null otherwise
+   */
+  private Resource findURLResource(String resourceName)
+  {
+    int max = urlinfos.size();
+    for (int i = 0; i < max; i++)
+      {
+        URLLoader loader = (URLLoader) urlinfos.elementAt(i);
+        if (loader == null)
+          continue;
+
+        Resource resource = loader.getResource(resourceName);
+        if (resource != null)
+          return resource;
+      }
+    return null;
+  }
+
+  /**
+   * Finds the first occurrence of a resource that can be found.
+   *
+   * @param resourceName the resource name to look for
+   * @return the URL if found, null otherwise
+   */
+  public URL findResource(String resourceName)
+  {
+    Resource resource = findURLResource(resourceName);
+    if (resource != null)
+      return resource.getURL();
+
+    // Resource not found
+    return null;
+  }
+
+  /**
+   * If the URLStreamHandlerFactory has been set this return the appropriate
+   * URLStreamHandler for the given protocol, if not set returns null.
+   *
+   * @param protocol the protocol for which we need a URLStreamHandler
+   * @return the appropriate URLStreamHandler or null
+   */
+  URLStreamHandler getURLStreamHandler(String protocol)
+  {
+    if (factory == null)
+      return null;
+
+    URLStreamHandler handler;
+    synchronized (factoryCache)
+      {
+        // Check if there're handler for the same protocol in cache.
+        HashMap cache = (HashMap) factoryCache.get(factory);
+        handler = (URLStreamHandler) cache.get(protocol);
+        if (handler == null)
+          {
+            // Add it to cache.
+            handler = factory.createURLStreamHandler(protocol);
+            cache.put(protocol, handler);
+          }
+      }
+    return handler;
+  }
+
+  /**
+   * Finds all the resources with a particular name from all the locations.
+   *
+   * @param resourceName the name of the resource to lookup
+   * @return a (possible empty) enumeration of URLs where the resource can be
+   * found
+   * @exception IOException when an error occurs accessing one of the
+   * locations
+   */
+  public Enumeration findResources(String resourceName)
+    throws IOException
+  {
+    Vector resources = new Vector();
+    int max = urlinfos.size();
+    for (int i = 0; i < max; i++)
+      {
+        URLLoader loader = (URLLoader) urlinfos.elementAt(i);
+        Resource resource = loader.getResource(resourceName);
+        if (resource != null)
+          resources.add(resource.getURL());
+      }
+    return resources.elements();
+  }
+
+  /**
+   * Returns the permissions needed to access a particular code
+   * source.  These permissions includes those returned by
+   * <code>SecureClassLoader.getPermissions()</code> and the actual
+   * permissions to access the objects referenced by the URL of the
+   * code source.  The extra permissions added depend on the protocol
+   * and file portion of the URL in the code source. If the URL has
+   * the "file" protocol ends with a '/' character then it must be a
+   * directory and a file Permission to read everything in that
+   * directory and all subdirectories is added. If the URL had the
+   * "file" protocol and doesn't end with a '/' character then it must
+   * be a normal file and a file permission to read that file is
+   * added. If the <code>URL</code> has any other protocol then a
+   * socket permission to connect and accept connections from the host
+   * portion of the URL is added.
+   *
+   * @param source The codesource that needs the permissions to be accessed
+   * @return the collection of permissions needed to access the code resource
+   * @see java.security.SecureClassLoader#getPermissions(CodeSource)
+   */
+  protected PermissionCollection getPermissions(CodeSource source)
+  {
+    // XXX - This implementation does exactly as the Javadoc describes.
+    // But maybe we should/could use URLConnection.getPermissions()?
+    // First get the permissions that would normally be granted
+    PermissionCollection permissions = super.getPermissions(source);
+
+    // Now add any extra permissions depending on the URL location.
+    URL url = source.getLocation();
+    String protocol = url.getProtocol();
+    if (protocol.equals("file"))
+      {
+        String file = url.getFile();
+
+        // If the file end in / it must be an directory.
+        if (file.endsWith("/") || file.endsWith(File.separator))
+          {
+            // Grant permission to read everything in that directory and
+            // all subdirectories.
+            permissions.add(new FilePermission(file + "-", "read"));
+          }
+        else
+          {
+            // It is a 'normal' file.
+            // Grant permission to access that file.
+            permissions.add(new FilePermission(file, "read"));
+          }
+      }
+    else
+      {
+        // Grant permission to connect to and accept connections from host
+        String host = url.getHost();
+        if (host != null)
+          permissions.add(new SocketPermission(host, "connect,accept"));
+      }
+
+    return permissions;
+  }
+
+  /**
+   * Returns all the locations that this class loader currently uses the
+   * resolve classes and resource. This includes both the initially supplied
+   * URLs as any URLs added later by the loader.
+   * @return All the currently used URLs
+   */
+  public URL[] getURLs()
+  {
+    return (URL[]) urls.toArray(new URL[urls.size()]);
+  }
+
+  /**
+   * Creates a new instance of a <code>URLClassLoader</code> that gets
+   * classes from the supplied <code>URL</code>s. This class loader
+   * will have as parent the standard system class loader.
+   *
+   * @param urls the initial URLs used to resolve classes and
+   * resources
+   *
+   * @return the class loader
+   *
+   * @exception SecurityException when the calling code does not have
+   * permission to access the given <code>URL</code>s
+   */
+  public static URLClassLoader newInstance(URL[] urls)
+    throws SecurityException
+  {
+    return newInstance(urls, null);
+  }
+
+  /**
+   * Creates a new instance of a <code>URLClassLoader</code> that gets
+   * classes from the supplied <code>URL</code>s and with the supplied
+   * loader as parent class loader.
+   *
+   * @param urls the initial URLs used to resolve classes and
+   * resources
+   * @param parent the parent class loader
+   *
+   * @return the class loader
+   *
+   * @exception SecurityException when the calling code does not have
+   * permission to access the given <code>URL</code>s
+   */
+  public static URLClassLoader newInstance(URL[] urls, final ClassLoader parent)
+    throws SecurityException
+  {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm == null)
+      return new URLClassLoader(urls, parent);
+    else
+      {
+        final Object securityContext = sm.getSecurityContext();
+
+        // XXX - What to do with anything else then an AccessControlContext?
+        if (! (securityContext instanceof AccessControlContext))
+          throw new SecurityException("securityContext must be AccessControlContext: "
+                                      + securityContext);
+
+        URLClassLoader loader =
+          (URLClassLoader) AccessController.doPrivileged(new PrivilegedAction()
+              {
+                public Object run()
+                {
+                  return new URLClassLoader(parent,
+                                            (AccessControlContext) securityContext);
+                }
+              });
+        loader.addURLs(urls);
+        return loader;
+      }
+  }
+
+  /**
+   * Tell whether runtime initialization is complete.
+   *
+   * @return whether runtime initialization is complete.
+   */
+  private static native boolean runtimeInitialized();  
+}

Added: llvm-gcc-4.2/trunk/libjava/java/net/VMInetAddress.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/net/VMInetAddress.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/net/VMInetAddress.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/net/VMInetAddress.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,117 @@
+/* VMInetAddress.java -- Class to model an Internet address
+   Copyright (C) 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.net;
+
+import gnu.classpath.Configuration;
+
+import java.io.Serializable;
+
+class VMInetAddress implements Serializable
+{
+  static
+  {
+    if (Configuration.INIT_LOAD_LIBRARY)
+      System.loadLibrary("javanet");
+  }
+
+  /**
+   * This method looks up the hostname of the local machine
+   * we are on.  If the actual hostname cannot be determined, then the
+   * value "localhost" will be used.  This native method wrappers the
+   * "gethostname" function.
+   *
+   * @return The local hostname.
+   */
+  public static String getLocalHostname()
+  {
+    return InetAddress.getLocalHostname();
+  }
+
+  /**
+   * Returns the value of the special address INADDR_ANY
+   */
+  public static byte[] lookupInaddrAny() throws UnknownHostException
+  {
+    return new byte[] {0, 0, 0, 0};
+  }
+
+  /**
+   * 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 String getHostByAddr(byte[] ip) throws UnknownHostException
+  {
+    InetAddress addr = InetAddress.getByAddress(ip);
+    InetAddress.lookup(null, addr, false);
+    return addr.getHostName();
+  }
+
+  /**
+   * Returns a list of all IP addresses for a given hostname.  Will throw
+   * an UnknownHostException if the hostname cannot be resolved.
+   */
+  public static byte[][] getHostByName(String hostname)
+    throws UnknownHostException
+  {
+    InetAddress[] iaddrs = InetAddress.lookup(hostname, null, true);
+    byte[][] addrs = new byte[iaddrs.length][];
+    for (int i = 0; i < iaddrs.length; i++)
+      addrs[i] = iaddrs[i].getAddress();
+    return addrs;
+  }
+
+  /**
+   * Return the IP address represented by a literal address.
+   * Will return null if the literal address is not valid.
+   *
+   * @param address the name of the host
+   *
+   * @return The IP address as a byte array
+   */
+  public static byte[] aton(String address)
+  {
+    return InetAddress.aton(address);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/net/VMNetworkInterface.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/net/VMNetworkInterface.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/net/VMNetworkInterface.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/net/VMNetworkInterface.java Thu Nov  8 16:56:19 2007
@@ -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 at gmx.de)
+ * @since 1.4
+ */
+final class VMNetworkInterface
+{
+  static
+    {
+      if (Configuration.INIT_LOAD_LIBRARY)
+	System.loadLibrary("javanet");
+    }
+
+  public static native Vector getInterfaces()
+    throws SocketException;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/net/VMURLConnection.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/net/VMURLConnection.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/net/VMURLConnection.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/net/VMURLConnection.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,76 @@
+/* VMURLConnection - VM code for URLConnection
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.net;
+
+import gnu.classpath.Configuration;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+final class VMURLConnection
+{
+  public static final int LENGTH = 1024;
+
+  // private static native void init();
+
+  private static String guessContentTypeFromBuffer(byte[] b, int valid)
+  {
+    // FIXME - write real implementation
+    return null;
+  }
+
+  /**
+   * This is called from URLConnection to guess the mime type of a
+   * stream.  This method may return null to indicate that it could
+   * not guess a type.
+   */
+  static String guessContentTypeFromStream(InputStream is)
+    throws IOException
+  {
+    if (! is.markSupported())
+      return null;
+    is.mark(LENGTH);
+    byte[] bytes = new byte[LENGTH];
+    int r = is.read(bytes);
+    if (r < 0)
+      return null;
+    is.reset();
+    return guessContentTypeFromBuffer(bytes, r);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/net/natInetAddressNoNet.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/net/natInetAddressNoNet.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/net/natInetAddressNoNet.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/net/natInetAddressNoNet.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,36 @@
+/* Copyright (C) 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <stddef.h>
+
+#include <java/net/InetAddress.h>
+
+jbyteArray
+java::net::InetAddress::aton (jstring)
+{
+  return NULL;
+}
+
+jint
+java::net::InetAddress::getFamily (jbyteArray bytes)
+{
+  return 0;
+}
+
+JArray<java::net::InetAddress*> *
+java::net::InetAddress::lookup (jstring, java::net::InetAddress *, jboolean)
+{
+  return NULL;
+}
+
+jstring
+java::net::InetAddress::getLocalHostname ()
+{
+  return NULL;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/net/natInetAddressPosix.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/net/natInetAddressPosix.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/net/natInetAddressPosix.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/net/natInetAddressPosix.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,304 @@
+/* Copyright (C) 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/net/InetAddress.h>
+#include <java/net/UnknownHostException.h>
+#include <java/lang/SecurityException.h>
+
+#if defined(HAVE_UNAME) && ! defined(HAVE_GETHOSTNAME)
+#include <sys/utsname.h>
+#endif
+
+#ifndef HAVE_GETHOSTNAME_DECL
+extern "C" int gethostname (char *name, int namelen);
+#endif
+
+jbyteArray
+java::net::InetAddress::aton (jstring host)
+{
+  char *hostname;
+  char buf[100];
+  int len = JvGetStringUTFLength(host);
+  if (len < 100)
+    hostname = buf;
+  else
+    hostname = (char*) _Jv_AllocBytes (len+1);
+  JvGetStringUTFRegion (host, 0, host->length(), hostname);
+  buf[len] = '\0';
+  char* bytes = NULL;
+  int blen = 0;
+#ifdef HAVE_INET_ATON
+  struct in_addr laddr;
+  if (inet_aton (hostname, &laddr))
+    {
+      bytes = (char*) &laddr;
+      blen = 4;
+    }
+#elif defined(HAVE_INET_ADDR)
+#if ! HAVE_IN_ADDR_T
+  typedef jint in_addr_t;
+#endif
+  in_addr_t laddr = inet_addr (hostname);
+  if (laddr != (in_addr_t)(-1))
+    {
+      bytes = (char*) &laddr;
+      blen = 4;
+    }
+#endif
+#if defined (HAVE_INET_PTON) && defined (HAVE_INET6)
+  char inet6_addr[16];
+  if (len != 0 && inet_pton (AF_INET6, hostname, inet6_addr) > 0)
+    {
+      bytes = inet6_addr;
+      blen = 16;
+    }
+#endif
+  if (blen == 0)
+    return NULL;
+  jbyteArray result = JvNewByteArray (blen);
+  memcpy (elements (result), bytes, blen);
+  return result;
+}
+
+jint
+java::net::InetAddress::getFamily (jbyteArray bytes)
+{
+  int len = bytes->length;
+  if (len == 4)
+    return AF_INET;
+#ifdef HAVE_INET6
+  else if (len == 16)
+    return AF_INET6;
+#endif /* HAVE_INET6 */
+  else
+    JvFail ("unrecognized size");
+}
+
+
+JArray<java::net::InetAddress*> *
+java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
+				jboolean all)
+{
+  struct hostent *hptr = NULL;
+#if defined (HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR_R)
+  struct hostent hent_r;
+#if HAVE_STRUCT_HOSTENT_DATA
+  struct hostent_data fixed_buffer, *buffer_r = &fixed_buffer;
+#else
+#if defined (__GLIBC__) 
+  // FIXME: in glibc, gethostbyname_r returns NETDB_INTERNAL to herr and
+  // ERANGE to errno if the buffer size is too small, rather than what is 
+  // expected here. We work around this by setting a bigger buffer size and 
+  // hoping that it is big enough.
+  char fixed_buffer[1024];
+#else
+  char fixed_buffer[200];
+#endif
+  char *buffer_r = fixed_buffer;
+  int size_r = sizeof (fixed_buffer);
+#endif
+#endif
+
+  if (host != NULL)
+    {
+      char *hostname;
+      char buf[100];
+      int len = JvGetStringUTFLength(host);
+      if (len < 100)
+	hostname = buf;
+      else
+	hostname = (char*) _Jv_AllocBytes (len+1);
+      JvGetStringUTFRegion (host, 0, host->length(), hostname);
+      buf[len] = '\0';
+#ifdef HAVE_GETHOSTBYNAME_R
+      while (true)
+	{
+	  int ok;
+#if HAVE_STRUCT_HOSTENT_DATA
+	  ok = ! gethostbyname_r (hostname, &hent_r, buffer_r);
+#else
+	  int herr = 0;
+#ifdef GETHOSTBYNAME_R_RETURNS_INT
+	  ok = ! gethostbyname_r (hostname, &hent_r, buffer_r, size_r,
+				  &hptr, &herr);
+#else
+	  hptr = gethostbyname_r (hostname, &hent_r, buffer_r, size_r, &herr);
+	  ok = hptr != NULL;
+#endif /* GETHOSTNAME_R_RETURNS_INT */
+	  if (! ok && herr == ERANGE)
+	    {
+	      size_r *= 2;
+	      buffer_r = (char *) _Jv_AllocBytes (size_r);
+	    }
+	  else
+#endif /* HAVE_STRUCT_HOSTENT_DATA */
+	    break;
+	}
+#else
+      // FIXME: this is insufficient if some other piece of code calls
+      // this gethostbyname.
+      JvSynchronize sync (java::net::InetAddress::loopbackAddress);
+      hptr = gethostbyname (hostname);
+#endif /* HAVE_GETHOSTBYNAME_R */
+    }
+  else
+    {
+      jbyteArray bytes = iaddr->addr;
+      char *chars = (char*) elements (bytes);
+      int len = bytes->length;
+      int type;
+      char *val;
+      if (len == 4)
+	{
+	  val = chars;
+	  type = iaddr->family = AF_INET;
+	}
+#ifdef HAVE_INET6
+      else if (len == 16)
+	{
+	  val = (char *) &chars;
+	  type = iaddr->family = AF_INET6;
+	}
+#endif /* HAVE_INET6 */
+      else
+	JvFail ("unrecognized size");
+
+#ifdef HAVE_GETHOSTBYADDR_R
+      while (true)
+	{
+	  int ok;
+#if HAVE_STRUCT_HOSTENT_DATA
+	  ok = ! gethostbyaddr_r (val, len, type, &hent_r, buffer_r);
+#else
+	  int herr = 0;
+#ifdef GETHOSTBYADDR_R_RETURNS_INT
+	  ok = ! gethostbyaddr_r (val, len, type, &hent_r,
+				  buffer_r, size_r, &hptr, &herr);
+#else
+	  hptr = gethostbyaddr_r (val, len, type, &hent_r,
+				  buffer_r, size_r, &herr);
+	  ok = hptr != NULL;
+#endif /* GETHOSTBYADDR_R_RETURNS_INT */
+	  if (! ok && herr == ERANGE)
+	    {
+	      size_r *= 2;
+	      buffer_r = (char *) _Jv_AllocBytes (size_r);
+	    }
+	  else 
+#endif /* HAVE_STRUCT_HOSTENT_DATA */
+	    break;
+	}
+#else /* HAVE_GETHOSTBYADDR_R */
+      // FIXME: this is insufficient if some other piece of code calls
+      // this gethostbyaddr.
+      JvSynchronize sync (java::net::InetAddress::loopbackAddress);
+      hptr = gethostbyaddr (val, len, type);
+#endif /* HAVE_GETHOSTBYADDR_R */
+    }
+  if (hptr != NULL)
+    {
+      if (!all)
+        host = JvNewStringUTF (hptr->h_name);
+    }
+  if (hptr == NULL)
+    {
+      if (iaddr != NULL && iaddr->addr != NULL)
+	{
+	  iaddr->hostName = iaddr->getHostAddress();
+	  return NULL;
+	}
+      else
+	throw new java::net::UnknownHostException(host);
+    }
+  int count;
+  if (all)
+    {
+      char** ptr = hptr->h_addr_list;
+      count = 0;
+      while (*ptr++)  count++;
+    }
+  else
+    count = 1;
+  JArray<java::net::InetAddress*> *result;
+  java::net::InetAddress** iaddrs;
+  if (all)
+    {
+      result = java::net::InetAddress::allocArray (count);
+      iaddrs = elements (result);
+    }
+  else
+    {
+      result = NULL;
+      iaddrs = &iaddr;
+    }
+
+  for (int i = 0;  i < count;  i++)
+    {
+      if (iaddrs[i] == NULL)
+	iaddrs[i] = new java::net::InetAddress (NULL, NULL);
+      if (iaddrs[i]->hostName == NULL)
+        iaddrs[i]->hostName = host;
+      if (iaddrs[i]->addr == NULL)
+	{
+	  char *bytes = hptr->h_addr_list[i];
+	  iaddrs[i]->addr = JvNewByteArray (hptr->h_length);
+	  iaddrs[i]->family = getFamily (iaddrs[i]->addr);
+	  memcpy (elements (iaddrs[i]->addr), bytes, hptr->h_length);
+	}
+    }
+  return result;
+}
+
+jstring
+java::net::InetAddress::getLocalHostname ()
+{
+  char *chars;
+#ifdef HAVE_GETHOSTNAME
+  char buffer[MAXHOSTNAMELEN];
+  if (gethostname (buffer, MAXHOSTNAMELEN))
+    return NULL;
+  chars = buffer;
+#elif HAVE_UNAME
+  struct utsname stuff;
+  if (uname (&stuff) != 0)
+    return NULL;
+  chars = stuff.nodename;
+#else
+  return NULL;
+#endif
+  // It is admittedly non-optimal to convert the hostname to Unicode
+  // only to convert it back in getByName, but simplicity wins.  Note
+  // that unless there is a SecurityManager, we only get called once
+  // anyway, thanks to the InetAddress.localhost cache.
+  return JvNewStringUTF (chars);
+}

Added: llvm-gcc-4.2/trunk/libjava/java/net/natInetAddressWin32.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/net/natInetAddressWin32.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/net/natInetAddressWin32.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/net/natInetAddressWin32.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,168 @@
+/* Copyright (C) 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#undef STRICT
+
+#include <java/net/InetAddress.h>
+#include <java/net/UnknownHostException.h>
+#include <java/lang/SecurityException.h>
+
+jbyteArray
+java::net::InetAddress::aton (jstring host)
+{
+  JV_TEMP_UTF_STRING (hostname, host);
+  char* bytes = NULL;
+  int blen = 0;
+  unsigned long laddr = inet_addr (hostname);
+  if (laddr != INADDR_NONE)
+    {
+      bytes = (char*) &laddr;
+      blen = 4;
+    }
+  if (blen == 0)
+    return NULL;
+  jbyteArray result = JvNewByteArray (blen);
+  memcpy (elements (result), bytes, blen);
+  return result;
+}
+
+jint
+java::net::InetAddress::getFamily (jbyteArray bytes)
+{
+  int len = bytes->length;
+  if (len == 4)
+    return AF_INET;
+#ifdef HAVE_INET6
+  else if (len == 16)
+    return AF_INET6;
+#endif /* HAVE_INET6 */
+  else
+    JvFail ("unrecognized size");
+}
+
+
+JArray<java::net::InetAddress*> *
+java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
+        jboolean all)
+{
+  struct hostent *hptr = NULL;
+  if (host != NULL)
+    {
+      JV_TEMP_UTF_STRING (hostname, host);
+
+      // FIXME: this is insufficient if some other piece of code calls
+      // this gethostbyname.
+      JvSynchronize sync (java::net::InetAddress::loopbackAddress);
+      hptr = gethostbyname (hostname);
+    }
+  else
+    {
+      jbyteArray bytes = iaddr->addr;
+      char *chars = (char*) elements (bytes);
+      int len = bytes->length;
+      int type;
+      char *val;
+      if (len == 4)
+        {
+          val = chars;
+          type = iaddr->family = AF_INET;
+        }
+#ifdef HAVE_INET6
+      else if (len == 16)
+      {
+        val = (char *) &chars;
+        type = iaddr->family = AF_INET6;
+      }
+#endif /* HAVE_INET6 */
+      else
+        JvFail ("unrecognized size");
+
+      // FIXME: this is insufficient if some other piece of code calls
+      // this gethostbyaddr.
+      JvSynchronize sync (java::net::InetAddress::loopbackAddress);
+      hptr = gethostbyaddr (val, len, type);
+    }
+  if (hptr != NULL)
+    {
+      if (!all)
+        host = JvNewStringUTF (hptr->h_name);
+      java::lang::SecurityException *ex = checkConnect (host);
+      if (ex != NULL)
+        {
+          if (iaddr == NULL || iaddr->addr == NULL)
+            throw ex;
+          hptr = NULL;
+        }
+    }
+  if (hptr == NULL)
+    {
+      if (iaddr != NULL && iaddr->addr != NULL)
+        {
+          iaddr->hostName = iaddr->getHostAddress();
+          return NULL;
+        }
+      else
+        throw new java::net::UnknownHostException(host);
+    }
+
+  int count;
+  if (all)
+    {
+      char** ptr = hptr->h_addr_list;
+      count = 0;
+      while (*ptr++)  count++;
+    }
+  else
+    count = 1;
+
+  JArray<java::net::InetAddress*> *result;
+  java::net::InetAddress** iaddrs;
+  if (all)
+    {
+      result = java::net::InetAddress::allocArray (count);
+      iaddrs = elements (result);
+    }
+  else
+    {
+      result = NULL;
+      iaddrs = &iaddr;
+    }
+
+  for (int i = 0;  i < count;  i++)
+    {
+      if (iaddrs[i] == NULL)
+        iaddrs[i] = new java::net::InetAddress (NULL, NULL);
+      if (iaddrs[i]->hostName == NULL)
+        iaddrs[i]->hostName = host;
+      if (iaddrs[i]->addr == NULL)
+        {
+          char *bytes = hptr->h_addr_list[i];
+          iaddrs[i]->addr = JvNewByteArray (hptr->h_length);
+          iaddrs[i]->family = getFamily (iaddrs[i]->addr);
+          memcpy (elements (iaddrs[i]->addr), bytes, hptr->h_length);
+        }
+    }
+    
+  return result;
+}
+
+jstring
+java::net::InetAddress::getLocalHostname ()
+{
+  char buffer[400];
+  if (gethostname (buffer, sizeof(buffer)))
+    return NULL;
+  // It is admittedly non-optimal to convert the hostname to Unicode
+  // only to convert it back in getByName, but simplicity wins.  Note
+  // that unless there is a SecurityManager, we only get called once
+  // anyway, thanks to the InetAddress.localhost cache.
+  return JvNewStringUTF (buffer);
+}

Added: llvm-gcc-4.2/trunk/libjava/java/net/natURLClassLoader.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/net/natURLClassLoader.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/net/natURLClassLoader.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/net/natURLClassLoader.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,22 @@
+// natURLClassLoader.cc -- Native part of the URLClassLoader class.
+
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/net/URLClassLoader.h>
+
+jboolean
+java::net::URLClassLoader::runtimeInitialized ()
+{
+  return gcj::runtimeInitialized;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/net/natVMNetworkInterfaceNoNet.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/net/natVMNetworkInterfaceNoNet.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/net/natVMNetworkInterfaceNoNet.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/net/natVMNetworkInterfaceNoNet.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,21 @@
+/* Copyright (C) 2003, 2005  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#include <java/net/SocketException.h>
+#include <java/net/VMNetworkInterface.h>
+#include <java/util/Vector.h>
+
+::java::util::Vector*
+java::net::VMNetworkInterface::getInterfaces ()
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("VMNetworkInterface.getInterfaces: unimplemented"));
+}

Added: llvm-gcc-4.2/trunk/libjava/java/net/natVMNetworkInterfacePosix.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/net/natVMNetworkInterfacePosix.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/net/natVMNetworkInterfacePosix.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/net/natVMNetworkInterfacePosix.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,163 @@
+/* Copyright (C) 2003, 2005, 2006  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#define BSD_COMP /* Get FIONREAD on Solaris2. */
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_IFADDRS_H
+#include <ifaddrs.h>
+#endif
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/net/InetAddress.h>
+#include <java/net/NetworkInterface.h>
+#include <java/net/SocketException.h>
+#include <java/net/VMNetworkInterface.h>
+#include <java/util/Vector.h>
+
+::java::util::Vector*
+java::net::VMNetworkInterface::getInterfaces ()
+{
+  ::java::util::Vector* ht = new ::java::util::Vector ();
+
+#ifdef HAVE_GETIFADDRS
+
+  struct ifaddrs *addrs;
+  if (::getifaddrs (&addrs) == -1)
+    throw new ::java::net::SocketException(JvNewStringUTF (strerror (errno)));
+
+  for (struct ifaddrs *work = addrs; work != NULL; work = work->ifa_next)
+    {
+      // Sometimes the address can be NULL; I don't know why but
+      // there's nothing we can do with this.
+      if (! work->ifa_addr)
+	continue;
+      // We only return Inet4 or Inet6 addresses.
+      jbyteArray laddr;
+      if (work->ifa_addr->sa_family == AF_INET)
+	{
+	  sockaddr_in *real = reinterpret_cast<sockaddr_in *> (work->ifa_addr);
+	  laddr = JvNewByteArray(4);
+	  memcpy (elements (laddr), &real->sin_addr, 4);
+	}
+#ifdef HAVE_INET6
+      else if (work->ifa_addr->sa_family == AF_INET6)
+	{
+	  sockaddr_in6 *real
+	    = reinterpret_cast<sockaddr_in6 *> (work->ifa_addr);
+	  laddr = JvNewByteArray(16);
+	  memcpy (elements (laddr), &real->sin6_addr, 16);
+	}
+#endif
+      else
+	continue;
+
+      ::java::net::InetAddress *inaddr
+	  =  ::java::net::InetAddress::getByAddress(laddr);
+
+      // It is ok to make a new NetworkInterface for each struct; the
+      // java code will unify these as necessary; see
+      // NetworkInterface.condense().
+      jstring name = JvNewStringUTF (work->ifa_name);
+
+      ht->add (new NetworkInterface (name, inaddr));
+    }
+
+  freeifaddrs (addrs);
+
+#else /* ! HAVE_GETIFADDRS */
+
+  int fd;
+  int num_interfaces = 0;
+  struct ifconf if_data;
+  struct ifreq* if_record;
+
+  if_data.ifc_len = 0;
+  if_data.ifc_buf = NULL;
+
+  // Open a (random) socket to have a file descriptor for the ioctl calls.
+  fd = _Jv_socket (PF_INET, SOCK_DGRAM, htons (IPPROTO_IP));
+
+  if (fd < 0)
+    throw new ::java::net::SocketException;
+
+  // Get all interfaces. If not enough buffers are available try it
+  // with a bigger buffer size.
+  do
+    {
+      num_interfaces += 16;
+      
+      if_data.ifc_len = sizeof (struct ifreq) * num_interfaces;
+      if_data.ifc_buf =
+        (char*) _Jv_Realloc (if_data.ifc_buf, if_data.ifc_len);
+
+      // Try to get all local interfaces.
+      if (::ioctl (fd, SIOCGIFCONF, &if_data) < 0)
+        throw new java::net::SocketException;
+    }
+  while (if_data.ifc_len >= (int) (sizeof (struct ifreq) * num_interfaces));
+
+  // Get addresses of all interfaces.
+  if_record = if_data.ifc_req;
+
+  for (int n = 0; n < if_data.ifc_len; n += sizeof (struct ifreq))
+    {
+      struct ifreq ifr;
+      
+      memset (&ifr, 0, sizeof (ifr));
+      strcpy (ifr.ifr_name, if_record->ifr_name);
+
+      // Try to get the IPv4-address of the local interface
+      if (::ioctl (fd, SIOCGIFADDR, &ifr) < 0)
+        throw new java::net::SocketException;
+
+      int len = 4;
+      struct sockaddr_in sa = *((sockaddr_in*) &(ifr.ifr_addr));
+
+      jbyteArray baddr = JvNewByteArray (len);
+      memcpy (elements (baddr), &(sa.sin_addr), len);
+      jstring if_name = JvNewStringLatin1 (if_record->ifr_name);
+      InetAddress* address = java::net::InetAddress::getByAddress (baddr);
+      ht->add (new NetworkInterface (if_name, address));
+      if_record++;
+    }
+
+  _Jv_Free (if_data.ifc_buf);
+  
+  if (fd >= 0)
+    _Jv_close (fd);
+#endif /* HAVE_GETIFADDRS */ 
+
+  return ht;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/net/natVMNetworkInterfaceWin32.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/net/natVMNetworkInterfaceWin32.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/net/natVMNetworkInterfaceWin32.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/net/natVMNetworkInterfaceWin32.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,144 @@
+/* Copyright (C) 2003, 2005  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#undef STRICT
+
+#include <java/net/NetworkInterface.h>
+#include <java/net/Inet4Address.h>
+#include <java/net/SocketException.h>
+#include <java/net/VMNetworkInterface.h>
+#include <java/util/Vector.h>
+
+/* As of this writing, NetworkInterface.java has
+   getName() == getDisplayName() and only one IP address
+   per interface. If this changes, we'll need to use
+   iphlpapi (not supported on Win95) to retrieve richer
+   adapter information via GetAdaptersInfo(). In this
+   module, we provide the necessary hooks to detect the
+   presence of iphlpapi and use it if necessary, but
+   comment things out for now to avoid compiler warnings. */
+
+enum {MAX_INTERFACES = 50};
+
+typedef int
+(*PfnGetRealNetworkInterfaces) (jstring* pjstrName,
+  java::net::InetAddress** ppAddress);
+
+static int
+winsock2GetRealNetworkInterfaces (jstring* pjstrName,
+  java::net::InetAddress** ppAddress)
+{
+  // FIXME: Add IPv6 support.
+  
+  INTERFACE_INFO arInterfaceInfo[MAX_INTERFACES];
+
+  // Open a (random) socket to have a file descriptor for the WSAIoctl call.
+  SOCKET skt = ::socket (AF_INET, SOCK_DGRAM, 0);
+  if (skt == INVALID_SOCKET) 
+    _Jv_ThrowSocketException ();
+    
+  DWORD dwOutBufSize;
+  int nRetCode = ::WSAIoctl (skt, SIO_GET_INTERFACE_LIST,
+    NULL, 0, &arInterfaceInfo, sizeof(arInterfaceInfo),
+    &dwOutBufSize, NULL, NULL);
+    
+  if (nRetCode == SOCKET_ERROR)
+  {
+    DWORD dwLastErrorCode = WSAGetLastError ();
+    ::closesocket (skt);
+    _Jv_ThrowSocketException (dwLastErrorCode);
+  }
+  
+  // Get addresses of all interfaces.
+  int nNbInterfaces = dwOutBufSize / sizeof(INTERFACE_INFO);
+  int nCurETHInterface = 0;
+  for (int i=0; i < nNbInterfaces; ++i) 
+    {
+      int len = 4;
+      jbyteArray baddr = JvNewByteArray (len);
+      SOCKADDR_IN* pAddr = (SOCKADDR_IN*) &arInterfaceInfo[i].iiAddress;
+      memcpy (elements (baddr), &(pAddr->sin_addr), len);
+
+      // Concoct a name for this interface. Since we don't
+      // have access to the real name under Winsock 2, we use
+      // "lo" for the loopback interface and ethX for the
+      // real ones.
+      TCHAR szName[30];
+      u_long lFlags = arInterfaceInfo[i].iiFlags;
+
+      if (lFlags & IFF_LOOPBACK)
+        _tcscpy (szName, _T("lo"));
+      else
+        {
+          _tcscpy (szName, _T("eth"));
+          wsprintf(szName+3, _T("%d"), nCurETHInterface++);
+        }
+
+      jstring if_name = _Jv_Win32NewString (szName);
+      java::net::Inet4Address* address =
+        new java::net::Inet4Address (baddr, JvNewStringLatin1 (""));
+      pjstrName[i] = if_name;
+      ppAddress[i] = address;
+    }
+
+  ::closesocket (skt);
+  
+  return nNbInterfaces;
+}
+
+/*
+static int
+iphlpapiGetRealNetworkInterfaces (jstring* pjstrName,
+  java::net::InetAddress** ppAddress)
+{
+  return 0;
+}
+*/
+
+static PfnGetRealNetworkInterfaces
+determineGetRealNetworkInterfacesFN ()
+{
+  /* FIXME: Try to dynamically load iphlpapi.dll and
+     detect the presence of GetAdaptersInfo() using
+     GetProcAddress(). If successful, return
+     iphlpapiGetRealNetworkInterfaces; if not,
+     return winsock2GetRealNetworkInterfaces */
+  return &winsock2GetRealNetworkInterfaces;
+}
+
+::java::util::Vector*
+java::net::VMNetworkInterface::getInterfaces ()
+{
+  // This next declaration used to be a static local,
+  // but this introduced a dependency on libsupc++ due
+  // to _cxa_guard_acquire and _cxa_guard_release.
+  // When Win95 is gone and we eventually get rid of
+  // winsock2GetRealNetworkInterfaces, we can rework
+  // all of this. Alternatively, we could move this all
+  // to win32.cc and initialize this at startup time,
+  // but that seems more trouble than it's worth at
+  // the moment.
+  PfnGetRealNetworkInterfaces pfn =
+    determineGetRealNetworkInterfacesFN ();
+    
+  jstring arIFName[MAX_INTERFACES];
+  InetAddress* arpInetAddress[MAX_INTERFACES];
+  ::java::util::Vector* ht = new ::java::util::Vector ();
+  
+  int nNbInterfaces = (*pfn) (arIFName, arpInetAddress);
+  for (int i=0; i < nNbInterfaces; ++i) 
+    {
+      ht->add (new java::net::NetworkInterface (arIFName[i],
+        arpInetAddress[i]));
+    }
+    
+  return ht;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/nio/Buffer.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/nio/Buffer.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/nio/Buffer.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/nio/Buffer.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,361 @@
+/* Buffer.java -- 
+   Copyright (C) 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.nio;
+
+import gnu.gcj.RawData;
+
+/**
+ * @since 1.4
+ */
+public abstract class Buffer
+{
+  int cap = 0;
+  int limit = 0;
+  int pos = 0;
+  int mark = -1;
+  RawData address;
+
+  /**
+   * Creates a new Buffer.
+   *
+   * Should be package private.
+   */
+  Buffer (int capacity, int limit, int position, int mark)
+  {
+    if (capacity < 0)
+      throw new IllegalArgumentException ();
+    
+    cap = capacity;
+    limit (limit);
+    position (position);
+    
+    if (mark >= 0)
+    {
+      if (mark > pos)
+        throw new IllegalArgumentException ();
+      
+      this.mark = mark;
+    }
+  }
+  
+  /**
+   * Retrieves the capacity of the buffer.
+   *
+   * @return the capacity of the buffer
+   */
+  public final int capacity ()
+  {
+    return cap;
+  }
+
+  /**
+   * Clears the buffer.
+   *
+   * @return this buffer
+   */
+  public final Buffer clear ()
+  {
+    limit = cap;
+    pos = 0;
+    mark = -1;
+    return this;
+  }
+    
+  /**
+   * Flips the buffer.
+   *
+   * @return this buffer
+   */
+  public final Buffer flip ()
+  {
+    limit = pos;
+    pos = 0;
+    mark = -1;
+    return this;
+  }
+    
+  /**
+   * Tells whether the buffer has remaining data to read or not.
+   *
+   * @return true if the buffer contains remaining data to read,
+   * false otherwise
+   */
+  public final boolean hasRemaining ()
+  {
+    return remaining() > 0;
+  }
+
+  /**
+   * Tells whether this buffer is read only or not.
+   *
+   * @return true if the buffer is read only, false otherwise
+   */
+  public abstract boolean isReadOnly ();
+
+  /**
+   * Retrieves the current limit of the buffer.
+   *
+   * @return the limit of the buffer
+   */
+  public final int limit ()
+  {
+    return limit;
+  }
+
+  /**
+   * Sets this buffer's limit.
+   * 
+   * @param newLimit The new limit value; must be non-negative and no larger
+   * than this buffer's capacity.
+   *
+   * @return this buffer
+   *
+   * @exception IllegalArgumentException If the preconditions on newLimit
+   * do not hold.
+   */
+  public final Buffer limit (int newLimit)
+  {
+    if ((newLimit < 0) || (newLimit > cap))
+      throw new IllegalArgumentException ();
+
+    if (newLimit < mark)
+        mark = -1;
+
+    if (pos > newLimit)
+        pos = newLimit;
+
+    limit = newLimit;
+    return this;
+  }
+
+  /**
+   * Sets this buffer's mark at its position.
+   *
+   * @return this buffer
+   */
+  public final Buffer mark ()
+  {
+    mark = pos;
+    return this;
+  }
+
+  /**
+   * Retrieves the current position of this buffer.
+   *
+   * @return the current position of this buffer
+   */
+  public final int position ()
+  {
+    return pos;
+  }
+    
+  /**
+   * Sets this buffer's position. If the mark is defined and larger than the
+   * new position then it is discarded.
+   * 
+   * @param newPosition The new position value; must be non-negative and no
+   * larger than the current limit.
+   *
+   * @return this buffer
+   *
+   * @exception IllegalArgumentException If the preconditions on newPosition
+   * do not hold
+   */
+  public final Buffer position (int newPosition)
+  {
+    if ((newPosition < 0) || (newPosition > limit))
+      throw new IllegalArgumentException ();
+
+    if (newPosition <= mark)
+        mark = -1;
+
+    pos = newPosition;
+    return this;
+  }
+
+  /**
+   * Returns the number of elements between the current position and the limit.
+   *
+   * @return the number of remaining elements
+   */
+  public final int remaining()
+  {
+    return limit - pos;
+  }
+
+  /**
+   * Resets this buffer's position to the previously-marked position.
+   *
+   * @return this buffer
+   *
+   * @exception InvalidMarkException If the mark has not been set.
+   */
+  public final Buffer reset()
+  {
+    if (mark == -1)
+      throw new InvalidMarkException ();
+
+    pos = mark;
+    return this;
+  }
+
+  /**
+   * Rewinds this buffer. The position is set to zero and the mark
+   * is discarded.
+   *
+   * @return this buffer
+   */
+  public final Buffer rewind()
+  {
+    pos = 0;
+    mark = -1;
+    return this;
+  }
+
+  /**
+   * Checks for underflow. This method is used internally to check
+   * whether a buffer has enough elements left to satisfy a read 
+   * request.
+   *
+   * @exception BufferUnderflowException If there are no remaining
+   * elements in this buffer.
+   */
+  final void checkForUnderflow()
+  {
+    if (!hasRemaining())
+      throw new BufferUnderflowException();
+  }
+
+  /**
+   * Checks for underflow. This method is used internally to check
+   * whether a buffer has enough elements left to satisfy a read 
+   * request for a given number of elements.
+   *
+   * @param length The length of a sequence of elements.
+   *
+   * @exception BufferUnderflowException If there are not enough 
+   * remaining elements in this buffer.
+   */
+  final void checkForUnderflow(int length)
+  {
+    if (remaining() < length)
+      throw new BufferUnderflowException();
+  }
+
+  /**
+   * Checks for overflow. This method is used internally to check
+   * whether a buffer has enough space left to satisfy a write 
+   * request.
+   *
+   * @exception BufferOverflowException If there is no remaining
+   * space in this buffer.
+   */
+  final void checkForOverflow()
+  {
+    if (!hasRemaining())
+      throw new BufferOverflowException();
+  }
+
+  /**
+   * Checks for overflow. This method is used internally to check
+   * whether a buffer has enough space left to satisfy a write 
+   * request for a given number of elements.
+   *
+   * @param length The length of a sequence of elements.
+   *
+   * @exception BufferUnderflowException If there is not enough 
+   * remaining space in this buffer.
+   */
+  final void checkForOverflow(int length)
+  {
+    if (remaining() < length)
+      throw new BufferOverflowException();
+  }
+
+  /**
+   * Checks if index is negative or not smaller than the buffer's 
+   * limit. This method is used internally to check whether
+   * an indexed request can be fulfilled.
+   *
+   * @param index The requested position in the buffer.
+   *
+   * @exception IndexOutOfBoundsException If index is negative or not smaller
+   * than the buffer's limit.
+   */
+  final void checkIndex(int index)
+  {
+    if (index < 0
+        || index >= limit ())
+      throw new IndexOutOfBoundsException ();
+  }
+
+  /**
+   * Checks if buffer is read-only. This method is used internally to
+   * check if elements can be put into a buffer.
+   *
+   * @exception ReadOnlyBufferException If this buffer is read-only.
+   */
+  final void checkIfReadOnly() 
+  {
+    if (isReadOnly())
+      throw new ReadOnlyBufferException ();
+  }
+
+  /**
+   * Checks whether an array is large enough to hold the given number of
+   * elements at the given offset. This method is used internally to
+   * check if an array is big enough.
+   *
+   * @param arraylength The length of the array.
+   * @param offset The offset within the array of the first byte to be read;
+   * must be non-negative and no larger than arraylength.
+   * @param length The number of bytes to be read from the given array;
+   * must be non-negative and no larger than arraylength - offset.
+   *
+   * @exception IndexOutOfBoundsException If the preconditions on the offset
+   * and length parameters do not hold
+   */
+  static final void checkArraySize(int arraylength, int offset, int length)
+  {
+    if ((offset < 0) ||
+        (length < 0) ||
+        (arraylength < length + offset))
+      throw new IndexOutOfBoundsException ();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/nio/DirectByteBufferImpl.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/nio/DirectByteBufferImpl.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/nio/DirectByteBufferImpl.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/nio/DirectByteBufferImpl.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,431 @@
+/* DirectByteBufferImpl.java -- 
+   Copyright (C) 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.nio;
+
+import gnu.gcj.RawData;
+
+abstract class DirectByteBufferImpl extends ByteBuffer
+{
+  /**
+   * The owner is used to keep alive the object that actually owns the
+   * memory. There are three possibilities:
+   *  1) owner == this: We allocated the memory and we should free it,
+   *                    but *only* in finalize (if we've been sliced
+   *                    other objects will also have access to the
+   *                    memory).
+   *  2) owner == null: The byte buffer was created thru
+   *                    JNI.NewDirectByteBuffer. The JNI code is
+   *                    responsible for freeing the memory.
+   *  3) owner == some other object: The other object allocated the
+   *                                 memory and should free it.
+   */
+  private final Object owner;
+
+  static final class ReadOnly extends DirectByteBufferImpl
+  {
+    ReadOnly(Object owner, RawData address,
+	     int capacity, int limit,
+	     int position)
+    {
+      super(owner, address, capacity, limit, position);
+    }
+
+    public ByteBuffer put(byte value)
+    {
+      throw new ReadOnlyBufferException ();
+    }
+
+    public ByteBuffer put(int index, byte value)
+    {
+      throw new ReadOnlyBufferException ();
+    }
+
+    public boolean isReadOnly()
+    {
+      return true;
+    }
+  }
+
+  static final class ReadWrite extends DirectByteBufferImpl
+  {
+    ReadWrite(int capacity)
+    {
+      super(capacity);
+    }
+
+    ReadWrite(RawData address, int capacity)
+    {
+      super(address, capacity);
+    }
+    
+    ReadWrite(Object owner, RawData address,
+	      int capacity, int limit,
+	      int position)
+    {
+      super(owner, address, capacity, limit, position);
+    }
+
+    public boolean isReadOnly()
+    {
+      return false;
+    }
+  }
+
+  DirectByteBufferImpl(int capacity)
+  {
+    super(capacity, capacity, 0, -1);
+    this.owner = this;
+    this.address = VMDirectByteBuffer.allocate(capacity);
+  }
+
+  DirectByteBufferImpl(RawData address, int capacity)
+  {
+    super(capacity, capacity, 0, -1);
+    this.owner = null;
+    this.address = address;
+  }
+  
+  DirectByteBufferImpl(Object owner, RawData address,
+		       int capacity, int limit,
+		       int position)
+  {
+    super(capacity, limit, position, -1);
+    this.owner = owner;
+    this.address = address;
+  }
+
+  /**
+   * Allocates a new direct byte buffer.
+   */ 
+  public static ByteBuffer allocate(int capacity)
+  {
+    return new DirectByteBufferImpl.ReadWrite(capacity);
+  }
+
+  protected void finalize() throws Throwable
+  {
+    if (owner == this)
+        VMDirectByteBuffer.free(address);
+  }
+  
+  public byte get()
+  {
+    checkForUnderflow();
+
+    int pos = position();
+    byte result = VMDirectByteBuffer.get(address, pos);
+    position(pos + 1);
+    return result;
+  }
+
+  public byte get(int index)
+  {
+    checkIndex(index);
+
+    return VMDirectByteBuffer.get(address, index);
+  }
+
+  public ByteBuffer get(byte[] dst, int offset, int length)
+  {
+    checkArraySize(dst.length, offset, length);
+    checkForUnderflow(length);
+
+    int index = position();
+    VMDirectByteBuffer.get(address, index, dst, offset, length);
+    position(index+length);
+
+    return this;
+  }
+
+  public ByteBuffer put(byte value)
+  {
+    checkForOverflow();
+
+    int pos = position();
+    VMDirectByteBuffer.put(address, pos, value);
+    position(pos + 1);
+    return this;
+  }
+  
+  public ByteBuffer put(int index, byte value)
+  {
+    checkIndex(index);
+
+    VMDirectByteBuffer.put(address, index, value);
+    return this;
+  }
+  
+  void shiftDown(int dst_offset, int src_offset, int count)
+  {
+    VMDirectByteBuffer.shiftDown(address, dst_offset, src_offset, count);
+  }
+  
+  public ByteBuffer compact()
+  {
+    checkIfReadOnly();
+    mark = -1;
+    int pos = position();
+    if (pos > 0)
+      {
+	int count = remaining();
+	VMDirectByteBuffer.shiftDown(address, 0, pos, count);
+	position(count);
+	limit(capacity());
+      }
+    else
+      {
+	position(limit());
+	limit(capacity());
+      }
+    return this;
+  }
+
+  public ByteBuffer slice()
+  {
+    int rem = remaining();
+    if (isReadOnly())
+        return new DirectByteBufferImpl.ReadOnly
+      (owner, VMDirectByteBuffer.adjustAddress(address, position()),
+       rem, rem, 0);
+    else
+        return new DirectByteBufferImpl.ReadWrite
+      (owner, VMDirectByteBuffer.adjustAddress(address, position()),
+       rem, rem, 0);
+  }
+
+  private ByteBuffer duplicate(boolean readOnly)
+  {
+    int pos = position();
+    reset();
+    int mark = position();
+    position(pos);
+    DirectByteBufferImpl result;
+    if (readOnly)
+        result = new DirectByteBufferImpl.ReadOnly(owner, address, capacity(),
+                                                   limit(), pos);
+    else
+        result = new DirectByteBufferImpl.ReadWrite(owner, address, capacity(),
+                                                    limit(), pos);
+
+    if (mark != pos)
+      {
+	result.position(mark);
+	result.mark();
+	result.position(pos);
+      }
+    return result;
+  }
+
+  public ByteBuffer duplicate()
+  {
+    return duplicate(isReadOnly());
+  }
+
+  public ByteBuffer asReadOnlyBuffer()
+  {
+    return duplicate(true);
+  }
+
+  public boolean isDirect()
+  {
+    return true;
+  }
+
+  public CharBuffer asCharBuffer()
+  {
+    return new CharViewBufferImpl(this, remaining() >> 1);
+  }
+
+  public ShortBuffer asShortBuffer()
+  {
+    return new ShortViewBufferImpl(this, remaining() >> 1);
+  }
+
+  public IntBuffer asIntBuffer()
+  {
+    return new IntViewBufferImpl(this, remaining() >> 2);
+  }
+
+  public LongBuffer asLongBuffer()
+  {
+    return new LongViewBufferImpl(this, remaining() >> 3);
+  }
+
+  public FloatBuffer asFloatBuffer()
+  {
+    return new FloatViewBufferImpl(this, remaining() >> 2);
+  }
+
+  public DoubleBuffer asDoubleBuffer()
+  {
+    return new DoubleViewBufferImpl(this, remaining() >> 3);
+  }
+
+  public char getChar()
+  {
+    return ByteBufferHelper.getChar(this, order());
+  }
+  
+  public ByteBuffer putChar(char value)
+  {
+    ByteBufferHelper.putChar(this, value, order());
+    return this;
+  }
+  
+  public char getChar(int index)
+  {
+    return ByteBufferHelper.getChar(this, index, order());
+  }
+  
+  public ByteBuffer putChar(int index, char value)
+  {
+    ByteBufferHelper.putChar(this, index, value, order());
+    return this;
+  }
+
+  public short getShort()
+  {
+    return ByteBufferHelper.getShort(this, order());
+  }
+  
+  public ByteBuffer putShort(short value)
+  {
+    ByteBufferHelper.putShort(this, value, order());
+    return this;
+  }
+  
+  public short getShort(int index)
+  {
+    return ByteBufferHelper.getShort(this, index, order());
+  }
+  
+  public ByteBuffer putShort(int index, short value)
+  {
+    ByteBufferHelper.putShort(this, index, value, order());
+    return this;
+  }
+
+  public int getInt()
+  {
+    return ByteBufferHelper.getInt(this, order());
+  }
+  
+  public ByteBuffer putInt(int value)
+  {
+    ByteBufferHelper.putInt(this, value, order());
+    return this;
+  }
+  
+  public int getInt(int index)
+  {
+    return ByteBufferHelper.getInt(this, index, order());
+  }
+  
+  public ByteBuffer putInt(int index, int value)
+  {
+    ByteBufferHelper.putInt(this, index, value, order());
+    return this;
+  }
+
+  public long getLong()
+  {
+    return ByteBufferHelper.getLong(this, order());
+  }
+  
+  public ByteBuffer putLong(long value)
+  {
+    ByteBufferHelper.putLong(this, value, order());
+    return this;
+  }
+  
+  public long getLong(int index)
+  {
+    return ByteBufferHelper.getLong(this, index, order());
+  }
+  
+  public ByteBuffer putLong(int index, long value)
+  {
+    ByteBufferHelper.putLong(this, index, value, order());
+    return this;
+  }
+
+  public float getFloat()
+  {
+    return ByteBufferHelper.getFloat(this, order());
+  }
+  
+  public ByteBuffer putFloat(float value)
+  {
+    ByteBufferHelper.putFloat(this, value, order());
+    return this;
+  }
+  
+  public float getFloat(int index)
+  {
+    return ByteBufferHelper.getFloat(this, index, order());
+  }
+
+  public ByteBuffer putFloat(int index, float value)
+  {
+    ByteBufferHelper.putFloat(this, index, value, order());
+    return this;
+  }
+
+  public double getDouble()
+  {
+    return ByteBufferHelper.getDouble(this, order());
+  }
+
+  public ByteBuffer putDouble(double value)
+  {
+    ByteBufferHelper.putDouble(this, value, order());
+    return this;
+  }
+  
+  public double getDouble(int index)
+  {
+    return ByteBufferHelper.getDouble(this, index, order());
+  }
+  
+  public ByteBuffer putDouble(int index, double value)
+  {
+    ByteBufferHelper.putDouble(this, index, value, order());
+    return this;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/nio/MappedByteBuffer.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/nio/MappedByteBuffer.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/nio/MappedByteBuffer.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/nio/MappedByteBuffer.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,89 @@
+/* MappedByteBuffer.java -- 
+   Copyright (C) 2002, 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;
+
+/**
+ * @author Michael Koch (konqueror at gmx.de)
+ * @since 1.4
+ */
+public abstract class MappedByteBuffer extends ByteBuffer
+{
+  MappedByteBuffer (int capacity, int limit, int position, int mark)
+  {
+    super (capacity, limit, position, mark);
+  }
+  
+  void forceImpl()
+  {
+  }
+
+  public final MappedByteBuffer force ()
+  {
+    forceImpl();
+    return this;
+  }
+    
+  boolean isLoadedImpl()
+  {
+    load();
+    return true;
+  }
+
+  public final boolean isLoaded ()
+  {
+    return isLoadedImpl();
+  }
+    
+  void loadImpl()
+  {
+  }
+
+  public final MappedByteBuffer load ()
+  {
+    loadImpl();
+    return this;
+  }
+
+  void unmapImpl ()
+  {
+    forceImpl();
+  }
+
+  public void finalize () { unmapImpl(); }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/nio/MappedByteBufferImpl.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/nio/MappedByteBufferImpl.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/nio/MappedByteBufferImpl.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/nio/MappedByteBufferImpl.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,360 @@
+/* MappedByteBufferImpl.java -- 
+   Copyright (C) 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.nio;
+
+import gnu.gcj.RawData;
+
+import java.io.IOException;
+
+final class MappedByteBufferImpl extends MappedByteBuffer
+{
+  boolean readOnly;
+
+  /** Posix uses this for the pointer returned by mmap;
+   * Win32 uses it for the pointer returned by MapViewOfFile. */
+  public RawData implPtr;
+  /** Posix uses this for the actual length passed to mmap;
+   * Win32 uses it for the pointer returned by CreateFileMapping. */
+  public long implLen;
+  
+  public MappedByteBufferImpl(RawData address, int size, boolean readOnly)
+    throws IOException
+  {
+    super(size, size, 0, -1);
+    this.address = address;
+    this.readOnly = readOnly;
+  }
+
+  public boolean isReadOnly()
+  {
+    return readOnly;
+  }
+  
+  public byte get()
+  {
+    checkForUnderflow();
+
+    int pos = position();
+    byte result = VMDirectByteBuffer.get(address, pos);
+    position(pos + 1);
+    return result;
+  }
+
+  public ByteBuffer put(byte value)
+  {
+    checkIfReadOnly();
+    checkForOverflow();
+
+    int pos = position();
+    VMDirectByteBuffer.put(address, pos, value);
+    position(pos + 1);
+    return this;
+  }
+
+  public byte get(int index)
+  {
+    checkIndex(index);
+
+    return VMDirectByteBuffer.get(address, index);
+  }
+
+  public ByteBuffer get(byte[] dst, int offset, int length)
+  {
+    checkArraySize(dst.length, offset, length);
+    checkForUnderflow(length);
+
+    int index = position();
+    VMDirectByteBuffer.get(address, index, dst, offset, length);
+    position(index+length);
+
+    return this;
+  }
+
+  public ByteBuffer put(int index, byte value)
+  {
+    checkIfReadOnly();
+    checkIndex(index);
+
+    VMDirectByteBuffer.put(address, index, value);
+    return this;
+  }
+
+  public ByteBuffer compact()
+  {
+    checkIfReadOnly();
+    mark = -1;
+    int pos = position();
+    if (pos > 0)
+      {
+	int count = remaining();
+	// Call shiftDown method optimized for direct buffers.
+	VMDirectByteBuffer.shiftDown(address, 0, pos, count);
+	position(count);
+	limit(capacity());
+      }
+    else
+      {
+	position(limit());
+	limit(capacity());
+      }
+    return this;
+  }
+
+  public boolean isDirect()
+  {
+    return true;
+  }
+
+  public ByteBuffer slice()
+  {
+    int rem = remaining();
+    if (isReadOnly())
+        return new DirectByteBufferImpl.ReadOnly
+      (this, VMDirectByteBuffer.adjustAddress(address, position()),
+       rem, rem, 0);
+    else
+        return new DirectByteBufferImpl.ReadWrite
+      (this, VMDirectByteBuffer.adjustAddress(address, position()),
+       rem, rem, 0);
+  }
+
+  private ByteBuffer duplicate(boolean readOnly)
+  {
+    int pos = position();
+    reset();
+    int mark = position();
+    position(pos);
+    DirectByteBufferImpl result;
+    if (readOnly)
+        result = new DirectByteBufferImpl.ReadOnly(this, address, capacity(),
+                                                   limit(), pos);
+    else
+        result = new DirectByteBufferImpl.ReadWrite(this, address, capacity(),
+                                                    limit(), pos);
+
+    if (mark != pos)
+      {
+	result.position(mark);
+	result.mark();
+	result.position(pos);
+      }
+    return result;
+  }
+
+  public ByteBuffer duplicate()
+  {
+    return duplicate(isReadOnly());
+  }
+
+  public ByteBuffer asReadOnlyBuffer()
+  {
+    return duplicate(true);
+  }
+
+  public CharBuffer asCharBuffer()
+  {
+    return new CharViewBufferImpl(this, remaining() >> 1);
+  }
+
+  public ShortBuffer asShortBuffer()
+  {
+    return new ShortViewBufferImpl(this, remaining() >> 1);
+  }
+
+  public IntBuffer asIntBuffer()
+  {
+    return new IntViewBufferImpl(this, remaining() >> 2);
+  }
+
+  public LongBuffer asLongBuffer()
+  {
+    return new LongViewBufferImpl(this, remaining() >> 3);
+  }
+
+  public FloatBuffer asFloatBuffer()
+  {
+    return new FloatViewBufferImpl(this, remaining() >> 2);
+  }
+
+  public DoubleBuffer asDoubleBuffer()
+  {
+    return new DoubleViewBufferImpl(this, remaining() >> 3);
+  }
+
+  public char getChar()
+  {
+    return ByteBufferHelper.getChar(this, order());
+  }
+  
+  public ByteBuffer putChar(char value)
+  {
+    ByteBufferHelper.putChar(this, value, order());
+    return this;
+  }
+  
+  public char getChar(int index)
+  {
+    return ByteBufferHelper.getChar(this, index, order());
+  }
+  
+  public ByteBuffer putChar(int index, char value)
+  {
+    ByteBufferHelper.putChar(this, index, value, order());
+    return this;
+  }
+
+  public short getShort()
+  {
+    return ByteBufferHelper.getShort(this, order());
+  }
+  
+  public ByteBuffer putShort(short value)
+  {
+    ByteBufferHelper.putShort(this, value, order());
+    return this;
+  }
+  
+  public short getShort(int index)
+  {
+    return ByteBufferHelper.getShort(this, index, order());
+  }
+  
+  public ByteBuffer putShort(int index, short value)
+  {
+    ByteBufferHelper.putShort(this, index, value, order());
+    return this;
+  }
+
+  public int getInt()
+  {
+    return ByteBufferHelper.getInt(this, order());
+  }
+  
+  public ByteBuffer putInt(int value)
+  {
+    ByteBufferHelper.putInt(this, value, order());
+    return this;
+  }
+  
+  public int getInt(int index)
+  {
+    return ByteBufferHelper.getInt(this, index, order());
+  }
+  
+  public ByteBuffer putInt(int index, int value)
+  {
+    ByteBufferHelper.putInt(this, index, value, order());
+    return this;
+  }
+
+  public long getLong()
+  {
+    return ByteBufferHelper.getLong(this, order());
+  }
+  
+  public ByteBuffer putLong(long value)
+  {
+    ByteBufferHelper.putLong(this, value, order());
+    return this;
+  }
+  
+  public long getLong(int index)
+  {
+    return ByteBufferHelper.getLong(this, index, order());
+  }
+  
+  public ByteBuffer putLong(int index, long value)
+  {
+    ByteBufferHelper.putLong(this, index, value, order());
+    return this;
+  }
+
+  public float getFloat()
+  {
+    return ByteBufferHelper.getFloat(this, order());
+  }
+  
+  public ByteBuffer putFloat(float value)
+  {
+    ByteBufferHelper.putFloat(this, value, order());
+    return this;
+  }
+  
+  public float getFloat(int index)
+  {
+    return ByteBufferHelper.getFloat(this, index, order());
+  }
+
+  public ByteBuffer putFloat(int index, float value)
+  {
+    ByteBufferHelper.putFloat(this, index, value, order());
+    return this;
+  }
+
+  public double getDouble()
+  {
+    return ByteBufferHelper.getDouble(this, order());
+  }
+
+  public ByteBuffer putDouble(double value)
+  {
+    ByteBufferHelper.putDouble(this, value, order());
+    return this;
+  }
+  
+  public double getDouble(int index)
+  {
+    return ByteBufferHelper.getDouble(this, index, order());
+  }
+  
+  public ByteBuffer putDouble(int index, double value)
+  {
+    ByteBufferHelper.putDouble(this, index, value, order());
+    return this;
+  }
+
+  // NOTE: In libgcj these methods are implemented in natFileChannelXxx.cc,
+  // because they're small, and to put them next to FileChannelImpl::mapImpl.
+  native void unmapImpl();
+  native boolean isLoadedImpl();
+    // FIXME: Try to load all pages into memory.
+  native void loadImpl();
+
+  native void forceImpl();
+}

Added: llvm-gcc-4.2/trunk/libjava/java/nio/VMDirectByteBuffer.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/nio/VMDirectByteBuffer.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/nio/VMDirectByteBuffer.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/nio/VMDirectByteBuffer.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,53 @@
+/* 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.gcj.RawData;
+
+final class VMDirectByteBuffer
+{
+  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);
+}

Added: llvm-gcc-4.2/trunk/libjava/java/nio/channels/VMChannels.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/nio/channels/VMChannels.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/nio/channels/VMChannels.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/nio/channels/VMChannels.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,85 @@
+/* VMChannels.java --
+   Copyright (C) 2005, 2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package 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.
+  }
+
+  static native FileInputStream newInputStream(FileChannelImpl ch);
+
+  static native FileOutputStream newOutputStream(FileChannelImpl ch);
+
+  /**
+   * Constructs a stream that reads bytes from the given channel.
+   */
+  static InputStream newInputStream(ReadableByteChannel ch)
+  {
+    if (ch instanceof FileChannelImpl)
+      return newInputStream((FileChannelImpl) 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 newOutputStream((FileChannelImpl) ch);
+    return new ChannelOutputStream(ch);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/nio/channels/natVMChannels.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/nio/channels/natVMChannels.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/nio/channels/natVMChannels.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/nio/channels/natVMChannels.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,37 @@
+// natVMChannels.cc - Native part of VMChannels class.
+
+/* Copyright (C) 2004, 2006  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <gcj/cni.h>
+
+#include <java/nio/channels/VMChannels.h>
+#include <java/nio/channels/Channels.h>
+#include <java/io/FileInputStream.h>
+#include <java/io/FileOutputStream.h>
+#include <gnu/java/nio/channels/FileChannelImpl.h>
+
+using java::nio::channels::VMChannels;
+using java::io::FileInputStream;
+using java::io::FileOutputStream;
+using gnu::java::nio::channels::FileChannelImpl;
+
+FileInputStream*
+VMChannels::newInputStream(FileChannelImpl* ch)
+{
+  // Needs to be native to bypass Java access protection.
+  return new FileInputStream (ch);
+}
+
+FileOutputStream*
+VMChannels::newOutputStream(FileChannelImpl* ch)
+{
+  // Needs to be native to bypass Java access protection.
+  return new FileOutputStream (ch);
+}

Added: llvm-gcc-4.2/trunk/libjava/java/nio/charset/Charset.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/nio/charset/Charset.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/nio/charset/Charset.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/nio/charset/Charset.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,412 @@
+/* Charset.java -- 
+   Copyright (C) 2002, 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.nio.charset;
+
+import gnu.classpath.ServiceFactory;
+import gnu.classpath.SystemProperties;
+import gnu.java.nio.charset.Provider;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.spi.CharsetProvider;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Locale;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+/**
+ * @author Jesse Rosenstock
+ * @since 1.4
+ */
+public abstract class Charset implements Comparable
+{
+  private CharsetEncoder cachedEncoder;
+  private CharsetDecoder cachedDecoder;
+ 
+  /**
+   * Charset providers.
+   */
+  private static CharsetProvider[] providers;
+  
+  private final String canonicalName;
+  private final String[] aliases;
+  
+  protected Charset (String canonicalName, String[] aliases)
+  {
+    checkName (canonicalName);
+    if (aliases != null)
+      {
+        int n = aliases.length;
+        for (int i = 0; i < n; ++i)
+            checkName (aliases[i]);
+      }
+
+    cachedEncoder = null;
+    cachedDecoder = null;
+    this.canonicalName = canonicalName;
+    this.aliases = aliases;
+  }
+
+  /**
+   * @throws IllegalCharsetNameException  if the name is illegal
+   */
+  private static void checkName (String name)
+  {
+    int n = name.length ();
+
+    if (n == 0)
+      throw new IllegalCharsetNameException (name);
+
+    char ch = name.charAt (0);
+    if (!(('A' <= ch && ch <= 'Z')
+          || ('a' <= ch && ch <= 'z')
+          || ('0' <= ch && ch <= '9')))
+      throw new IllegalCharsetNameException (name);
+
+    for (int i = 1; i < n; ++i)
+      {
+        ch = name.charAt (i);
+        if (!(('A' <= ch && ch <= 'Z')
+              || ('a' <= ch && ch <= 'z')
+              || ('0' <= ch && ch <= '9')
+              || ch == '-' || ch == '.' || ch == ':' || ch == '_'))
+          throw new IllegalCharsetNameException (name);
+      }
+  }
+
+  /**
+   * Returns the system default charset.
+   *
+   * This may be set by the user or VM with the file.encoding
+   * property.
+   *
+   * @since 1.5
+   */
+  public static Charset defaultCharset()
+  {
+    String encoding;
+    
+    try 
+      {
+	encoding = SystemProperties.getProperty("file.encoding");
+      }
+    catch(SecurityException e)
+      {
+	// Use fallback.
+	encoding = "ISO-8859-1";
+      }
+    catch(IllegalArgumentException e)
+      {
+	// Use fallback.
+	encoding = "ISO-8859-1";
+      }
+
+    try
+      {
+	return forName(encoding);
+      }
+    catch(UnsupportedCharsetException e)
+      {
+	// Ignore.
+      }
+    catch(IllegalCharsetNameException e)
+      {
+	// Ignore.
+      }
+    catch(IllegalArgumentException e)
+      {
+	// Ignore.
+      }
+    
+    throw new IllegalStateException("Can't get default charset!");
+  }
+
+  public static boolean isSupported (String charsetName)
+  {
+    return charsetForName (charsetName) != null;
+  }
+
+  /**
+   * Returns the Charset instance for the charset of the given name.
+   * 
+   * @param charsetName
+   * @return
+   * @throws UnsupportedCharsetException if this VM does not support
+   * the charset of the given name.
+   * @throws IllegalCharsetNameException if the given charset name is
+   * legal.
+   * @throws IllegalArgumentException if <code>charsetName</code> is null.
+   */
+  public static Charset forName (String charsetName)
+  {
+    // Throws IllegalArgumentException as the JDK does.
+    if(charsetName == null)
+        throw new IllegalArgumentException("Charset name must not be null.");
+    
+    Charset cs = charsetForName (charsetName);
+    if (cs == null)
+      throw new UnsupportedCharsetException (charsetName);
+    return cs;
+  }
+
+  /**
+   * Retrieves a charset for the given charset name.
+   *
+   * @return A charset object for the charset with the specified name, or
+   * <code>null</code> if no such charset exists.
+   *
+   * @throws IllegalCharsetNameException  if the name is illegal
+   */
+  private static Charset charsetForName(String charsetName)
+  {
+    checkName (charsetName);
+    // Try the default provider first
+    // (so we don't need to load external providers unless really necessary)
+    // if it is an exotic charset try loading the external providers.
+    Charset cs = provider().charsetForName(charsetName);
+    if (cs == null)
+      {
+	CharsetProvider[] providers = providers2();
+	for (int i = 0; i < providers.length; i++)
+	  {
+	    cs = providers[i].charsetForName(charsetName);
+	    if (cs != null)
+	      break;
+	  }
+      }
+    return cs;
+  }
+
+  public static SortedMap availableCharsets()
+  {
+    TreeMap charsets = new TreeMap(String.CASE_INSENSITIVE_ORDER);
+    for (Iterator i = provider().charsets(); i.hasNext(); )
+      {
+	Charset cs = (Charset) i.next();
+	charsets.put(cs.name(), cs);
+      }
+
+    CharsetProvider[] providers = providers2();
+    for (int j = 0; j < providers.length; j++)
+      {
+        for (Iterator i = providers[j].charsets(); i.hasNext(); )
+          {
+            Charset cs = (Charset) i.next();
+            charsets.put(cs.name(), cs);
+          }
+      }
+
+    return Collections.unmodifiableSortedMap(charsets);
+  }
+
+  private static CharsetProvider provider()
+  {
+    try
+      {
+	String s = System.getProperty("charset.provider");
+	if (s != null)
+	  {
+	    CharsetProvider p =
+	      (CharsetProvider) ((Class.forName(s)).newInstance());
+	    return p;
+	  }
+      }
+    catch (Exception e)
+      {
+	// Ignore.
+      }
+    
+    return Provider.provider();
+  }
+
+  /**
+   * We need to support multiple providers, reading them from
+   * java.nio.charset.spi.CharsetProvider in the resource directory
+   * META-INF/services. This returns the "extra" charset providers.
+   */
+  private static CharsetProvider[] providers2()
+  {
+    if (providers == null)
+      {
+        try
+          {
+            Iterator i = ServiceFactory.lookupProviders(CharsetProvider.class);
+            LinkedHashSet set = new LinkedHashSet();
+            while (i.hasNext())
+              set.add(i.next());
+
+            providers = new CharsetProvider[set.size()];
+            set.toArray(providers);
+          }
+        catch (Exception e)
+          {
+            throw new RuntimeException(e);
+          }
+      }
+    return providers;
+  }
+
+  public final String name ()
+  {
+    return canonicalName;
+  }
+
+  public final Set aliases ()
+  {
+    if (aliases == null)
+      return Collections.EMPTY_SET;
+
+    // should we cache the aliasSet instead?
+    int n = aliases.length;
+    HashSet aliasSet = new HashSet (n);
+    for (int i = 0; i < n; ++i)
+        aliasSet.add (aliases[i]);
+    return Collections.unmodifiableSet (aliasSet);
+  }
+
+  public String displayName ()
+  {
+    return canonicalName;
+  }
+
+  public String displayName (Locale locale)
+  {
+    return canonicalName;
+  }
+
+  public final boolean isRegistered ()
+  {
+    return (!canonicalName.startsWith ("x-")
+            && !canonicalName.startsWith ("X-"));
+  }
+
+  public abstract boolean contains (Charset cs);
+
+  public abstract CharsetDecoder newDecoder ();
+
+  public abstract CharsetEncoder newEncoder ();
+
+  public boolean canEncode ()
+  {
+    return true;
+  }
+
+  // NB: This implementation serializes different threads calling
+  // Charset.encode(), a potential performance problem.  It might
+  // be better to remove the cache, or use ThreadLocal to cache on
+  // a per-thread basis.
+  public final synchronized ByteBuffer encode (CharBuffer cb)
+  {
+    try
+      {
+	if (cachedEncoder == null)
+	  {
+	    cachedEncoder = newEncoder ()
+	      .onMalformedInput (CodingErrorAction.REPLACE)
+	      .onUnmappableCharacter (CodingErrorAction.REPLACE);
+	  } else
+	  cachedEncoder.reset();
+	return cachedEncoder.encode (cb);
+      }
+    catch (CharacterCodingException e)
+      {
+        throw new AssertionError (e);
+      }
+  }
+  
+  public final ByteBuffer encode (String str)
+  {
+    return encode (CharBuffer.wrap (str));
+  }
+
+  // NB: This implementation serializes different threads calling
+  // Charset.decode(), a potential performance problem.  It might
+  // be better to remove the cache, or use ThreadLocal to cache on
+  // a per-thread basis.
+  public final synchronized CharBuffer decode (ByteBuffer bb)
+  {
+    try
+      {
+	if (cachedDecoder == null)
+	  {
+	    cachedDecoder = newDecoder ()
+	      .onMalformedInput (CodingErrorAction.REPLACE)
+	      .onUnmappableCharacter (CodingErrorAction.REPLACE);
+	  } else
+	  cachedDecoder.reset();
+
+	return cachedDecoder.decode (bb);
+      }
+    catch (CharacterCodingException e)
+      {
+        throw new AssertionError (e);
+      }
+  }
+
+  public final int compareTo (Object ob)
+  {
+    return canonicalName.compareToIgnoreCase (((Charset) ob).canonicalName);
+  }
+
+  public final int hashCode ()
+  {
+    return canonicalName.hashCode ();
+  }
+
+  public final boolean equals (Object ob)
+  {
+    if (ob instanceof Charset)
+      return canonicalName.equalsIgnoreCase (((Charset) ob).canonicalName);
+    else
+      return false;
+  }
+
+  public final String toString ()
+  {
+    return canonicalName;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/nio/charset/spi/CharsetProvider.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/nio/charset/spi/CharsetProvider.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/nio/charset/spi/CharsetProvider.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/nio/charset/spi/CharsetProvider.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,96 @@
+/* CharsetProvider.java -- charset service provider interface
+   Copyright (C) 2002, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.nio.charset.spi;
+
+import java.nio.charset.Charset;
+import java.util.Iterator;
+
+
+/**
+ * This class allows an implementor to provide additional character sets. The
+ * subclass must have a nullary constructor, and be attached to charset
+ * implementation classes. These extensions are loaded via the context class
+ * loader. To provide the charset extension, all files named
+ * <code>META-INF/services/java.nio.charset.spi.CharsetProvider</code> are
+ * read from the classpath. Each one should be a UTF-8 encoded list of
+ * fully-qualified names of concrete subclasses of this class; whitespace is
+ * ignored, and '#' starts comments. Duplicates are ignored. The
+ * implementations must be accessible to the classloader that requests them.
+ *
+ * @author Eric Blake (ebb9 at email.byu.edu)
+ * @see Charset
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public abstract class CharsetProvider
+{
+  /**
+   * Initialize a new charset provider. This performs a security check on
+   * RuntimePermission("charsetProvider").
+   *
+   * @throws SecurityException if building a new set is not allowed
+   */
+  protected CharsetProvider()
+  {
+    // We only do the security check for custom providers, not for the
+    // built in ones.
+    SecurityManager s = System.getSecurityManager();
+    if (s != null &&
+        ! (this instanceof gnu.java.nio.charset.Provider))
+	// GCJ LOCAL - We have the iconv provider in standard.omit
+        // || this instanceof gnu.java.nio.charset.iconv.IconvProvider))
+      s.checkPermission(new RuntimePermission("charsetProvider"));
+  }
+
+  /**
+   * Returns an iterator over the charsets defined by this provider.
+   *
+   * @return the iterator
+   * @see Charset#availableCharsets()
+   */
+  public abstract Iterator charsets();
+
+  /**
+   * Returns the named charset, by canonical name or alias.
+   *
+   * @param name the name of the character
+   *
+   * @return the charset, or null if not supported
+   */
+  public abstract Charset charsetForName(String name);
+} // class CharsetProvider

Added: llvm-gcc-4.2/trunk/libjava/java/nio/natDirectByteBufferImpl.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/nio/natDirectByteBufferImpl.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/nio/natDirectByteBufferImpl.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/nio/natDirectByteBufferImpl.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,72 @@
+// natDirectByteBufferImpl.cc
+
+/* Copyright (C) 2003, 2004  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <stdlib.h>
+
+#include <gnu/gcj/RawData.h>
+#include <java/nio/VMDirectByteBuffer.h>
+
+using gnu::gcj::RawData;
+
+RawData*
+java::nio::VMDirectByteBuffer::allocate (jint capacity)
+{
+  return reinterpret_cast<gnu::gcj::RawData*> (::malloc (capacity));
+}
+
+void
+java::nio::VMDirectByteBuffer::free (gnu::gcj::RawData* address)
+{
+  ::free (reinterpret_cast<void*> (address));
+}
+
+jbyte
+java::nio::VMDirectByteBuffer::get (RawData* address, jint index)
+{
+  jbyte* pointer = reinterpret_cast<jbyte*> (address) + index;
+  return *pointer;
+}
+
+void
+java::nio::VMDirectByteBuffer::get (RawData* address, jint index,
+				    jbyteArray dst, jint offset, jint length)
+{
+  jbyte* src = reinterpret_cast<jbyte*> (address) + index;
+  memcpy (elements (dst) + offset, src, length);
+}
+
+void
+java::nio::VMDirectByteBuffer::put (gnu::gcj::RawData* address,
+				    jint index, jbyte value)
+{
+  jbyte* pointer = reinterpret_cast<jbyte*> (address) + index;
+  *pointer = value;
+}
+
+RawData*
+java::nio::VMDirectByteBuffer::adjustAddress (RawData* address, jint offset)
+{
+  jbyte* start = reinterpret_cast<jbyte*> (address) + offset;
+  return reinterpret_cast<RawData*>(start);
+}
+
+void
+java::nio::VMDirectByteBuffer::shiftDown (RawData* address, jint dst_offset,
+					  jint src_offset, jint count)
+{
+  jbyte* dst = reinterpret_cast<jbyte*> (address) + dst_offset;
+  jbyte* src = reinterpret_cast<jbyte*> (address) + src_offset;
+  ::memmove(dst, src, count);
+}

Added: llvm-gcc-4.2/trunk/libjava/java/security/Security.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/security/Security.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/security/Security.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/security/Security.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,714 @@
+/* Security.java --- Java base security class implementation
+   Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.security;
+
+import gnu.classpath.SystemProperties;
+
+import gnu.classpath.Configuration;
+// GCJ LOCAL - We don't have VMStackWalker yet.
+// import gnu.classpath.VMStackWalker;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+
+/**
+ * This class centralizes all security properties and common security methods.
+ * One of its primary uses is to manage security providers.
+ *
+ * @author Mark Benvenuto (ivymccough at worldnet.att.net)
+ */
+public final class Security
+{
+  private static final String ALG_ALIAS = "Alg.Alias.";
+
+  private static Vector providers = new Vector();
+  private static Properties secprops = new Properties();
+  
+  static
+    {
+      String base = SystemProperties.getProperty("gnu.classpath.home.url");
+      String vendor = SystemProperties.getProperty("gnu.classpath.vm.shortname");
+
+      // Try VM specific security file
+      boolean loaded = loadProviders (base, vendor);
+    
+      // Append classpath standard provider if possible
+      if (!loadProviders (base, "classpath")
+	  && !loaded
+	  && providers.size() == 0)
+	  {
+	      if (Configuration.DEBUG)
+		  {
+		      /* No providers found and both security files failed to
+		       * load properly. Give a warning in case of DEBUG is
+		       * enabled. Could be done with java.util.logging later.
+		       */
+		      System.err.println
+			  ("WARNING: could not properly read security provider files:");
+		      System.err.println
+			  ("         " + base + "/security/" + vendor
+			   + ".security");
+		      System.err.println
+			  ("         " + base + "/security/" + "classpath"
+			   + ".security");
+		      System.err.println
+			  ("         Falling back to standard GNU security provider");
+		  }
+              // Note that this matches our classpath.security file.
+	      providers.addElement (new gnu.java.security.provider.Gnu());
+	      providers.addElement(new gnu.javax.crypto.jce.GnuCrypto());
+              providers.addElement(new gnu.javax.crypto.jce.GnuSasl());
+              providers.addElement(new gnu.javax.net.ssl.provider.Jessie());
+              providers.addElement(new gnu.javax.security.auth.callback.GnuCallbacks());
+	  }
+    }
+  // This class can't be instantiated.
+  private Security()
+  {
+  }
+
+  /**
+   * Tries to load the vender specific security providers from the given base
+   * URL. Returns true if the resource could be read and completely parsed
+   * successfully, false otherwise.
+   */
+  private static boolean loadProviders(String baseUrl, String vendor)
+  {
+    if (baseUrl == null || vendor == null)
+      return false;
+
+    boolean result = true;
+    String secfilestr = baseUrl + "/security/" + vendor + ".security";
+    try
+      {
+	InputStream fin = new URL(secfilestr).openStream();
+	secprops.load(fin);
+
+	int i = 1;
+	String name;
+	while ((name = secprops.getProperty("security.provider." + i)) != null)
+	  {
+	    Exception exception = null;
+	    try
+	      {
+            ClassLoader sys = ClassLoader.getSystemClassLoader();
+		providers.addElement(Class.forName(name, true, sys).newInstance());
+	      }
+	    catch (ClassNotFoundException x)
+	      {
+	        exception = x;
+	      }
+	    catch (InstantiationException x)
+	      {
+	        exception = x;
+	      }
+	    catch (IllegalAccessException x)
+	      {
+	        exception = x;
+	      }
+
+	    if (exception != null)
+	      {
+		System.err.println ("WARNING: Error loading security provider "
+				    + name + ": " + exception);
+		result = false;
+	      }
+	    i++;
+	  }
+      }
+    catch (IOException ignored)
+      {
+	result = false;
+      }
+
+    return result;
+  }
+
+  /**
+   * Returns the value associated to a designated property name for a given
+   * algorithm.
+   * 
+   * @param algName
+   *          the algorithm name.
+   * @param propName
+   *          the name of the property to return.
+   * @return the value of the specified property or <code>null</code> if none
+   *         found.
+   * @deprecated Use the provider-based and algorithm-independent
+   *             {@link AlgorithmParameters} and {@link KeyFactory} engine
+   *             classes instead.
+   */
+  public static String getAlgorithmProperty(String algName, String propName)
+  {
+    if (algName == null || propName == null)
+      return null;
+
+    String property = String.valueOf(propName) + "." + String.valueOf(algName);
+    Provider p;
+    for (Iterator i = providers.iterator(); i.hasNext(); )
+      {
+        p = (Provider) i.next();
+        for (Iterator j = p.keySet().iterator(); j.hasNext(); )
+          {
+            String key = (String) j.next();
+            if (key.equalsIgnoreCase(property))
+              return p.getProperty(key);
+          }
+      }
+    return null;
+  }
+
+  /**
+   * Inserts a new designated {@link Provider} at a designated (1-based)
+   * position in the current list of installed {@link Provider}s,
+   * 
+   * @param provider
+   *          the new {@link Provider} to add.
+   * @param position
+   *          the position (starting from 1) of where to install
+   *          <code>provider</code>.
+   * @return the actual position, in the list of installed Providers. Returns
+   *         <code>-1</code> if <code>provider</code> was laready in the
+   *         list. The actual position may be different than the desired
+   *         <code>position</code>.
+   * @throws SecurityException
+   *           if a {@link SecurityManager} is installed and it disallows this
+   *           operation.
+   * @see #getProvider(String)
+   * @see #removeProvider(String)
+   * @see SecurityPermission
+   */
+  public static int insertProviderAt(Provider provider, int position)
+  {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      sm.checkSecurityAccess("insertProvider." + provider.getName());
+
+    position--;
+    int max = providers.size ();
+    for (int i = 0; i < max; i++)
+      {
+	if (((Provider) providers.elementAt(i)).getName().equals(provider.getName()))
+	  return -1;
+      }
+
+    if (position < 0)
+      position = 0;
+    if (position > max)
+      position = max;
+
+    providers.insertElementAt(provider, position);
+
+    return position + 1;
+  }
+
+  /**
+   * Appends the designated new {@link Provider} to the current list of
+   * installed {@link Provider}s.
+   * 
+   * @param provider
+   *          the new {@link Provider} to append.
+   * @return the position (starting from 1) of <code>provider</code> in the
+   *         current list of {@link Provider}s, or <code>-1</code> if
+   *         <code>provider</code> was already there.
+   * @throws SecurityException
+   *           if a {@link SecurityManager} is installed and it disallows this
+   *           operation.
+   * @see #getProvider(String)
+   * @see #removeProvider(String)
+   * @see SecurityPermission
+   */
+  public static int addProvider(Provider provider)
+  {
+    return insertProviderAt (provider, providers.size () + 1);
+  }
+
+  /**
+   * Removes an already installed {@link Provider}, given its name, from the
+   * current list of installed {@link Provider}s.
+   * 
+   * @param name
+   *          the name of an already installed {@link Provider} to remove.
+   * @throws SecurityException
+   *           if a {@link SecurityManager} is installed and it disallows this
+   *           operation.
+   * @see #getProvider(String)
+   * @see #addProvider(Provider)
+   */
+  public static void removeProvider(String name)
+  {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      sm.checkSecurityAccess("removeProvider." + name);
+
+    int max = providers.size ();
+    for (int i = 0; i < max; i++)
+      {
+	if (((Provider) providers.elementAt(i)).getName().equals(name))
+	  {
+	    providers.remove(i);
+	    break;
+	  }
+      }
+  }
+
+  /**
+   * Returns the current list of installed {@link Provider}s as an array
+   * ordered according to their installation preference order.
+   * 
+   * @return an array of all the installed providers.
+   */
+  public static Provider[] getProviders()
+  {
+    Provider[] array = new Provider[providers.size ()];
+    providers.copyInto (array);
+    return array;
+  }
+
+  /**
+   * Returns an already installed {@link Provider} given its name.
+   * 
+   * @param name
+   *          the name of an already installed {@link Provider}.
+   * @return the {@link Provider} known by <code>name</code>. Returns
+   *         <code>null</code> if the current list of {@link Provider}s does
+   *         not include one named <code>name</code>.
+   * @see #removeProvider(String)
+   * @see #addProvider(Provider)
+   */
+  public static Provider getProvider(String name)
+  {
+    if (name == null)
+      return null;
+    else
+      {
+        name = name.trim();
+        if (name.length() == 0)
+          return null;
+      }
+    Provider p;
+    int max = providers.size ();
+    for (int i = 0; i < max; i++)
+      {
+	p = (Provider) providers.elementAt(i);
+	if (p.getName().equals(name))
+	  return p;
+      }
+    return null;
+  }
+
+  /**
+   * Returns the value associated with a Security propery.
+   * 
+   * @param key
+   *          the key of the property to fetch.
+   * @return the value of the Security property associated with
+   *         <code>key</code>. Returns <code>null</code> if no such property
+   *         was found.
+   * @throws SecurityException
+   *           if a {@link SecurityManager} is installed and it disallows this
+   *           operation.
+   * @see #setProperty(String, String)
+   * @see SecurityPermission
+   */
+  public static String getProperty(String key)
+  {
+    // GCJ LOCAL - We don't have VMStackWalker yet.
+    // XXX To prevent infinite recursion when the SecurityManager calls us,
+    // don't do a security check if the caller is trusted (by virtue of having
+    // been loaded by the bootstrap class loader).
+    SecurityManager sm = System.getSecurityManager();
+    // if (sm != null && VMStackWalker.getCallingClassLoader() != null)
+    if (sm != null)
+      sm.checkSecurityAccess("getProperty." + key);
+
+    return secprops.getProperty(key);
+  }
+
+  /**
+   * Sets or changes a designated Security property to a designated value.
+   * 
+   * @param key
+   *          the name of the property to set.
+   * @param datum
+   *          the new value of the property.
+   * @throws SecurityException
+   *           if a {@link SecurityManager} is installed and it disallows this
+   *           operation.
+   * @see #getProperty(String)
+   * @see SecurityPermission
+   */
+  public static void setProperty(String key, String datum)
+  {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      sm.checkSecurityAccess("setProperty." + key);
+
+    if (datum == null)
+      secprops.remove(key);
+    else
+      secprops.put(key, datum);
+  }
+
+  /**
+   * For a given <i>service</i> (e.g. Signature, MessageDigest, etc...) this
+   * method returns the {@link Set} of all available algorithm names (instances
+   * of {@link String}, from all currently installed {@link Provider}s.
+   * 
+   * @param serviceName
+   *          the case-insensitive name of a service (e.g. Signature,
+   *          MessageDigest, etc).
+   * @return a {@link Set} of {@link String}s containing the names of all
+   *         algorithm names provided by all of the currently installed
+   *         {@link Provider}s.
+   * @since 1.4
+   */
+  public static Set getAlgorithms(String serviceName)
+  {
+    HashSet result = new HashSet();
+    if (serviceName == null || serviceName.length() == 0)
+      return result;
+
+    serviceName = serviceName.trim();
+    if (serviceName.length() == 0)
+      return result;
+
+    serviceName = serviceName.toUpperCase()+".";
+    Provider[] providers = getProviders();
+    int ndx;
+    for (int i = 0; i < providers.length; i++)
+      for (Enumeration e = providers[i].propertyNames(); e.hasMoreElements(); )
+        {
+          String service = ((String) e.nextElement()).trim();
+          if (service.toUpperCase().startsWith(serviceName))
+            {
+              service = service.substring(serviceName.length()).trim();
+              ndx = service.indexOf(' '); // get rid of attributes
+              if (ndx != -1)
+                service = service.substring(0, ndx);
+              result.add(service);
+            }
+        }
+    return Collections.unmodifiableSet(result);
+  }
+
+  /**
+   * Returns an array of currently installed {@link Provider}s, ordered
+   * according to their installation preference order, which satisfy a given
+   * <i>selection</i> criterion.
+   * 
+   * <p>This implementation recognizes a <i>selection</i> criterion written in
+   * one of two following forms:</p>
+   * 
+   * <ul>
+   *   <li><crypto_service>.<algorithm_or_type>: Where
+   *   <i>crypto_service</i> is a case-insensitive string, similar to what has
+   *   been described in the {@link #getAlgorithms(String)} method, and
+   *   <i>algorithm_or_type</i> is a known case-insensitive name of an
+   *   Algorithm, or one of its aliases.
+   *   
+   *   <p>For example, "CertificateFactory.X.509" would return all the installed
+   *   {@link Provider}s which provide a <i>CertificateFactory</i>
+   *   implementation of <i>X.509</i>.</p></li>
+   *   
+   *   <li><crypto_service>.<algorithm_or_type> <attribute_name>:<value>:
+   *   Where <i>crypto_service</i> is a case-insensitive string, similar to what
+   *   has been described in the {@link #getAlgorithms(String)} method,
+   *   <i>algorithm_or_type</i> is a case-insensitive known name of an Algorithm
+   *   or one of its aliases, <i>attribute_name</i> is a case-insensitive
+   *   property name with no whitespace characters, and no dots, in-between, and
+   *   <i>value</i> is a {@link String} with no whitespace characters in-between.
+   *   
+   *   <p>For example, "Signature.Sha1WithDSS KeySize:1024" would return all the
+   *   installed {@link Provider}s which declared their ability to provide
+   *   <i>Signature</i> services, using the <i>Sha1WithDSS</i> algorithm with
+   *   key sizes of <i>1024</i>.</p></li>
+   * </ul>
+   * 
+   * @param filter
+   *          the <i>selection</i> criterion for selecting among the installed
+   *          {@link Provider}s.
+   * @return all the installed {@link Provider}s which satisfy the <i>selection</i>
+   *         criterion. Returns <code>null</code> if no installed
+   *         {@link Provider}s were found which satisfy the <i>selection</i>
+   *         criterion. Returns ALL installed {@link Provider}s if
+   *         <code>filter</code> is <code>null</code> or is an empty string.
+   * @throws InvalidParameterException
+   *           if an exception occurs while parsing the <code>filter</code>.
+   * @see #getProviders(Map)
+   */
+  public static Provider[] getProviders(String filter)
+  {
+    if (providers == null || providers.isEmpty())
+      return null;
+
+    if (filter == null || filter.length() == 0)
+      return getProviders();
+
+    HashMap map = new HashMap(1);
+    int i = filter.indexOf(':');
+    if (i == -1) // <service>.<algorithm>
+      map.put(filter, "");
+    else // <service>.<algorithm> <attribute>:<value>
+      map.put(filter.substring(0, i), filter.substring(i+1));
+
+    return getProviders(map);
+  }
+
+  /**
+   * Returns an array of currently installed {@link Provider}s which satisfy a
+   * set of <i>selection</i> criteria.
+   * 
+   * <p>The <i>selection</i> criteria are defined in a {@link Map} where each
+   * element specifies a <i>selection</i> querry. The <i>Keys</i> in this
+   * {@link Map} must be in one of the two following forms:</p>
+   * 
+   * <ul>
+   *   <li><crypto_service>.<algorithm_or_type>: Where
+   *   <i>crypto_service</i> is a case-insensitive string, similar to what has
+   *   been described in the {@link #getAlgorithms(String)} method, and
+   *   <i>algorithm_or_type</i> is a case-insensitive known name of an
+   *   Algorithm, or one of its aliases. The <i>value</i> of the entry in the
+   *   {@link Map} for such a <i>Key</i> MUST be the empty string.
+   *   {@link Provider}s which provide an implementation for the designated
+   *   <i>service algorithm</i> are included in the result.</li>
+   *   
+   *   <li><crypto_service>.<algorithm_or_type> <attribute_name>:
+   *   Where <i>crypto_service</i> is a case-insensitive string, similar to what
+   *   has been described in the {@link #getAlgorithms(String)} method,
+   *   <i>algorithm_or_type</i> is a case-insensitive known name of an Algorithm
+   *   or one of its aliases, and <i>attribute_name</i> is a case-insensitive
+   *   property name with no whitespace characters, and no dots, in-between. The
+   *   <i>value</i> of the entry in this {@link Map} for such a <i>Key</i> MUST
+   *   NOT be <code>null</code> or an empty string. {@link Provider}s which
+   *   declare the designated <i>attribute_name</i> and <i>value</i> for the
+   *   designated <i>service algorithm</i> are included in the result.</li>
+   * </ul>
+   * 
+   * @param filter
+   *          a {@link Map} of <i>selection querries</i>.
+   * @return all currently installed {@link Provider}s which satisfy ALL the
+   *         <i>selection</i> criteria defined in <code>filter</code>.
+   *         Returns ALL installed {@link Provider}s if <code>filter</code>
+   *         is <code>null</code> or empty.
+   * @throws InvalidParameterException
+   *           if an exception is encountered while parsing the syntax of the
+   *           {@link Map}'s <i>keys</i>.
+   * @see #getProviders(String)
+   */
+  public static Provider[] getProviders(Map filter)
+  {
+    if (providers == null || providers.isEmpty())
+      return null;
+
+    if (filter == null)
+      return getProviders();
+
+    Set querries = filter.keySet();
+    if (querries == null || querries.isEmpty())
+      return getProviders();
+
+    LinkedHashSet result = new LinkedHashSet(providers); // assume all
+    int dot, ws;
+    String querry, service, algorithm, attribute, value;
+    LinkedHashSet serviceProviders = new LinkedHashSet(); // preserve insertion order
+    for (Iterator i = querries.iterator(); i.hasNext(); )
+      {
+        querry = (String) i.next();
+        if (querry == null) // all providers
+          continue;
+
+        querry = querry.trim();
+        if (querry.length() == 0) // all providers
+          continue;
+
+        dot = querry.indexOf('.');
+        if (dot == -1) // syntax error
+          throw new InvalidParameterException(
+              "missing dot in '" + String.valueOf(querry)+"'");
+
+        value = (String) filter.get(querry);
+        // deconstruct querry into [service, algorithm, attribute]
+        if (value == null || value.trim().length() == 0) // <service>.<algorithm>
+          {
+            value = null;
+            attribute = null;
+            service = querry.substring(0, dot).trim();
+            algorithm = querry.substring(dot+1).trim();
+          }
+        else // <service>.<algorithm> <attribute>
+          {
+            ws = querry.indexOf(' ');
+            if (ws == -1)
+              throw new InvalidParameterException(
+                  "value (" + String.valueOf(value) +
+                  ") is not empty, but querry (" + String.valueOf(querry) +
+                  ") is missing at least one space character");
+            value = value.trim();
+            attribute = querry.substring(ws+1).trim();
+            // was the dot in the attribute?
+            if (attribute.indexOf('.') != -1)
+              throw new InvalidParameterException(
+                  "attribute_name (" + String.valueOf(attribute) +
+                  ") in querry (" + String.valueOf(querry) + ") contains a dot");
+
+            querry = querry.substring(0, ws).trim();
+            service = querry.substring(0, dot).trim();
+            algorithm = querry.substring(dot+1).trim();
+          }
+
+        // service and algorithm must not be empty
+        if (service.length() == 0)
+          throw new InvalidParameterException(
+              "<crypto_service> in querry (" + String.valueOf(querry) +
+              ") is empty");
+
+        if (algorithm.length() == 0)
+          throw new InvalidParameterException(
+              "<algorithm_or_type> in querry (" + String.valueOf(querry) +
+              ") is empty");
+
+        selectProviders(service, algorithm, attribute, value, result, serviceProviders);
+        result.retainAll(serviceProviders); // eval next retaining found providers
+        if (result.isEmpty()) // no point continuing
+          break;
+      }
+
+    if (result.isEmpty())
+      return null;
+
+    return (Provider[]) result.toArray(new Provider[result.size()]);
+  }
+
+  private static void selectProviders(String svc, String algo, String attr,
+                                      String val, LinkedHashSet providerSet,
+                                      LinkedHashSet result)
+  {
+    result.clear(); // ensure we start with an empty result set
+    for (Iterator i = providerSet.iterator(); i.hasNext(); )
+      {
+        Provider p = (Provider) i.next();
+        if (provides(p, svc, algo, attr, val))
+          result.add(p);
+      }
+  }
+
+  private static boolean provides(Provider p, String svc, String algo,
+                                  String attr, String val)
+  {
+    Iterator it;
+    String serviceDotAlgorithm = null;
+    String key = null;
+    String realVal;
+    boolean found = false;
+    // if <svc>.<algo> <attr> is in the set then so is <svc>.<algo>
+    // but it may be stored under an alias <algo>. resolve
+    outer: for (int r = 0; r < 3; r++) // guard against circularity
+      {
+        serviceDotAlgorithm = (svc+"."+String.valueOf(algo)).trim();
+        for (it = p.keySet().iterator(); it.hasNext(); )
+          {
+            key = (String) it.next();
+            if (key.equalsIgnoreCase(serviceDotAlgorithm)) // eureka
+              {
+                found = true;
+                break outer;
+              }
+            // it may be there but as an alias
+            if (key.equalsIgnoreCase(ALG_ALIAS + serviceDotAlgorithm))
+              {
+                algo = p.getProperty(key);
+                continue outer;
+              }
+            // else continue inner
+          }
+      }
+
+    if (!found)
+      return false;
+
+    // found a candidate for the querry.  do we have an attr to match?
+    if (val == null) // <service>.<algorithm> querry
+      return true;
+
+    // <service>.<algorithm> <attribute>; find the key entry that match
+    String realAttr;
+    int limit = serviceDotAlgorithm.length() + 1;
+    for (it = p.keySet().iterator(); it.hasNext(); )
+      {
+        key = (String) it.next();
+        if (key.length() <= limit)
+          continue;
+
+        if (key.substring(0, limit).equalsIgnoreCase(serviceDotAlgorithm+" "))
+          {
+            realAttr = key.substring(limit).trim();
+            if (! realAttr.equalsIgnoreCase(attr))
+              continue;
+
+            // eveything matches so far.  do the value
+            realVal = p.getProperty(key);
+            if (realVal == null)
+              return false;
+
+            realVal = realVal.trim();
+            // is it a string value?
+            if (val.equalsIgnoreCase(realVal))
+              return true;
+
+            // assume value is a number. cehck for greater-than-or-equal
+            return (new Integer(val).intValue() >= new Integer(realVal).intValue());
+          }
+      }
+
+    return false;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/security/VMAccessControlState.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/security/VMAccessControlState.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/security/VMAccessControlState.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/security/VMAccessControlState.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,103 @@
+/* VMAccessControlState.java -- per-thread state for the access controller.
+   Copyright (C) 2006 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.LinkedList;
+
+class VMAccessControlState
+{
+  /**
+   * A list of {@link AccessControlContext} objects (which can be
+   * null) for each call to {@link AccessController#doPrivileged()} in
+   * the thread's call stack.
+   */
+  private LinkedList contexts = new LinkedList();
+
+  /**
+   * A flag indicating that we are within a call to {@link
+   * VMAccessController#getContext()}.
+   */
+  private boolean inGetContext = false;
+
+  /**
+   * Not directly instantiable: use getThreadState() instead.
+   */
+  private VMAccessControlState() {}
+
+  /**
+   * Return an object representing the access control state of this
+   * thread.
+   *
+   * @return The access control state of this thread, or
+   * <code>null</code> if the VM is not initialized to the point of
+   * being able to return this.
+   */
+  static native VMAccessControlState getThreadState();
+
+  /**
+   * Indicate whether this thread is within a call to {@link
+   * VMAccessController#getContext()}.
+   *
+   * @return <code>true</code> if this thread is within a call to
+   * {@link VMAccessController#getContext()}.
+   */
+  boolean isInGetContext()
+  {
+    return inGetContext;
+  }
+
+  /**
+   * Specify whether this thread is within a call to {@link
+   * VMAccessController#getContext()}.
+   */
+  void setInGetContext(boolean inGetContext)
+  {
+    this.inGetContext = inGetContext;
+  }
+  
+  /**
+   * Return a list of {@link AccessControlContext} objects (which can
+   * be null) for each call to {@link AccessController#doPrivileged()}
+   * in the thread's call stack.
+   *
+   * @return a list of {@link AccessControlContext} objects.
+   */
+  LinkedList getContexts()
+  {
+    return contexts;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/security/VMAccessController.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/security/VMAccessController.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/security/VMAccessController.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/security/VMAccessController.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,255 @@
+/* VMAccessController.java -- VM-specific access controller methods.
+   Copyright (C) 2004, 2005, 2006  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.
+  // -------------------------------------------------------------------------
+
+  /**
+   * And we return this all-permissive context to ensure that privileged
+   * methods called from getContext succeed.
+   */
+  private static final AccessControlContext DEFAULT_CONTEXT;
+  static
+  {
+    CodeSource source = new CodeSource(null, null);
+    Permissions permissions = new Permissions();
+    permissions.add(new AllPermission());
+    ProtectionDomain[] domain = new ProtectionDomain[] {
+      new ProtectionDomain(source, permissions)
+    };
+    DEFAULT_CONTEXT = new AccessControlContext(domain);
+  }
+
+  private static final boolean DEBUG = gnu.classpath.Configuration.DEBUG;
+  private static void debug(String msg)
+  {
+    System.err.print(">>> VMAccessController: ");
+    System.err.println(msg);
+  }
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  private VMAccessController() { }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Relate a class (which should be an instance of {@link PrivilegedAction}
+   * with an access control context. This method is used by {@link
+   * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}
+   * to set up the context that will be returned by {@link #getContext()}.
+   * This method relates the class to the current thread, so contexts
+   * pushed from one thread will not be available to another.
+   *
+   * @param acc The access control context.
+   */
+  static void pushContext (AccessControlContext acc)
+  {
+    // Can't really do anything while the VM is initializing.
+    VMAccessControlState state = VMAccessControlState.getThreadState();
+    if (state == null)
+      return;
+
+    if (DEBUG)
+      debug("pushing " + acc);
+
+    LinkedList stack = state.getContexts();
+    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()
+  {
+    // Can't really do anything while the VM is initializing.
+    VMAccessControlState state = VMAccessControlState.getThreadState();
+    if (state == null)
+      return;
+
+    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 = state.getContexts();
+    if (!stack.isEmpty())
+      {
+	stack.removeFirst();
+      }
+    else if (DEBUG)
+      {
+        debug("no stack during pop?????");
+      }
+  }
+
+  /**
+   * Examine the method stack of the currently running thread, and create
+   * an {@link AccessControlContext} filled in with the appropriate {@link
+   * ProtectionDomain} objects given this stack.
+   *
+   * @return The context.
+   */
+  static AccessControlContext getContext()
+  {
+    // If the VM is initializing return the all-permissive context
+    // so that any security checks succeed.
+    VMAccessControlState state = VMAccessControlState.getThreadState();
+    if (state == null)
+      return DEFAULT_CONTEXT;
+
+    // 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.
+    if (state.isInGetContext())
+      {
+        if (DEBUG)
+          debug("already in getContext");
+        return DEFAULT_CONTEXT;
+      }
+
+    state.setInGetContext(true);
+
+    Object[] stack = getStack();
+    Class[] classes = (Class[]) stack[0];
+    boolean privileged = ((Boolean) stack[1]).booleanValue();
+
+    if (DEBUG)
+      debug("got trace of length " + classes.length);
+
+    HashSet domains = new HashSet();
+    HashSet seenDomains = new HashSet();
+    AccessControlContext context = null;
+
+    // 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; i++)
+      {
+        Class clazz = classes[i];
+
+        if (DEBUG)
+          {
+            debug("checking " + clazz);
+            // subject to getClassLoader RuntimePermission
+            debug("loader = " + clazz.getClassLoader());
+          }
+
+        if (privileged && i == classes.length - 2)
+          {
+            // If there was a call to doPrivileged with a supplied context,
+            // return that context. If using JAAS doAs*, it should be 
+	    // a context with a SubjectDomainCombiner
+            LinkedList l = state.getContexts();
+            if (!l.isEmpty())
+              context = (AccessControlContext) l.getFirst();
+          }
+
+        // subject to getProtectionDomain RuntimePermission
+	ProtectionDomain domain = clazz.getProtectionDomain();
+
+        if (domain == null)
+          continue;
+        if (seenDomains.contains(domain))
+          continue;
+        seenDomains.add(domain);
+
+        // Create a static snapshot of this domain, which may change over time
+        // if the current policy changes.
+        domains.add(new ProtectionDomain(domain.getCodeSource(),
+                                         domain.getPermissions()));
+      }
+
+    if (DEBUG)
+      debug("created domains: " + domains);
+
+    ProtectionDomain[] result = (ProtectionDomain[])
+      domains.toArray(new ProtectionDomain[domains.size()]);
+
+    if (context != null)
+      {
+        DomainCombiner dc = context.getDomainCombiner ();
+        // If the supplied context had no explicit DomainCombiner, use
+        // our private version, which computes the intersection of the
+        // context's domains with the derived set.
+        if (dc == null)
+          context = new AccessControlContext
+            (IntersectingDomainCombiner.SINGLETON.combine
+             (result, context.getProtectionDomains ()));
+        // Use the supplied DomainCombiner. This should be secure,
+        // because only trusted code may create an
+        // AccessControlContext with a custom DomainCombiner.
+        else
+          context = new AccessControlContext (result, context, dc);
+      }
+    // No context was supplied. Return the derived one.
+    else
+      context = new AccessControlContext (result);
+
+    state.setInGetContext(false);
+    return context;
+  }
+
+  /**
+   * Returns a snapshot of the current call stack as a two-element
+   * array. The first element is an array of classes in the call
+   * stack, and the second element is a boolean value indicating
+   * whether the trace stopped early because a call to doPrivileged
+   * was encountered.  If this boolean value is true then the call to
+   * doPrivileged will be the second-last frame in the returned trace.
+   *
+   * @return A snapshot of the current call stack.
+   */
+  private static native Object[] getStack();
+}

Added: llvm-gcc-4.2/trunk/libjava/java/security/VMSecureRandom.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/security/VMSecureRandom.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/security/VMSecureRandom.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/security/VMSecureRandom.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,134 @@
+/* VMSecureRandom.java -- random seed generator.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package java.security;
+
+import gnu.classpath.SystemProperties;
+import gnu.java.security.action.GetSecurityPropertyAction;
+
+import java.net.URL;
+
+/**
+ * VM-specific methods for generating real (or almost real) random
+ * seeds. VM implementors should write a version of this class that
+ * reads random bytes from some system source.
+ *
+ * <p>The default implementation of this class runs eight threads that
+ * increment counters in a tight loop, and XORs each counter to
+ * produce one byte of seed data. This is not very efficient, and is
+ * not guaranteed to be random (the thread scheduler is probably
+ * deterministic, after all). If possible, VM implementors should
+ * reimplement this class so it obtains a random seed from a system
+ * facility, such as a system entropy gathering device or hardware
+ * random number generator.
+ */
+final class VMSecureRandom
+{
+
+  /**
+   * Generate a random seed. Implementations are free to generate
+   * fewer random bytes than are requested, and leave the remaining
+   * bytes of the destination buffer as zeros. Implementations SHOULD,
+   * however, make a best-effort attempt to satisfy the request.
+   *
+   * @param buffer The destination buffer.
+   * @param offset The offset in the buffer to start putting bytes.
+   * @param length The number of random bytes to generate.
+   */
+  static int generateSeed(byte[] buffer, int offset, int length)
+  {
+    if (length < 0)
+      throw new IllegalArgumentException("length must be nonnegative");
+    if (offset < 0 || offset + length > buffer.length)
+      throw new IndexOutOfBoundsException();
+
+    Spinner[] spinners = new Spinner[8];
+    int n = 0x1;
+    for (int i = 0; i < spinners.length; i++)
+      {
+        spinners[i] = new Spinner((byte) n);
+        Thread t = new Thread(spinners[i]);
+        t.start();
+        n <<= 1;
+      }
+
+    // Wait until at least one spinner has started.
+    while (!(spinners[0].running || spinners[1].running || spinners[2].running
+             || spinners[3].running || spinners[4].running || spinners[5].running
+             || spinners[6].running || spinners[7].running))
+      {
+        Thread.yield();
+      }
+
+    for (int i = offset; i < length; i++)
+      {
+        buffer[i] = (byte) (spinners[0].value ^ spinners[1].value ^ spinners[2].value
+                            ^ spinners[3].value ^ spinners[4].value ^ spinners[5].value
+                            ^ spinners[6].value ^ spinners[7].value);
+        Thread.yield();
+      }
+
+    for (int i = 0; i < spinners.length; i++)
+      spinners[i].stop();
+
+    return length;
+  }
+
+  static class Spinner implements Runnable
+  {
+    volatile byte value;
+    volatile boolean running;
+
+    Spinner(final byte initial)
+    {
+      value = initial;
+    }
+
+    public void run()
+    {
+      running = true;
+      while (running)
+        value++;
+    }
+
+    private void stop()
+    {
+      running = false;
+    }
+  }
+}
\ No newline at end of file

Added: llvm-gcc-4.2/trunk/libjava/java/security/natVMAccessControlState.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/security/natVMAccessControlState.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/security/natVMAccessControlState.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/security/natVMAccessControlState.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,32 @@
+// natVMAccessControlState.cc -- Native part of the VMAccessControlState class.
+
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/lang/Thread.h>
+#include <java/security/VMAccessControlState.h>
+
+java::security::VMAccessControlState *
+java::security::VMAccessControlState::getThreadState ()
+{
+  java::lang::Thread *thread = java::lang::Thread::currentThread ();
+  if (thread == NULL)
+    return NULL;
+
+  VMAccessControlState *state =
+    reinterpret_cast<VMAccessControlState *> (thread->accessControlState);
+  if (state == NULL)
+    thread->accessControlState = state = new VMAccessControlState ();
+
+  return state;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/security/natVMAccessController.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/security/natVMAccessController.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/security/natVMAccessController.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/security/natVMAccessController.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,23 @@
+// natVMAccessController.cc -- Native part of the VMAccessController class.
+
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-stack.h>
+
+#include <java/security/VMAccessController.h>
+
+jobjectArray
+java::security::VMAccessController::getStack ()
+{
+  return _Jv_StackTrace::GetAccessControlStack ();
+}

Added: llvm-gcc-4.2/trunk/libjava/java/text/Collator.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/text/Collator.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/text/Collator.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/text/Collator.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,395 @@
+/* Collator.java -- Perform locale dependent String comparisons.
+   Copyright (C) 1998, 1999, 2000, 2001, 2004, 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+ 
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.text;
+
+import java.util.Comparator;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * This class is the abstract superclass of classes which perform 
+ * locale dependent <code>String</code> comparisons.  A caller requests
+ * an instance of <code>Collator</code> for a particular locale using
+ * the <code>getInstance()</code> static method in this class.  That method
+ * will return a locale specific subclass of <code>Collator</code> which
+ * can be used to perform <code>String</code> comparisons for that locale.
+ * If a subclass of <code>Collator</code> cannot be located for a particular
+ * locale, a default instance for the current locale will be returned.  
+ *
+ * In addition to setting the correct locale, there are two additional
+ * settings that can be adjusted to affect <code>String</code> comparisons:
+ * strength and decomposition.  The strength value determines the level
+ * of signficance of character differences required for them to sort
+ * differently.  (For example, whether or not capital letters are considered
+ * different from lower case letters).  The decomposition value affects how
+ * variants of the same character are treated for sorting purposes.  (For
+ * example, whether or not an accent is signficant or not).  These settings
+ * are described in detail in the documentation for the methods and values
+ * that are related to them.
+ *
+ * @author Tom Tromey (tromey at cygnus.com)
+ * @author Aaron M. Renn (arenn at urbanophile.com)
+ * @date March 18, 1999
+ */
+/* Written using "Java Class Libraries", 2nd edition, plus online
+ * API docs for JDK 1.2 from http://www.javasoft.com.
+ * Status: Mostly complete, but parts stubbed out.  Look for FIXME.
+ */
+public abstract class Collator implements Comparator, Cloneable
+{
+  /**
+   * This constant is a strength value which indicates that only primary
+   * differences between characters will be considered signficant.  As an
+   * example, two completely different English letters such as 'a' and 'b'
+   * are considered to have a primary difference.
+   */
+  public static final int PRIMARY = 0;
+  
+  /**
+   * This constant is a strength value which indicates that only secondary
+   * or primary differences between characters will be considered
+   * significant.  An example of a secondary difference between characters
+   * are instances of the same letter with different accented forms.
+   */
+  public static final int SECONDARY = 1;
+  
+  /**
+   * This constant is a strength value which indicates that tertiary,
+   * secondary, and primary differences will be considered during sorting.
+   * An example of a tertiary difference is capitalization of a given letter.
+   * This is the default value for the strength setting.
+   */
+  public static final int TERTIARY = 2;
+  
+  /**
+   * This constant is a strength value which indicates that any difference
+   * at all between character values are considered significant.
+   */
+  public static final int IDENTICAL = 3;
+  
+  /**
+   * This constant indicates that accented characters won't be decomposed
+   * when performing comparisons.  This will yield the fastest results, but
+   * will only work correctly in call cases for languages which do not
+   * use accents such as English.
+   */
+  public static final int NO_DECOMPOSITION = 0;
+  
+  /**
+   * This constant indicates that only characters which are canonical variants
+   * in Unicode 2.0 will be decomposed prior to performing comparisons.  This
+   * will cause accented languages to be sorted correctly.  This is the
+   * default decomposition value.
+   */
+  public static final int CANONICAL_DECOMPOSITION = 1;
+  
+  /**
+   * This constant indicates that both canonical variants and compatibility
+   * variants in Unicode 2.0 will be decomposed prior to performing
+   * comparisons.  This is the slowest mode, but is required to get the
+   * correct sorting for certain languages with certain special formats.
+   */
+  public static final int FULL_DECOMPOSITION = 2;
+
+  /**
+   * This method initializes a new instance of <code>Collator</code> to have
+   * the default strength (TERTIARY) and decomposition 
+   * (CANONICAL_DECOMPOSITION) settings.  This constructor is protected and
+   * is for use by subclasses only.  Non-subclass callers should use the
+   * static <code>getInstance()</code> methods of this class to instantiate
+   * <code>Collation</code> objects for the desired locale.
+   */
+  protected Collator ()
+  {
+    strength = TERTIARY;
+    decmp = CANONICAL_DECOMPOSITION;
+  }
+
+  /**
+   * This method compares the two <code>String</code>'s and returns an
+   * integer indicating whether or not the first argument is less than,
+   * equal to, or greater than the second argument.  The comparison is
+   * performed according to the rules of the locale for this 
+   * <code>Collator</code> and the strength and decomposition rules in
+   * effect.
+   *
+   * @param source The first object to compare
+   * @param target The second object to compare
+   *
+   * @return A negative integer if str1 < str2, 0 if str1 == str2, or
+   * a positive integer if str1 > str2. 
+   */
+  public abstract int compare (String source, String target);
+
+  /**
+   * This method compares the two <code>Object</code>'s and returns an
+   * integer indicating whether or not the first argument is less than,
+   * equal to, or greater than the second argument.  These two objects
+   * must be <code>String</code>'s or an exception will be thrown.
+   *
+   * @param o1 The first object to compare
+   * @param o2 The second object to compare
+   *
+   * @return A negative integer if obj1 < obj2, 0 if obj1 == obj2, or
+   * a positive integer if obj1 > obj2. 
+   *
+   * @exception ClassCastException If the arguments are not instances
+   * of <code>String</code>. 
+   */
+  public int compare (Object o1, Object o2)
+  {
+    return compare ((String) o1, (String) o2);
+  }
+
+  /**
+   * This method tests the specified object for equality against this
+   * object.  This will be true if and only if the following conditions are
+   * met:
+   * <ul>
+   * <li>The specified object is not <code>null</code>.</li>
+   * <li>The specified object is an instance of <code>Collator</code>.</li>
+   * <li>The specified object has the same strength and decomposition
+   * settings as this object.</li>
+   * </ul>
+   *
+   * @param obj The <code>Object</code> to test for equality against
+   *            this object. 
+   *
+   * @return <code>true</code> if the specified object is equal to
+   * this one, <code>false</code> otherwise.
+   */
+  public boolean equals (Object obj)
+  {
+    if (! (obj instanceof Collator))
+      return false;
+    Collator c = (Collator) obj;
+    return decmp == c.decmp && strength == c.strength;
+  }
+
+  /**
+   * This method tests whether the specified <code>String</code>'s are equal
+   * according to the collation rules for the locale of this object and
+   * the current strength and decomposition settings.
+   *
+   * @param source The first <code>String</code> to compare
+   * @param target The second <code>String</code> to compare
+   *
+   * @return <code>true</code> if the two strings are equal,
+   * <code>false</code> otherwise. 
+   */
+  public boolean equals (String source, String target)
+  {
+    return compare (source, target) == 0;
+  }
+
+  /**
+   * This method returns a copy of this <code>Collator</code> object.
+   *
+   * @return A duplicate of this object.
+   */
+  public Object clone ()
+  {
+    try
+      {
+	return super.clone ();
+      }
+    catch (CloneNotSupportedException _)
+      {
+	return null;
+      }
+  }
+
+  /**
+   * This method returns an array of <code>Locale</code> objects which is
+   * the list of locales for which <code>Collator</code> objects exist.
+   *
+   * @return The list of locales for which <code>Collator</code>'s exist.
+   */
+  public static synchronized Locale[] getAvailableLocales ()
+  {
+    // FIXME
+    Locale[] l = new Locale[1];
+    l[0] = Locale.US;
+    return l;
+  }
+
+  /**
+   * This method transforms the specified <code>String</code> into a
+   * <code>CollationKey</code> for faster comparisons.  This is useful when
+   * comparisons against a string might be performed multiple times, such
+   * as during a sort operation.
+   *
+   * @param source The <code>String</code> to convert.
+   *
+   * @return A <code>CollationKey</code> for the specified <code>String</code>.
+   */
+  public abstract CollationKey getCollationKey (String source);
+
+  /**
+   * This method returns the current decomposition setting for this
+   * object.  This * will be one of NO_DECOMPOSITION,
+   * CANONICAL_DECOMPOSITION, or * FULL_DECOMPOSITION.  See the
+   * documentation for those constants for an * explanation of this
+   * setting.
+   *
+   * @return The current decomposition setting.
+   */
+  public synchronized int getDecomposition ()
+  {
+    return decmp;
+  }
+
+  /**
+   * This method returns an instance of <code>Collator</code> for the
+   * default locale.
+   *
+   * @return A <code>Collator</code> for the default locale.
+   */
+  public static Collator getInstance ()
+  {
+    return getInstance (Locale.getDefault());
+  }
+
+  /**
+   * This method returns an instance of <code>Collator</code> for the
+   * specified locale.  If no <code>Collator</code> exists for the desired
+   * locale, a <code>Collator</code> for the default locale will be returned.
+   *
+   * @param loc The desired localed to load a <code>Collator</code> for.
+   *
+   * @return A <code>Collator</code> for the requested locale
+   */
+  public static Collator getInstance (Locale loc)
+  {
+    ResourceBundle res;
+    String pattern;
+    try
+      {
+	res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
+				       loc, ClassLoader.getSystemClassLoader());
+	pattern = res.getString("collation_rules");
+      }
+    catch (MissingResourceException x)
+      {
+	pattern = "<0<1<2<3<4<5<6<7<8<9<A,a<b,B<c,C<d,D<e,E<f,F<g,G<h,H<i,I<j,J<k,K" +
+		"<l,L<m,M<n,N<o,O<p,P<q,Q<r,R<s,S<t,T<u,U<v,V<w,W<x,X<y,Y<z,Z";
+      }
+    try
+      {
+	return new RuleBasedCollator (pattern);
+      }
+    catch (ParseException x)
+      {
+	throw (InternalError)new InternalError().initCause(x);
+      }
+  }
+
+  /**
+   * This method returns the current strength setting for this object.  This
+   * will be one of PRIMARY, SECONDARY, TERTIARY, or IDENTICAL.  See the
+   * documentation for those constants for an explanation of this setting.
+   *
+   * @return The current strength setting.
+   */
+  public synchronized int getStrength ()
+  {
+    return strength;
+  }
+
+  /**
+   * This method returns a hash code value for this object.
+   *
+   * @return A hash value for this object.
+   */
+  public abstract int hashCode ();
+
+  /**
+   * This method sets the decomposition setting for this object to the
+   * specified value.  This must be one of NO_DECOMPOSITION,
+   * CANONICAL_DECOMPOSITION, or FULL_DECOMPOSITION.  Otherwise an
+   * exception will be thrown.  See the documentation for those
+   * contants for an explanation of this setting.
+   *
+   * @param mode The new decomposition setting.
+   *
+   * @exception IllegalArgumentException If the requested
+   * decomposition setting is not valid.
+   */
+  public synchronized void setDecomposition (int mode)
+  {
+    if (mode != NO_DECOMPOSITION
+	&& mode != CANONICAL_DECOMPOSITION
+	&& mode != FULL_DECOMPOSITION)
+      throw new IllegalArgumentException ();
+    decmp = mode;
+  }
+
+  /**
+   * This method sets the strength setting for this object to the specified
+   * value.  This must be one of PRIMARY, SECONDARY, TERTIARY, or IDENTICAL.
+   * Otherwise an exception is thrown. See the documentation for these
+   * constants for an explanation of this setting.
+   * 
+   * @param strength The new strength setting.
+   *
+   * @exception IllegalArgumentException If the requested strength
+   * setting value is not valid.
+   */
+  public synchronized void setStrength (int strength)
+  {
+    if (strength != PRIMARY && strength != SECONDARY
+	&& strength != TERTIARY && strength != IDENTICAL)
+      throw new IllegalArgumentException ();
+    this.strength = strength;
+  }
+
+  // Decompose a single character and append results to the buffer.
+  native final void decomposeCharacter (char c, StringBuffer buf);
+
+  /**
+   * This is the current collation decomposition setting.
+   */
+  int decmp;
+
+  /**
+   * This is the current collation strength setting.
+   */
+  int strength;
+}

Added: llvm-gcc-4.2/trunk/libjava/java/text/DateFormatSymbols.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/text/DateFormatSymbols.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/text/DateFormatSymbols.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/text/DateFormatSymbols.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,502 @@
+/* DateFormatSymbols.java -- Format over a range of numbers
+   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+ 
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.text;
+
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * This class acts as container for locale specific date/time formatting
+ * information such as the days of the week and the months of the year.
+ * @author Per Bothner (bothner at cygnus.com)
+ * @date October 24, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3.
+ * Status:  Believed complete and correct.
+ */
+public class DateFormatSymbols implements java.io.Serializable, Cloneable
+{
+  String[] ampms;
+  String[] eras;
+  private String localPatternChars;
+  String[] months;
+  String[] shortMonths;
+  String[] shortWeekdays;
+  String[] weekdays;
+  private String[][] zoneStrings;
+
+  private static final long serialVersionUID = -5987973545549424702L;
+
+  // The order of these prefixes must be the same as in DateFormat
+  private static final String[] formatPrefixes =
+  {
+    "full", "long", "medium", "short"
+  };
+
+  // These are each arrays with a value for SHORT, MEDIUM, LONG, FULL,
+  // and DEFAULT (constants defined in java.text.DateFormat).  While
+  // not part of the official spec, we need a way to get at locale-specific
+  // default formatting patterns.  They are declared package scope so
+  // as to be easily accessible where needed (DateFormat, SimpleDateFormat).
+  transient String[] dateFormats;
+  transient String[] timeFormats;
+
+  private String[] formatsForKey(ResourceBundle res, String key) 
+  {
+    String[] values = new String [formatPrefixes.length];
+    for (int i = 0; i < formatPrefixes.length; i++)
+      {
+        values[i] = res.getString(formatPrefixes[i]+key);
+      }
+    return values;
+  }
+
+  /**
+   * This method initializes a new instance of <code>DateFormatSymbols</code>
+   * by loading the date format information for the specified locale.
+   *
+   * @param locale The locale for which date formatting symbols should
+   *               be loaded. 
+   */
+  public DateFormatSymbols (Locale locale) throws MissingResourceException
+  {
+    ResourceBundle res
+      = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", locale,
+      				 ClassLoader.getSystemClassLoader());
+
+    ampms = res.getStringArray ("ampms");
+    eras = res.getStringArray ("eras");
+    localPatternChars = res.getString ("localPatternChars");
+    months = res.getStringArray ("months");
+    shortMonths = res.getStringArray ("shortMonths");
+    shortWeekdays = res.getStringArray ("shortWeekdays");
+    weekdays = res.getStringArray ("weekdays");
+    zoneStrings = (String[][]) res.getObject ("zoneStrings");
+
+    dateFormats = formatsForKey(res, "DateFormat");
+    timeFormats = formatsForKey(res, "TimeFormat");
+  }
+
+  /**
+   * This method loads the format symbol information for the default
+   * locale.
+   */
+  public DateFormatSymbols () throws MissingResourceException
+  {
+    this (Locale.getDefault());
+  }
+
+  /**
+   * This method returns the list of strings used for displaying AM or PM.
+   * This is a two element <code>String</code> array indexed by
+   * <code>Calendar.AM</code> and <code>Calendar.PM</code>
+   *
+   * @return The list of AM/PM display strings.
+   */
+  public String[] getAmPmStrings()
+  {
+    return ampms;
+  }
+
+  /**
+    * This method returns the list of strings used for displaying eras
+    * (e.g., "BC" and "AD").  This is a two element <code>String</code>
+    * array indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>.
+    *
+    * @return The list of era disply strings.
+    */
+  public String[] getEras()
+  {
+    return eras;
+  }
+
+  /**
+    * This method returns the pattern character information for this
+    * object.  This is an 18 character string that contains the characters
+    * that are used in creating the date formatting strings in 
+    * <code>SimpleDateFormat</code>.   The following are the character
+    * positions in the string and which format character they correspond
+    * to (the character in parentheses is the default value in the US English
+    * locale):
+    * <p>
+    * <ul>
+    * <li>0 - era (G)</li>
+    * <li>1 - year (y)</li>
+    * <li>2 - month (M)</li>
+    * <li>3 - day of month (d)</li>
+    * <li>4 - hour out of 12, from 1-12 (h)</li>
+    * <li>5 - hour out of 24, from 0-23 (H)</li>
+    * <li>6 - minute (m)</li>
+    * <li>7 - second (s)</li>
+    * <li>8 - millisecond (S)</li>
+    * <li>9 - date of week (E)</li>
+    * <li>10 - date of year (D)</li>
+    * <li>11 - day of week in month, eg. "4th Thur in Nov" (F)</li>
+    * <li>12 - week in year (w)</li>
+    * <li>13 - week in month (W)</li>
+    * <li>14 - am/pm (a)</li>
+    * <li>15 - hour out of 24, from 1-24 (k)</li>
+    * <li>16 - hour out of 12, from 0-11 (K)</li>
+    * <li>17 - time zone (z)</li>
+    * </ul>
+    *
+    * @return The format patter characters
+    */
+  public String getLocalPatternChars()
+  {
+    return localPatternChars;
+  }
+
+  /**
+   * This method returns the list of strings used for displaying month
+   * names (e.g., "January" and "February").  This is a thirteen element
+   * string array indexed by <code>Calendar.JANUARY</code> through
+   * <code>Calendar.UNDECEMBER</code>.  Note that there are thirteen
+   * elements because some calendars have thriteen months.
+   *
+   * @return The list of month display strings.
+   */
+  public String[] getMonths ()
+  {
+    return months;
+  }
+
+  /**
+   * This method returns the list of strings used for displaying abbreviated
+   * month names (e.g., "Jan" and "Feb").  This is a thirteen element
+   * <code>String</code> array indexed by <code>Calendar.JANUARY</code>
+   * through <code>Calendar.UNDECEMBER</code>.  Note that there are thirteen
+   * elements because some calendars have thirteen months.
+   *
+   * @return The list of abbreviated month display strings.
+   */
+  public String[] getShortMonths ()
+  {
+    return shortMonths;
+  }
+
+  /**
+   * This method returns the list of strings used for displaying abbreviated 
+   * weekday names (e.g., "Sun" and "Mon").  This is an eight element
+   * <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
+   * through <code>Calendar.SATURDAY</code>.  Note that the first element
+   * of this array is ignored.
+   *
+   * @return This list of abbreviated weekday display strings.
+   */
+  public String[] getShortWeekdays ()
+  {
+    return shortWeekdays;
+  }
+
+  /**
+   * This method returns the list of strings used for displaying weekday
+   * names (e.g., "Sunday" and "Monday").  This is an eight element
+   * <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
+   * through <code>Calendar.SATURDAY</code>.  Note that the first element
+   * of this array is ignored.
+   *
+   * @return This list of weekday display strings.
+   */
+  public String[] getWeekdays ()
+  {
+    return weekdays;
+  }
+
+  /**
+   * This method returns this list of localized timezone display strings.
+   * This is a two dimensional <code>String</code> array where each row in
+   * the array contains five values:
+   * <P>
+   * <ul>
+   * <li>0 - The non-localized time zone id string.</li>
+   * <li>1 - The long name of the time zone (standard time).</li>
+   * <li>2 - The short name of the time zone (standard time).</li>
+   * <li>3 - The long name of the time zone (daylight savings time).</li>
+   * <li>4 - the short name of the time zone (daylight savings time).</li>
+   * </ul>
+   *
+   * @return The list of time zone display strings.
+   */
+  public String[] [] getZoneStrings ()
+  {
+    return zoneStrings;
+  }
+
+  /**
+   * This method sets the list of strings used to display AM/PM values to
+   * the specified list.
+   * This is a two element <code>String</code> array indexed by
+   * <code>Calendar.AM</code> and <code>Calendar.PM</code>
+   *
+   * @param value The new list of AM/PM display strings.
+   */
+  public void setAmPmStrings (String[] value)
+  {
+    ampms = value;
+  }
+
+  /**
+   * This method sets the list of strings used to display time eras to
+   * to the specified list.
+   * This is a two element <code>String</code>
+   * array indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>.
+   *
+   * @param labels The new list of era display strings.
+   */
+  public void setEras (String[] labels)
+  {
+    eras = labels;
+  }
+
+  /**
+    * This method sets the list of characters used to specific date/time
+    * formatting strings.
+    * This is an 18 character string that contains the characters
+    * that are used in creating the date formatting strings in 
+    * <code>SimpleDateFormat</code>.   The following are the character
+    * positions in the string and which format character they correspond
+    * to (the character in parentheses is the default value in the US English
+    * locale):
+    * <p>
+    * <ul>
+    * <li>0 - era (G)</li>
+    * <li>1 - year (y)</li>
+    * <li>2 - month (M)</li>
+    * <li>3 - day of month (d)</li>
+    * <li>4 - hour out of 12, from 1-12 (h)</li>
+    * <li>5 - hour out of 24, from 0-23 (H)</li>
+    * <li>6 - minute (m)</li>
+    * <li>7 - second (s)</li>
+    * <li>8 - millisecond (S)</li>
+    * <li>9 - date of week (E)</li>
+    * <li>10 - date of year (D)</li>
+    * <li>11 - day of week in month, eg. "4th Thur in Nov" (F)</li>
+    * <li>12 - week in year (w)</li>
+    * <li>13 - week in month (W)</li>
+    * <li>14 - am/pm (a)</li>
+    * <li>15 - hour out of 24, from 1-24 (k)</li>
+    * <li>16 - hour out of 12, from 0-11 (K)</li>
+    * <li>17 - time zone (z)</li>
+    * </ul>
+    *
+    * @param chars The new format pattern characters
+    */
+  public void setLocalPatternChars (String chars)
+  {
+    localPatternChars = chars;
+  }
+
+  /**
+    * This method sets the list of strings used to display month names.
+    * This is a thirteen element
+    * string array indexed by <code>Calendar.JANUARY</code> through
+    * <code>Calendar.UNDECEMBER</code>.  Note that there are thirteen
+    * elements because some calendars have thriteen months.
+    *
+    * @param labels The list of month display strings.
+    */
+  public void setMonths (String[] labels)
+  {
+    months = labels;
+  }
+
+  /**
+   * This method sets the list of strings used to display abbreviated month
+   * names.
+   * This is a thirteen element
+   * <code>String</code> array indexed by <code>Calendar.JANUARY</code>
+   * through <code>Calendar.UNDECEMBER</code>.  Note that there are thirteen
+   * elements because some calendars have thirteen months.
+   *
+   * @param labels The new list of abbreviated month display strings.
+   */
+  public void setShortMonths (String[] labels)
+  {
+    shortMonths = labels;
+  }
+
+  /**
+   * This method sets the list of strings used to display abbreviated
+   * weekday names.
+   * This is an eight element
+   * <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
+   * through <code>Calendar.SATURDAY</code>.  Note that the first element
+   * of this array is ignored.
+   *
+   * @param labels This list of abbreviated weekday display strings.
+   */
+  public void setShortWeekdays (String[] labels)
+  {
+    shortWeekdays = labels;
+  }
+
+  /**
+   * This method sets the list of strings used to display weekday names.
+   * This is an eight element
+   * <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
+   * through <code>Calendar.SATURDAY</code>.  Note that the first element
+   * of this array is ignored.
+   *
+   * @param labels This list of weekday display strings.
+   */
+  public void setWeekdays (String[] labels)
+  {
+    weekdays = labels;
+  }
+
+  /**
+   * This method sets the list of display strings for time zones.
+   * This is a two dimensional <code>String</code> array where each row in
+   * the array contains five values:
+   * <P>
+   * <ul>
+   * <li>0 - The non-localized time zone id string.</li>
+   * <li>1 - The long name of the time zone (standard time).</li>
+   * <li>2 - The short name of the time zone (standard time).</li>
+   * <li>3 - The long name of the time zone (daylight savings time).</li>
+   * <li>4 - the short name of the time zone (daylight savings time).</li>
+   * </ul>
+   *
+   * @params zones The list of time zone display strings.
+   */
+  public void setZoneStrings (String[][] zones)
+  {
+    zoneStrings = zones;
+  }
+
+  /* Does a "deep" equality test - recurses into arrays. */
+  private static boolean equals (Object x, Object y)
+  {
+    if (x == y)
+      return true;
+    if (x == null || y == null)
+      return false;
+    if (! (x instanceof Object[]) || ! (y instanceof Object[]))
+      return x.equals(y);
+    Object[] xa = (Object[]) x;
+    Object[] ya = (Object[]) y;
+    if (xa.length != ya.length)
+      return false;
+    for (int i = xa.length;  --i >= 0; )
+      {
+	if (! equals(xa[i], ya[i]))
+	  return false;
+      }
+    return true;
+  }
+
+  private static int hashCode (Object x)
+  {
+    if (x == null)
+      return 0;
+    if (! (x instanceof Object[]))
+      return x.hashCode();
+    Object[] xa = (Object[]) x;
+    int hash = 0;
+    for (int i = 0;  i < xa.length;  i++)
+      hash = 37 * hashCode(xa[i]);
+    return hash;
+  }
+
+  /**
+   * This method tests a specified object for equality against this object.
+   * This will be true if and only if the specified object:
+   * <p>
+   * <ul>
+   * <li> Is not <code>null</code>.</li>
+   * <li> Is an instance of <code>DateFormatSymbols</code>.</li>
+   * <li> Contains identical formatting symbols to this object.</li>
+   * </ul>
+   * 
+   * @param obj The <code>Object</code> to test for equality against.
+   *
+   * @return <code>true</code> if the specified object is equal to this one,
+   * <code>false</code> otherwise.
+   */
+  public boolean equals (Object obj)
+  {
+    if (! (obj instanceof DateFormatSymbols))
+      return false;
+    DateFormatSymbols other = (DateFormatSymbols) obj;
+    return (equals(ampms, other.ampms)
+	    && equals(eras, other.eras)
+	    && equals(localPatternChars, other.localPatternChars)
+	    && equals(months, other.months)
+	    && equals(shortMonths, other.shortMonths)
+	    && equals(shortWeekdays, other.shortWeekdays)
+	    && equals(weekdays, other.weekdays)
+	    && equals(zoneStrings, other.zoneStrings));
+  }
+
+  /**
+   * Returns a new copy of this object.
+   *
+   * @return A copy of this object
+   */
+  public Object clone ()
+  {
+    try
+      {
+        return super.clone ();
+      } 
+    catch (CloneNotSupportedException e) 
+      {
+        return null;
+      }
+  }
+
+  /**
+   * This method returns a hash value for this object.
+   *
+   * @return A hash value for this object.
+   */
+  public int hashCode ()
+  {
+    return (hashCode(ampms)
+	    ^ hashCode(eras)
+	    ^ hashCode(localPatternChars)
+	    ^ hashCode(months)
+	    ^ hashCode(shortMonths)
+	    ^ hashCode(shortWeekdays)
+	    ^ hashCode(weekdays)
+	    ^ hashCode(zoneStrings));
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/text/DecimalFormatSymbols.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/text/DecimalFormatSymbols.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/text/DecimalFormatSymbols.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/text/DecimalFormatSymbols.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,613 @@
+/* DecimalFormatSymbols.java -- Format symbols used by DecimalFormat
+   Copyright (C) 1999, 2000, 2001, 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.text;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.util.Currency;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * This class is a container for the symbols used by 
+ * <code>DecimalFormat</code> to format numbers and currency.  These are
+ * normally handled automatically, but an application can override
+ * values as desired using this class.
+ *
+ * @author Tom Tromey (tromey at cygnus.com)
+ * @author Aaron M. Renn (arenn at urbanophile.com)
+ * @date February 24, 1999
+ */
+/* Written using "Java Class Libraries", 2nd edition, plus online
+ * API docs for JDK 1.2 from http://www.javasoft.com.
+ * Status:  Believed complete and correct to 1.2.
+ */
+public final class DecimalFormatSymbols implements Cloneable, Serializable
+{
+  public Object clone ()
+  {
+    try
+      {
+	return super.clone ();
+      }
+    catch(CloneNotSupportedException e)
+      {
+	return null;
+      }
+  }
+
+  /**
+   * This method initializes a new instance of
+   * <code>DecimalFormatSymbols</code> for the default locale.
+   */
+  public DecimalFormatSymbols ()
+  {
+    this (Locale.getDefault());
+  }
+
+  private String safeGetString(ResourceBundle bundle,
+                               String name, String def)
+  {
+    if (bundle != null)
+      {
+	try
+	  {
+	    return bundle.getString(name);
+	  }
+	catch (MissingResourceException x)
+	  {
+	  }
+      }
+    return def;
+  }
+
+  private char safeGetChar(ResourceBundle bundle,
+                           String name, char def)
+  {
+    String r = null;
+    if (bundle != null)
+      {
+	try
+	  {
+	    r = bundle.getString(name);
+	  }
+	catch (MissingResourceException x)
+	  {
+	  }
+      }
+    if (r == null || r.length() < 1)
+      return def;
+    return r.charAt(0);
+  }
+
+  /**
+   * This method initializes a new instance of
+   * <code>DecimalFormatSymbols</code> for the specified locale.
+   *
+   * @param loc The local to load symbols for.
+   */
+  public DecimalFormatSymbols (Locale loc)
+  {
+    ResourceBundle res;
+    try
+      {
+	res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
+		loc, ClassLoader.getSystemClassLoader());
+      }
+    catch (MissingResourceException x)
+      {
+	res = null;
+      }
+    currencySymbol = safeGetString (res, "currencySymbol", "$");
+    decimalSeparator = safeGetChar (res, "decimalSeparator", '.');
+    digit = safeGetChar (res, "digit", '#');
+    exponential = safeGetChar (res, "exponential", 'E');
+    groupingSeparator = safeGetChar (res, "groupingSeparator", ',');
+    infinity = safeGetString (res, "infinity", "\u221e");
+    // FIXME: default?
+    intlCurrencySymbol = safeGetString (res, "intlCurrencySymbol", "$");
+    try
+      {
+	monetarySeparator = safeGetChar (res, "monetarySeparator", '.');
+      }
+    catch (MissingResourceException x)
+      {
+	monetarySeparator = decimalSeparator;
+      }
+    minusSign = safeGetChar (res, "minusSign", '-');
+    NaN = safeGetString (res, "NaN", "\ufffd");
+    patternSeparator = safeGetChar (res, "patternSeparator", ';');
+    percent = safeGetChar (res, "percent", '%');
+    perMill = safeGetChar (res, "perMill", '\u2030');
+    zeroDigit = safeGetChar (res, "zeroDigit", '0');
+    locale = loc;
+  }
+
+  /**
+   * This method this this object for equality against the specified object.
+   * This will be true if and only if the following criteria are met with
+   * regard to the specified object:
+   * <p>
+   * <ul>
+   * <li>It is not <code>null</code>.</li>
+   * <li>It is an instance of <code>DecimalFormatSymbols</code>.</li>
+   * <li>All of its symbols are identical to the symbols in this object.</li>
+   * </ul>
+   *
+   * @return <code>true</code> if the specified object is equal to this
+   * object, <code>false</code> otherwise.
+   */
+  public boolean equals (Object obj)
+  {
+    if (! (obj instanceof DecimalFormatSymbols))
+      return false;
+    DecimalFormatSymbols dfs = (DecimalFormatSymbols) obj;
+    return (currencySymbol.equals(dfs.currencySymbol)
+	    && decimalSeparator == dfs.decimalSeparator
+	    && digit == dfs.digit
+	    && exponential == dfs.exponential
+	    && groupingSeparator == dfs.groupingSeparator
+	    && infinity.equals(dfs.infinity)
+	    && intlCurrencySymbol.equals(dfs.intlCurrencySymbol)
+	    && minusSign == dfs.minusSign
+	    && monetarySeparator == dfs.monetarySeparator
+	    && NaN.equals(dfs.NaN)
+	    && patternSeparator == dfs.patternSeparator
+	    && percent == dfs.percent
+	    && perMill == dfs.perMill
+	    && zeroDigit == dfs.zeroDigit);
+  }
+
+  /**
+   * Returns the currency corresponding to the currency symbol stored
+   * in the instance of <code>DecimalFormatSymbols</code>.
+   *
+   * @return A new instance of <code>Currency</code> if
+   * the currency code matches a known one.
+   */
+  public Currency getCurrency ()
+  {
+    return Currency.getInstance (currencySymbol);
+  }
+
+  /**
+   * This method returns the currency symbol in local format.  For example,
+   * "$" for Canadian dollars.
+   *
+   * @return The currency symbol in local format.
+   */
+  public String getCurrencySymbol ()
+  {
+    return currencySymbol;
+  }
+
+  /**
+   * This method returns the character used as the decimal point.
+   *
+   * @return The character used as the decimal point.
+   */
+  public char getDecimalSeparator ()
+  {
+    return decimalSeparator;
+  }
+
+  /**
+   * This method returns the character used to represent a digit in a
+   * format pattern string.
+   *
+   * @return The character used to represent a digit in a format
+   * pattern string. 
+   */
+  public char getDigit ()
+  {
+    return digit;
+  }
+
+  // This is our own extension.
+  char getExponential ()
+  {
+    return exponential;
+  }
+
+  /**
+   * This method sets the character used to separate groups of digits.  For
+   * example, the United States uses a comma (,) to separate thousands in
+   * a number.
+   *
+   * @return The character used to separate groups of digits.
+   */
+  public char getGroupingSeparator ()
+  {
+    return groupingSeparator;
+  }
+
+  /**
+   * This method returns the character used to represent infinity.
+   *
+   * @return The character used to represent infinity.
+   */
+  public String getInfinity ()
+  {
+    return infinity;
+  }
+
+  /**
+   * This method returns the currency symbol in international format.  For
+   * example, "C$" for Canadian dollars.
+   *
+   * @return The currency symbol in international format.
+   */
+  public String getInternationalCurrencySymbol ()
+  {
+    return intlCurrencySymbol;
+  }
+
+  /**
+   * This method returns the character used to represent the minus sign.
+   *
+   * @return The character used to represent the minus sign.
+   */
+  public char getMinusSign ()
+  {
+    return minusSign;
+  }
+
+  /**
+   * This method returns the character used to represent the decimal
+   * point for currency values.
+   *
+   * @return The decimal point character used in currency values.
+   */
+  public char getMonetaryDecimalSeparator ()
+  {
+    return monetarySeparator;
+  }
+
+  /**
+   * This method returns the string used to represent the NaN (not a number)
+   * value.
+   *
+   * @return The string used to represent NaN
+   */
+  public String getNaN ()
+  {
+    return NaN;
+  }
+
+  /**
+   * This method returns the character used to separate positive and negative
+   * subpatterns in a format pattern.
+   *
+   * @return The character used to separate positive and negative subpatterns
+   * in a format pattern.
+   */
+  public char getPatternSeparator ()
+  {
+    return patternSeparator;
+  }
+
+  /**
+   * This method returns the character used as the percent sign.
+   *
+   * @return The character used as the percent sign.
+   */
+  public char getPercent ()
+  {
+    return percent;
+  }
+
+  /**
+   * This method returns the character used as the per mille character.
+   *
+   * @return The per mille character.
+   */
+  public char getPerMill ()
+  {
+    return perMill;
+  }
+
+  /**
+   * This method returns the character used to represent the digit zero.
+   *
+   * @return The character used to represent the digit zero.
+   */
+  public char getZeroDigit ()
+  {
+    return zeroDigit;
+  }
+
+  /**
+   * This method returns a hash value for this object.
+   *
+   * @return A hash value for this object.
+   */
+  public int hashCode ()
+  {
+    // Compute based on zero digit, grouping separator, and decimal
+    // separator -- JCL book.  This probably isn't a very good hash
+    // code.
+    return zeroDigit << 16 + groupingSeparator << 8 + decimalSeparator;
+  }
+
+  /**
+   * This method sets the currency to the specified value.
+   *
+   * @param currency The new currency
+   */
+  public void setCurrency (Currency currency)
+  {
+    setCurrencySymbol (currency.getSymbol());
+  }
+
+  /**
+   * This method sets the currency symbol to the specified value.
+   *
+   * @param currency The new currency symbol
+   */
+  public void setCurrencySymbol (String currency)
+  {
+    currencySymbol = currency;
+  }
+
+  /**
+   * This method sets the decimal point character to the specified value.
+   *
+   * @param decimalSep The new decimal point character
+   */
+  public void setDecimalSeparator (char decimalSep)
+  {
+    decimalSeparator = decimalSep;
+  }
+
+  /**
+   * This method sets the character used to represents a digit in a format
+   * string to the specified value.
+   *
+   * @param digit The character used to represent a digit in a format pattern.
+   */
+  public void setDigit (char digit)
+  {
+    this.digit = digit;
+  }
+
+  // This is our own extension.
+  void setExponential (char exp)
+  {
+    exponential = exp;
+  }
+
+  /**
+   * This method sets the character used to separate groups of digits.
+   *
+   * @param groupSep The character used to separate groups of digits.
+   */
+  public void setGroupingSeparator (char groupSep)
+  {
+    groupingSeparator = groupSep;
+  }
+
+  /**
+   * This method sets the string used to represents infinity.
+   *
+   * @param infinity The string used to represent infinity.
+   */
+  public void setInfinity (String infinity)
+  {
+    this.infinity = infinity;
+  }
+
+  /**
+   * This method sets the international currency symbols to the
+   * specified value. 
+   *
+   * @param intlCurrencySymbol The new international currency symbol.
+   */
+  public void setInternationalCurrencySymbol (String currency)
+  {
+    intlCurrencySymbol = currency;
+  }
+
+  /**
+   * This method sets the character used to represent the minus sign.
+   *
+   * @param minusSign The character used to represent the minus sign.
+   */
+  public void setMinusSign (char minusSign)
+  {
+    this.minusSign = minusSign;
+  }
+
+  /**
+   * This method sets the character used for the decimal point in currency
+   * values.
+   *
+   * @param decimalSep The decimal point character used in currency values. 
+   */
+  public void setMonetaryDecimalSeparator (char decimalSep)
+  {
+    monetarySeparator = decimalSep;
+  }
+
+  /**
+   * This method sets the string used to represent the NaN (not a
+   * number) value. 
+   *
+   * @param nan The string used to represent NaN
+   */
+  public void setNaN (String nan)
+  {
+    NaN = nan;
+  }
+
+  /**
+   * This method sets the character used to separate positive and negative
+   * subpatterns in a format pattern.
+   *
+   * @param patternSep The character used to separate positive and
+   * negative subpatterns in a format pattern.
+   */
+  public void setPatternSeparator (char patternSep)
+  {
+    patternSeparator = patternSep;
+  }
+
+  /**
+   * This method sets the character used as the percent sign.
+   *
+   * @param percent  The character used as the percent sign.
+   */
+  public void setPercent (char percent)
+  {
+    this.percent = percent;
+  }
+
+  /**
+   * This method sets the character used as the per mille character.
+   *
+   * @param perMill The per mille character.
+   */
+  public void setPerMill (char perMill)
+  {
+    this.perMill = perMill;
+  }
+
+  /**
+   * This method sets the character used to represent the digit zero.
+   *
+   * @param zeroDigit The character used to represent the digit zero.
+   */
+  public void setZeroDigit (char zeroDigit)
+  {
+    this.zeroDigit = zeroDigit;
+  }
+
+  /**
+   * @serial A string used for the local currency
+   */
+  private String currencySymbol;
+  /**
+   * @serial The <code>char</code> used to separate decimals in a number.
+   */
+  private char decimalSeparator;
+  /**
+   * @serial This is the <code>char</code> used to represent a digit in
+   * a format specification.
+   */
+  private char digit;
+  /**
+   * @serial This is the <code>char</code> used to represent the exponent
+   * separator in exponential notation.
+   */
+  private char exponential;
+  /**
+   * @serial This separates groups of thousands in numbers.
+   */
+  private char groupingSeparator;
+  /**
+   * @serial This string represents infinity.
+   */
+  private String infinity;
+  /**
+   * @serial This string represents the local currency in an international
+   * context, eg, "C$" for Canadian dollars.
+   */
+  private String intlCurrencySymbol;
+  /**
+   * @serial This is the character used to represent the minus sign.
+   */
+  private char minusSign;
+  /**
+   * @serial This character is used to separate decimals when formatting
+   * currency values.
+   */
+  private char monetarySeparator;
+  /**
+   * @serial This string is used the represent the Java NaN value for
+   * "not a number".
+   */
+  private String NaN;
+  /**
+   * @serial This is the character used to separate positive and negative
+   * subpatterns in a format pattern.
+   */
+  private char patternSeparator;
+  /**
+   * @serial This is the percent symbols
+   */
+  private char percent;
+  /**
+   * @serial This character is used for the mille percent sign.
+   */
+  private char perMill;
+  /**
+   * @serial This value represents the type of object being de-serialized.
+   * 0 indicates a pre-Java 1.1.6 version, 1 indicates 1.1.6 or later.
+   * 0 indicates a pre-Java 1.1.6 version, 1 indicates 1.1.6 or later,
+   * 2 indicates 1.4 or later
+    */
+  private int serialVersionOnStream = 2;
+  /**
+   * @serial This is the character used to represent 0.
+   */
+  private char zeroDigit;
+
+  /**
+   * @serial The locale of these currency symbols.
+   */
+  private Locale locale;
+ 
+  private static final long serialVersionUID = 5772796243397350300L;
+
+  private void readObject(ObjectInputStream stream)
+    throws IOException, ClassNotFoundException
+  {
+    stream.defaultReadObject();
+    if (serialVersionOnStream < 1)
+      {
+        monetarySeparator = decimalSeparator;
+	exponential = 'E';
+      }
+    if (serialVersionOnStream < 2)
+	locale = Locale.getDefault();
+
+    serialVersionOnStream = 2;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/text/natCollator.cc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/text/natCollator.cc?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/text/natCollator.cc (added)
+++ llvm-gcc-4.2/trunk/libjava/java/text/natCollator.cc Thu Nov  8 16:56:19 2007
@@ -0,0 +1,74 @@
+// natCollator.cc - Native code for collation.
+
+/* Copyright (C) 1999  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+// Written by Tom Tromey <tromey at cygnus.com>.
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/text/Collator.h>
+#include <java/lang/StringBuffer.h>
+
+#include <java-chardecomp.h>
+
+void
+java::text::Collator::decomposeCharacter (jchar c,
+					  java::lang::StringBuffer *buf)
+{
+  if (decmp == NO_DECOMPOSITION)
+    {
+      buf->append(c);
+      return;
+    }
+
+  const struct decomp_entry *base;
+  int high;
+
+  if (decmp == FULL_DECOMPOSITION)
+    {
+      base = full_decomposition;
+      high = sizeof (full_decomposition) / sizeof (struct decomp_entry);
+    }
+  else
+    {
+      base = canonical_decomposition;
+      high = sizeof (canonical_decomposition) / sizeof (struct decomp_entry);
+    }
+
+  // FIXME: this is probably a bit slow for the task at hand.
+  int i = high / 2;
+  int low = 0;
+  while (true)
+    {
+      if (c < base[i].key)
+	high = i;
+      else if (c > base[i].key)
+	low = i;
+      else
+	break;
+
+      int old = i;
+      i = (high + low) / 2;
+      if (i == old)
+	{
+	  // Not in table, so it expands to itself.
+	  buf->append(c);
+	  return;
+	}
+    }
+
+  for (int j = 0; base[i].value[j] != '\0'; j += 2)
+    {
+      jchar x = (base[i].value[j] << 8) | (base[i].value[j + 1]);
+      buf->append (x);
+    }
+}

Added: llvm-gcc-4.2/trunk/libjava/java/util/Calendar.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/java/util/Calendar.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/java/util/Calendar.java (added)
+++ llvm-gcc-4.2/trunk/libjava/java/util/Calendar.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1277 @@
+/* Calendar.java --
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 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.util;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * This class is an abstract base class for Calendars, which can be
+ * used to convert between <code>Date</code> objects and a set of
+ * integer fields which represent <code>YEAR</code>,
+ * <code>MONTH</code>, <code>DAY</code>, etc.  The <code>Date</code>
+ * object represents a time in milliseconds since the Epoch. <br>
+ *
+ * This class is locale sensitive.  To get the Object matching the
+ * current locale you can use <code>getInstance</code>.  You can even provide
+ * a locale or a timezone.  <code>getInstance</code> returns currently
+ * a <code>GregorianCalendar</code> for the current date. <br>
+ *
+ * If you want to convert a date from the Year, Month, Day, DayOfWeek,
+ * etc.  Representation to a <code>Date</code>-Object, you can create
+ * a new Calendar with <code>getInstance()</code>,
+ * <code>clear()</code> all fields, <code>set(int,int)</code> the
+ * fields you need and convert it with <code>getTime()</code>. <br>
+ *
+ * If you want to convert a <code>Date</code>-object to the Calendar
+ * representation, create a new Calendar, assign the
+ * <code>Date</code>-Object with <code>setTime()</code>, and read the
+ * fields with <code>get(int)</code>. <br>
+ *
+ * When computing the date from time fields, it may happen, that there
+ * are either two few fields set, or some fields are inconsistent.  This
+ * cases will handled in a calendar specific way.  Missing fields are
+ * replaced by the fields of the epoch: 1970 January 1 00:00. <br>
+ *
+ * To understand, how the day of year is computed out of the fields
+ * look at the following table.  It is traversed from top to bottom,
+ * and for the first line all fields are set, that line is used to
+ * compute the day. <br>
+ *
+ *
+<pre>month + day_of_month
+month + week_of_month + day_of_week
+month + day_of_week_of_month + day_of_week
+day_of_year
+day_of_week + week_of_year</pre>
+ *
+ * The hour_of_day-field takes precedence over the ampm and
+ * hour_of_ampm fields. <br>
+ *
+ * <STRONG>Note:</STRONG> This can differ for non-Gregorian calendar. <br>
+ *
+ * To convert a calendar to a human readable form and vice versa,  use
+ * the <code>java.text.DateFormat</code> class. <br>
+ *
+ * Other useful things you can do with an calendar, is
+ * <code>roll</code>ing fields (that means increase/decrease a
+ * specific field by one, propagating overflows), or
+ * <code>add</code>ing/substracting a fixed amount to a field.
+ *
+ * @see Date
+ * @see GregorianCalendar
+ * @see TimeZone
+ * @see java.text.DateFormat
+ */
+public abstract class Calendar implements Serializable, Cloneable
+{
+  /**
+   * Constant representing the era time field.
+   */
+  public static final int ERA = 0;
+
+  /**
+   * Constant representing the year time field.
+   */
+  public static final int YEAR = 1;
+
+  /**
+   * Constant representing the month time field.  This field
+   * should contain one of the JANUARY,...,DECEMBER constants below.
+   */
+  public static final int MONTH = 2;
+
+  /**
+   * Constant representing the week of the year field.
+   * @see #setFirstDayOfWeek(int)
+   */
+  public static final int WEEK_OF_YEAR = 3;
+
+  /**
+   * Constant representing the week of the month time field.
+   * @see #setFirstDayOfWeek(int)
+   */
+  public static final int WEEK_OF_MONTH = 4;
+
+  /**
+   * Constant representing the day time field, synonym for DAY_OF_MONTH.
+   */
+  public static final int DATE = 5;
+
+  /**
+   * Constant representing the day time field.
+   */
+  public static final int DAY_OF_MONTH = 5;
+
+  /**
+   * Constant representing the day of year time field.  This is
+   * 1 for the first day in month.
+   */
+  public static final int DAY_OF_YEAR = 6;
+
+  /**
+   * Constant representing the day of week time field.  This field
+   * should contain one of the SUNDAY,...,SATURDAY constants below.
+   */
+  public static final int DAY_OF_WEEK = 7;
+
+  /**
+   * Constant representing the day-of-week-in-month field.  For
+   * instance this field contains 2 for the second thursday in a
+   * month.  If you give a negative number here, the day will count
+   * from the end of the month.
+   */
+  public static final int DAY_OF_WEEK_IN_MONTH = 8;
+
+  /**
+   * Constant representing the part of the day for 12-hour clock.  This
+   * should be one of AM or PM.
+   */
+  public static final int AM_PM = 9;
+
+  /**
+   * Constant representing the hour time field for 12-hour clock.
+   */
+  public static final int HOUR = 10;
+
+  /**
+   * Constant representing the hour of day time field for 24-hour clock.
+   */
+  public static final int HOUR_OF_DAY = 11;
+
+  /**
+   * Constant representing the minute of hour time field.
+   */
+  public static final int MINUTE = 12;
+
+  /**
+   * Constant representing the second time field.
+   */
+  public static final int SECOND = 13;
+
+  /**
+   * Constant representing the millisecond time field.
+   */
+  public static final int MILLISECOND = 14;
+
+  /**
+   * Constant representing the time zone offset time field for the
+   * time given in the other fields.  It is measured in
+   * milliseconds.  The default is the offset of the time zone.
+   */
+  public static final int ZONE_OFFSET = 15;
+
+  /**
+   * Constant representing the daylight saving time offset in
+   * milliseconds.  The default is the value given by the time zone.
+   */
+  public static final int DST_OFFSET = 16;
+
+  /**
+   * Number of time fields.
+   */
+  public static final int FIELD_COUNT = 17;
+
+  /**
+   * Constant representing Sunday.
+   */
+  public static final int SUNDAY = 1;
+
+  /**
+   * Constant representing Monday.
+   */
+  public static final int MONDAY = 2;
+
+  /**
+   * Constant representing Tuesday.
+   */
+  public static final int TUESDAY = 3;
+
+  /**
+   * Constant representing Wednesday.
+   */
+  public static final int WEDNESDAY = 4;
+
+  /**
+   * Constant representing Thursday.
+   */
+  public static final int THURSDAY = 5;
+
+  /**
+   * Constant representing Friday.
+   */
+  public static final int FRIDAY = 6;
+
+  /**
+   * Constant representing Saturday.
+   */
+  public static final int SATURDAY = 7;
+
+  /**
+   * Constant representing January.
+   */
+  public static final int JANUARY = 0;
+
+  /**
+   * Constant representing February.
+   */
+  public static final int FEBRUARY = 1;
+
+  /**
+   * Constant representing March.
+   */
+  public static final int MARCH = 2;
+
+  /**
+   * Constant representing April.
+   */
+  public static final int APRIL = 3;
+
+  /**
+   * Constant representing May.
+   */
+  public static final int MAY = 4;
+
+  /**
+   * Constant representing June.
+   */
+  public static final int JUNE = 5;
+
+  /**
+   * Constant representing July.
+   */
+  public static final int JULY = 6;
+
+  /**
+   * Constant representing August.
+   */
+  public static final int AUGUST = 7;
+
+  /**
+   * Constant representing September.
+   */
+  public static final int SEPTEMBER = 8;
+
+  /**
+   * Constant representing October.
+   */
+  public static final int OCTOBER = 9;
+
+  /**
+   * Constant representing November.
+   */
+  public static final int NOVEMBER = 10;
+
+  /**
+   * Constant representing December.
+   */
+  public static final int DECEMBER = 11;
+
+  /**
+   * Constant representing Undecimber. This is an artificial name useful
+   * for lunar calendars.
+   */
+  public static final int UNDECIMBER = 12;
+
+  /**
+   * Useful constant for 12-hour clock.
+   */
+  public static final int AM = 0;
+
+  /**
+   * Useful constant for 12-hour clock.
+   */
+  public static final int PM = 1;
+
+  /**
+   * The time fields.  The array is indexed by the constants YEAR to
+   * DST_OFFSET.
+   * @serial
+   */
+  protected int[] fields = new int[FIELD_COUNT];
+
+  /**
+   * The flags which tell if the fields above have a value.
+   * @serial
+   */
+  protected boolean[] isSet = new boolean[FIELD_COUNT];
+
+  /**
+   * The time in milliseconds since the epoch.
+   * @serial
+   */
+  protected long time;
+
+  /**
+   * Tells if the above field has a valid value.
+   * @serial
+   */
+  protected boolean isTimeSet;
+
+  /**
+   * Tells if the fields have a valid value.  This superseeds the isSet
+   * array.
+   * @serial
+   */
+  protected boolean areFieldsSet;
+
+  /**
+   * The time zone of this calendar.  Used by sub classes to do UTC / local
+   * time conversion.  Sub classes can access this field with getTimeZone().
+   * @serial
+   */
+  private TimeZone zone;
+
+  /**
+   * Specifies if the date/time interpretation should be lenient.
+   * If the flag is set, a date such as "February 30, 1996" will be
+   * treated as the 29th day after the February 1.  If this flag
+   * is false, such dates will cause an exception.
+   * @serial
+   */
+  private boolean lenient;
+
+  /**
+   * Sets what the first day of week is.  This is used for
+   * WEEK_OF_MONTH and WEEK_OF_YEAR fields.
+   * @serial
+   */
+  private int firstDayOfWeek;
+
+  /**
+   * Sets how many days are required in the first week of the year.
+   * If the first day of the year should be the first week you should
+   * set this value to 1.  If the first week must be a full week, set
+   * it to 7.
+   * @serial
+   */
+  private int minimalDaysInFirstWeek;
+
+  /**
+   * Is set to true if DST_OFFSET is explicitly set. In that case
+   * it's value overrides the value computed from the current
+   * time and the timezone.
+   */
+  private boolean explicitDSTOffset = false;
+
+  /**
+   * The version of the serialized data on the stream.
+   * <dl><dt>0 or not present</dt>
+   * <dd> JDK 1.1.5 or later.</dd>
+   * <dt>1</dt>
+   * <dd>JDK 1.1.6 or later.  This always writes a correct `time' value
+   * on the stream, as well as the other fields, to be compatible with
+   * earlier versions</dd></dl>
+   * @since JDK1.1.6
+   * @serial
+   */
+  private int serialVersionOnStream = 1;
+
+  /**
+   * XXX - I have not checked the compatibility.  The documentation of
+   * the serialized-form is quite hairy...
+   */
+  static final long serialVersionUID = -1807547505821590642L;
+
+  /**
+   * The name of the resource bundle. Used only by getBundle()
+   */
+  private static final String bundleName = "gnu.java.locale.Calendar";
+
+  /**
+   * get resource bundle:
+   * The resources should be loaded via this method only. Iff an application
+   * uses this method, the resourcebundle is required.
+   */
+  private static ResourceBundle getBundle(Locale locale)
+  {
+    return ResourceBundle.getBundle(bundleName, locale,
+                                    ClassLoader.getSystemClassLoader());
+  }
+
+  /**
+   * Constructs a new Calendar with the default time zone and the default
+   * locale.
+   */
+  protected Calendar()
+  {
+    this(TimeZone.getDefault(), Locale.getDefault());
+  }
+
+  /**
+   * Constructs a new Calendar with the given time zone and the given
+   * locale.
+   * @param zone a time zone.
+   * @param locale a locale.
+   */
+  protected Calendar(TimeZone zone, Locale locale)
+  {
+    this.zone = zone;
+    lenient = true;
+
+    ResourceBundle rb = getBundle(locale);
+
+    firstDayOfWeek = ((Integer) rb.getObject("firstDayOfWeek")).intValue();
+    minimalDaysInFirstWeek = ((Integer) rb.getObject("minimalDaysInFirstWeek"))
+                             .intValue();
+    clear();
+  }
+
+  /**
+   * Creates a calendar representing the actual time, using the default
+   * time zone and locale.
+   */
+  public static synchronized Calendar getInstance()
+  {
+    return getInstance(TimeZone.getDefault(), Locale.getDefault());
+  }
+
+  /**
+   * Creates a calendar representing the actual time, using the given
+   * time zone and the default locale.
+   * @param zone a time zone.
+   */
+  public static synchronized Calendar getInstance(TimeZone zone)
+  {
+    return getInstance(zone, Locale.getDefault());
+  }
+
+  /**
+   * Creates a calendar representing the actual time, using the default
+   * time zone and the given locale.
+   * @param locale a locale.
+   */
+  public static synchronized Calendar getInstance(Locale locale)
+  {
+    return getInstance(TimeZone.getDefault(), locale);
+  }
+
+  /**
+   * Cache of locale->calendar-class mappings. This avoids having to do a ResourceBundle
+   * lookup for every getInstance call.
+   */
+  private static HashMap cache = new HashMap();
+
+  /** Preset argument types for calendar-class constructor lookup.  */
+  private static Class[] ctorArgTypes = new Class[]
+                                        {
+                                          TimeZone.class, Locale.class
+                                        };
+
+  /**
+   * Creates a calendar representing the actual time, using the given
+   * time zone and locale.
+   * @param zone a time zone.
+   * @param locale a locale.
+   */
+  public static synchronized Calendar getInstance(TimeZone zone, Locale locale)
+  {
+    Class calendarClass = (Class) cache.get(locale);
+    Throwable exception = null;
+
+    try
+      {
+	if (calendarClass == null)
+	  {
+	    ResourceBundle rb = getBundle(locale);
+	    String calendarClassName = rb.getString("calendarClass");
+
+	    if (calendarClassName != null)
+	      {
+		calendarClass = Class.forName(calendarClassName);
+		if (Calendar.class.isAssignableFrom(calendarClass))
+		  cache.put(locale, calendarClass);
+	      }
+	  }
+
+	// GregorianCalendar is by far the most common case. Optimize by 
+	// avoiding reflection.
+	if (calendarClass == GregorianCalendar.class)
+	  return new GregorianCalendar(zone, locale);
+
+	if (Calendar.class.isAssignableFrom(calendarClass))
+	  {
+	    Constructor ctor = calendarClass.getConstructor(ctorArgTypes);
+	    return (Calendar) ctor.newInstance(new Object[] { zone, locale });
+	  }
+      }
+    catch (ClassNotFoundException ex)
+      {
+	exception = ex;
+      }
+    catch (IllegalAccessException ex)
+      {
+	exception = ex;
+      }
+    catch (NoSuchMethodException ex)
+      {
+	exception = ex;
+      }
+    catch (InstantiationException ex)
+      {
+	exception = ex;
+      }
+    catch (InvocationTargetException ex)
+      {
+	exception = ex;
+      }
+
+    throw new RuntimeException("Error instantiating calendar for locale "
+                               + locale, exception);
+  }
+
+  /**
+   * Gets the set of locales for which a Calendar is available.
+   * @exception MissingResourceException if locale data couldn't be found.
+   * @return the set of locales.
+   */
+  public static synchronized Locale[] getAvailableLocales()
+  {
+    ResourceBundle rb = getBundle(new Locale("", ""));
+    return (Locale[]) rb.getObject("availableLocales");
+  }
+
+  /**
+   * Converts the time field values (<code>fields</code>) to
+   * milliseconds since the epoch UTC (<code>time</code>).  Override
+   * this method if you write your own Calendar.  */
+  protected abstract void computeTime();
+
+  /**
+   * Converts the milliseconds since the epoch UTC
+   * (<code>time</code>) to time fields
+   * (<code>fields</code>). Override this method if you write your
+   * own Calendar.
+   */
+  protected abstract void computeFields();
+
+  /**
+   * Converts the time represented by this object to a
+   * <code>Date</code>-Object.
+   * @return the Date.
+   */
+  public final Date getTime()
+  {
+    if (! isTimeSet)
+      computeTime();
+    return new Date(time);
+  }
+
+  /**
+   * Sets this Calendar's time to the given Date.  All time fields
+   * are invalidated by this method.
+   */
+  public final void setTime(Date date)
+  {
+    setTimeInMillis(date.getTime());
+  }
+
+  /**
+   * Returns the time represented by this Calendar.
+   * @return the time in milliseconds since the epoch.
+   * @specnote This was made public in 1.4.
+   */
+  public long getTimeInMillis()
+  {
+    if (! isTimeSet)
+      computeTime();
+    return time;
+  }
+
+  /**
+   * Sets this Calendar's time to the given Time.  All time fields
+   * are invalidated by this method.
+   * @param time the time in milliseconds since the epoch
+   * @specnote This was made public in 1.4.
+   */
+  public void setTimeInMillis(long time)
+  {
+    clear();
+    this.time = time;
+    isTimeSet = true;
+    computeFields();
+  }
+
+  /**
+   * Gets the value of the specified field.  They are recomputed
+   * if they are invalid.
+   * @param field the time field. One of the time field constants.
+   * @return the value of the specified field
+   * @throws ArrayIndexOutOfBoundsException if the field is outside
+   *         the valid range.  The value of field must be >= 0 and
+   *         <= <code>FIELD_COUNT</code>.
+   * @specnote Not final since JDK 1.4
+   */
+  public int get(int field)
+  {
+    // If the requested field is invalid, force all fields to be recomputed.
+    if (! isSet[field])
+      areFieldsSet = false;
+    complete();
+    return fields[field];
+  }
+
+  /**
+   * Gets the value of the specified field. This method doesn't
+   * recompute the fields, if they are invalid.
+   * @param field the time field. One of the time field constants.
+   * @return the value of the specified field, undefined if
+   * <code>areFieldsSet</code> or <code>isSet[field]</code> is false.
+   * @throws ArrayIndexOutOfBoundsException if the field is outside
+   *         the valid range.  The value of field must be >= 0 and
+   *         <= <code>FIELD_COUNT</code>.
+   */
+  protected final int internalGet(int field)
+  {
+    return fields[field];
+  }
+
+  /**
+   * Sets the time field with the given value.  This does invalidate
+   * the time in milliseconds.
+   * @param field the time field. One of the time field constants
+   * @param value the value to be set.
+   * @throws ArrayIndexOutOfBoundsException if field is outside
+   *         the valid range.  The value of field must be >= 0 and
+   *         <= <code>FIELD_COUNT</code>.
+   * @specnote Not final since JDK 1.4
+   */
+  public void set(int field, int value)
+  {
+    if (isTimeSet)
+      for (int i = 0; i < FIELD_COUNT; i++)
+	isSet[i] = false;
+    isTimeSet = false;
+    fields[field] = value;
+    isSet[field] = true;
+
+    // The five valid date patterns, in order of priority
+    // 1  YEAR + MONTH + DAY_OF_MONTH
+    // 2  YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
+    // 3  YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
+    // 4  YEAR + DAY_OF_YEAR
+    // 5  YEAR + DAY_OF_WEEK + WEEK_OF_YEAR
+    switch (field)
+      {
+      case MONTH: // pattern 1,2 or 3
+	isSet[DAY_OF_YEAR] = false;
+	isSet[WEEK_OF_YEAR] = false;
+	break;
+      case DAY_OF_MONTH: // pattern 1
+	isSet[YEAR] = true;
+	isSet[MONTH] = true;
+	isSet[WEEK_OF_MONTH] = true;
+	isSet[DAY_OF_WEEK] = false;
+	isSet[DAY_OF_WEEK_IN_MONTH] = false;
+	isSet[DAY_OF_YEAR] = false;
+	isSet[WEEK_OF_YEAR] = false;
+	break;
+      case WEEK_OF_MONTH: // pattern 2
+	if (! isSet[DAY_OF_WEEK])
+	  fields[DAY_OF_WEEK] = getFirstDayOfWeek();
+	isSet[YEAR] = true;
+	isSet[MONTH] = true;
+	isSet[DAY_OF_WEEK] = true;
+	isSet[DAY_OF_MONTH] = false;
+	isSet[DAY_OF_WEEK_IN_MONTH] = false;
+	isSet[DAY_OF_YEAR] = false;
+	isSet[WEEK_OF_YEAR] = false;
+	break;
+      case DAY_OF_WEEK_IN_MONTH: // pattern 3
+	if (! isSet[DAY_OF_WEEK])
+	  fields[DAY_OF_WEEK] = getFirstDayOfWeek();
+	isSet[YEAR] = true;
+	isSet[MONTH] = true;
+	isSet[DAY_OF_WEEK] = true;
+	isSet[DAY_OF_YEAR] = false;
+	isSet[DAY_OF_MONTH] = false;
+	isSet[WEEK_OF_MONTH] = false;
+	isSet[WEEK_OF_YEAR] = false;
+	break;
+      case DAY_OF_YEAR: // pattern 4
+	isSet[YEAR] = true;
+	isSet[MONTH] = false;
+	isSet[WEEK_OF_MONTH] = false;
+	isSet[DAY_OF_MONTH] = false;
+	isSet[DAY_OF_WEEK] = false;
+	isSet[WEEK_OF_YEAR] = false;
+	isSet[DAY_OF_WEEK_IN_MONTH] = false;
+	break;
+      case WEEK_OF_YEAR: // pattern 5
+	if (! isSet[DAY_OF_WEEK])
+	  fields[DAY_OF_WEEK] = getFirstDayOfWeek();
+	isSet[YEAR] = true;
+	isSet[DAY_OF_WEEK] = true;
+	isSet[MONTH] = false;
+	isSet[DAY_OF_MONTH] = false;
+	isSet[WEEK_OF_MONTH] = false;
+	isSet[DAY_OF_YEAR] = false;
+	isSet[DAY_OF_WEEK_IN_MONTH] = false;
+	break;
+      case AM_PM:
+	isSet[HOUR] = true;
+	isSet[HOUR_OF_DAY] = false;
+	break;
+      case HOUR_OF_DAY:
+	isSet[AM_PM] = false;
+	isSet[HOUR] = false;
+	break;
+      case HOUR:
+	isSet[AM_PM] = true;
+	isSet[HOUR_OF_DAY] = false;
+	break;
+      case DST_OFFSET:
+	explicitDSTOffset = true;
+      }
+
+    // May have crossed over a DST boundary.
+    if (! explicitDSTOffset && (field != DST_OFFSET && field != ZONE_OFFSET))
+      isSet[DST_OFFSET] = false;
+  }
+
+  /**
+   * Sets the fields for year, month, and date
+   * @param year the year.
+   * @param month the month, one of the constants JANUARY..UNDICEMBER.
+   * @param date the day of the month
+   */
+  public final void set(int year, int month, int date)
+  {
+    isTimeSet = false;
+    fields[YEAR] = year;
+    fields[MONTH] = month;
+    fields[DATE] = date;
+    isSet[YEAR] = isSet[MONTH] = isSet[DATE] = true;
+    isSet[WEEK_OF_YEAR] = false;
+    isSet[DAY_OF_YEAR] = false;
+    isSet[WEEK_OF_MONTH] = false;
+    isSet[DAY_OF_WEEK] = false;
+    isSet[DAY_OF_WEEK_IN_MONTH] = false;
+    isSet[ERA] = false;
+
+    if (! explicitDSTOffset)
+      isSet[DST_OFFSET] = false; // May have crossed a DST boundary.
+  }
+
+  /**
+   * Sets the fields for year, month, date, hour, and minute
+   * @param year the year.
+   * @param month the month, one of the constants JANUARY..UNDICEMBER.
+   * @param date the day of the month
+   * @param hour the hour of day.
+   * @param minute the minute.
+   */
+  public final void set(int year, int month, int date, int hour, int minute)
+  {
+    set(year, month, date);
+    fields[HOUR_OF_DAY] = hour;
+    fields[MINUTE] = minute;
+    isSet[HOUR_OF_DAY] = isSet[MINUTE] = true;
+    isSet[AM_PM] = false;
+    isSet[HOUR] = false;
+  }
+
+  /**
+   * Sets the fields for year, month, date, hour, and minute
+   * @param year the year.
+   * @param month the month, one of the constants JANUARY..UNDICEMBER.
+   * @param date the day of the month
+   * @param hour the hour of day.
+   * @param minute the minute.
+   * @param second the second.
+   */
+  public final void set(int year, int month, int date, int hour, int minute,
+                        int second)
+  {
+    set(year, month, date, hour, minute);
+    fields[SECOND] = second;
+    isSet[SECOND] = true;
+  }
+
+  /**
+   * Clears the values of all the time fields.
+   */
+  public final void clear()
+  {
+    isTimeSet = false;
+    areFieldsSet = false;
+    int zoneOffs = zone.getRawOffset();
+    int[] tempFields = 
+                       {
+                         1, 1970, JANUARY, 1, 1, 1, 1, THURSDAY, 1, AM, 0, 0, 0,
+                         0, 0, zoneOffs, 0
+                       };
+    fields = tempFields;
+    for (int i = 0; i < FIELD_COUNT; i++)
+      isSet[i] = false;
+  }
+
+  /**
+   * Clears the values of the specified time field.
+   * @param field the time field. One of the time field constants.
+   * @throws ArrayIndexOutOfBoundsException if field is outside
+   *         the valid range.  The value of field must be >= 0 and
+   *         <= <code>FIELD_COUNT</code>.
+   */
+  public final void clear(int field)
+  {
+    int[] tempFields = 
+                       {
+                         1, 1970, JANUARY, 1, 1, 1, 1, THURSDAY, 1, AM, 0, 0, 0,
+                         0, 0, zone.getRawOffset(), 0
+                       };
+    isTimeSet = false;
+    areFieldsSet = false;
+    isSet[field] = false;
+    fields[field] = tempFields[field];
+  }
+
+  /**
+   * Determines if the specified field has a valid value.
+   * @return true if the specified field has a value.
+   * @throws ArrayIndexOutOfBoundsException if the field is outside
+   *         the valid range.  The value of field must be >= 0 and
+   *         <= <code>FIELD_COUNT</code>.
+   */
+  public final boolean isSet(int field)
+  {
+    return isSet[field];
+  }
+
+  /**
+   * Fills any unset fields in the time field list
+   */
+  protected void complete()
+  {
+    if (! isTimeSet)
+      computeTime();
+    if (! areFieldsSet)
+      computeFields();
+  }
+
+  /**
+   * Compares the given calendar with this.
+   * @param o the object to that we should compare.
+   * @return true, if the given object is a calendar, that represents
+   * the same time (but doesn't necessary have the same fields).
+   */
+  public boolean equals(Object o)
+  {
+    if (! (o instanceof Calendar))
+      return false;
+    Calendar cal = (Calendar) o;
+    if (getTimeInMillis() == ((Calendar) o).getTimeInMillis()
+        && cal.getFirstDayOfWeek() == getFirstDayOfWeek()
+        && cal.isLenient() == isLenient()
+        && cal.getMinimalDaysInFirstWeek() == getMinimalDaysInFirstWeek())
+      {
+        TimeZone self = getTimeZone();
+        TimeZone oth = cal.getTimeZone();
+        return self == null ? oth == null : self.equals(oth);
+      }
+    return false;
+  }
+
+  /**
+   * Returns a hash code for this calendar.
+   * @return a hash code, which fullfits the general contract of
+   * <code>hashCode()</code>
+   */
+  public int hashCode()
+  {
+    long time = getTimeInMillis();
+    int val = (int) ((time & 0xffffffffL) ^ (time >> 32));
+    val += (getFirstDayOfWeek() + (isLenient() ? 1230 : 1237)
+            + getMinimalDaysInFirstWeek());
+    TimeZone self = getTimeZone();
+    if (self != null)
+      val ^= self.hashCode();
+    return val;
+  }
+
+  /**
+   * Compares the given calendar with this.
+   * @param o the object to that we should compare.
+   * @return true, if the given object is a calendar, and this calendar
+   * represents a smaller time than the calendar o.
+   * @exception ClassCastException if o is not an calendar.
+   * @since JDK1.2 you don't need to override this method
+   */
+  public boolean before(Object o)
+  {
+    return getTimeInMillis() < ((Calendar) o).getTimeInMillis();
+  }
+
+  /**
+   * Compares the given calendar with this.
+   * @param o the object to that we should compare.
+   * @return true, if the given object is a calendar, and this calendar
+   * represents a bigger time than the calendar o.
+   * @exception ClassCastException if o is not an calendar.
+   * @since JDK1.2 you don't need to override this method
+   */
+  public boolean after(Object o)
+  {
+    return getTimeInMillis() > ((Calendar) o).getTimeInMillis();
+  }
+
+  /**
+   * Adds the specified amount of time to the given time field.  The
+   * amount may be negative to subtract the time.  If the field overflows
+   * it does what you expect: Jan, 25 + 10 Days is Feb, 4.
+   * @param field the time field. One of the time field constants.
+   * @param amount the amount of time.
+   * @throws ArrayIndexOutOfBoundsException if the field is outside
+   *         the valid range.  The value of field must be >= 0 and
+   *         <= <code>FIELD_COUNT</code>.
+   */
+  public abstract void add(int field, int amount);
+
+  /**
+   * Rolls the specified time field up or down.  This means add one
+   * to the specified field, but don't change the other fields.  If
+   * the maximum for this field is reached, start over with the
+   * minimum value.  <br>
+   *
+   * <strong>Note:</strong> There may be situation, where the other
+   * fields must be changed, e.g rolling the month on May, 31.
+   * The date June, 31 is automatically converted to July, 1.
+   * @param field the time field. One of the time field constants.
+   * @param up the direction, true for up, false for down.
+   * @throws ArrayIndexOutOfBoundsException if the field is outside
+   *         the valid range.  The value of field must be >= 0 and
+   *         <= <code>FIELD_COUNT</code>.
+   */
+  public abstract void roll(int field, boolean up);
+
+  /**
+   * Rolls up or down the specified time field by the given amount.
+   * A negative amount rolls down.  The default implementation is
+   * call <code>roll(int, boolean)</code> for the specified amount.
+   *
+   * Subclasses should override this method to do more intuitiv things.
+   *
+   * @param field the time field. One of the time field constants.
+   * @param amount the amount to roll by, positive for rolling up,
+   * negative for rolling down.
+   * @throws ArrayIndexOutOfBoundsException if the field is outside
+   *         the valid range.  The value of field must be >= 0 and
+   *         <= <code>FIELD_COUNT</code>.
+   * @since JDK1.2
+   */
+  public void roll(int field, int amount)
+  {
+    while (amount > 0)
+      {
+	roll(field, true);
+	amount--;
+      }
+    while (amount < 0)
+      {
+	roll(field, false);
+	amount++;
+      }
+  }
+
+  /**
+   * Sets the time zone to the specified value.
+   * @param zone the new time zone
+   */
+  public void setTimeZone(TimeZone zone)
+  {
+    this.zone = zone;
+  }
+
+  /**
+   * Gets the time zone of this calendar
+   * @return the current time zone.
+   */
+  public TimeZone getTimeZone()
+  {
+    return zone;
+  }
+
+  /**
+   * Specifies if the date/time interpretation should be lenient.
+   * If the flag is set, a date such as "February 30, 1996" will be
+   * treated as the 29th day after the February 1.  If this flag
+   * is false, such dates will cause an exception.
+   * @param lenient true, if the date should be interpreted linient,
+   * false if it should be interpreted strict.
+   */
+  public void setLenient(boolean lenient)
+  {
+    this.lenient = lenient;
+  }
+
+  /**
+   * Tells if the date/time interpretation is lenient.
+   * @return true, if the date should be interpreted linient,
+   * false if it should be interpreted strict.
+   */
+  public boolean isLenient()
+  {
+    return lenient;
+  }
+
+  /**
+   * Sets what the first day of week is.  This is used for
+   * WEEK_OF_MONTH and WEEK_OF_YEAR fields.
+   * @param value the first day of week.  One of SUNDAY to SATURDAY.
+   */
+  public void setFirstDayOfWeek(int value)
+  {
+    firstDayOfWeek = value;
+  }
+
+  /**
+   * Gets what the first day of week is.  This is used for
+   * WEEK_OF_MONTH and WEEK_OF_YEAR fields.
+   * @return the first day of week.  One of SUNDAY to SATURDAY.
+   */
+  public int getFirstDayOfWeek()
+  {
+    return firstDayOfWeek;
+  }
+
+  /**
+   * Sets how many days are required in the first week of the year.
+   * If the first day of the year should be the first week you should
+   * set this value to 1.  If the first week must be a full week, set
+   * it to 7.
+   * @param value the minimal days required in the first week.
+   */
+  public void setMinimalDaysInFirstWeek(int value)
+  {
+    minimalDaysInFirstWeek = value;
+  }
+
+  /**
+   * Gets how many days are required in the first week of the year.
+   * @return the minimal days required in the first week.
+   * @see #setMinimalDaysInFirstWeek
+   */
+  public int getMinimalDaysInFirstWeek()
+  {
+    return minimalDaysInFirstWeek;
+  }
+
+  /**
+   * Gets the smallest value that is allowed for the specified field.
+   * @param field the time field. One of the time field constants.
+   * @return the smallest value.
+   */
+  public abstract int getMinimum(int field);
+
+  /**
+   * Gets the biggest value that is allowed for the specified field.
+   * @param field the time field. One of the time field constants.
+   * @return the biggest value.
+   */
+  public abstract int getMaximum(int field);
+
+  /**
+   * Gets the greatest minimum value that is allowed for the specified field.
+   * @param field the time field. One of the time field constants.
+   * @return the greatest minimum value.
+   */
+  public abstract int getGreatestMinimum(int field);
+
+  /**
+   * Gets the smallest maximum value that is allowed for the
+   * specified field.  For example this is 28 for DAY_OF_MONTH.
+   * @param field the time field. One of the time field constants.
+   * @return the least maximum value.
+   */
+  public abstract int getLeastMaximum(int field);
+
+  /**
+   * Gets the actual minimum value that is allowed for the specified field.
+   * This value is dependent on the values of the other fields.
+   * @param field the time field. One of the time field constants.
+   * @return the actual minimum value.
+   * @throws ArrayIndexOutOfBoundsException if the field is outside
+   *         the valid range.  The value of field must be >= 0 and
+   *         <= <code>FIELD_COUNT</code>.
+   * @since jdk1.2
+   */
+  public int getActualMinimum(int field)
+  {
+    Calendar tmp = (Calendar) clone(); // To avoid restoring state
+    int min = tmp.getGreatestMinimum(field);
+    int end = tmp.getMinimum(field);
+    tmp.set(field, min);
+    for (; min > end; min--)
+      {
+	tmp.add(field, -1); // Try to get smaller
+	if (tmp.get(field) != min - 1)
+	  break; // Done if not successful
+      }
+    return min;
+  }
+
+  /**
+   * Gets the actual maximum value that is allowed for the specified field.
+   * This value is dependent on the values of the other fields.
+   * @param field the time field. One of the time field constants.
+   * @return the actual maximum value.
+   * @throws ArrayIndexOutOfBoundsException if the field is outside
+   *         the valid range.  The value of field must be >= 0 and
+   *         <= <code>FIELD_COUNT</code>.
+   * @since jdk1.2
+   */
+  public int getActualMaximum(int field)
+  {
+    Calendar tmp = (Calendar) clone(); // To avoid restoring state
+    int max = tmp.getLeastMaximum(field);
+    int end = tmp.getMaximum(field);
+    tmp.set(field, max);
+    for (; max < end; max++)
+      {
+	tmp.add(field, 1);
+	if (tmp.get(field) != max + 1)
+	  break;
+      }
+    return max;
+  }
+
+  /**
+   * Return a clone of this object.
+   */
+  public Object clone()
+  {
+    try
+      {
+	Calendar cal = (Calendar) super.clone();
+	cal.fields = (int[]) fields.clone();
+	cal.isSet = (boolean[]) isSet.clone();
+	return cal;
+      }
+    catch (CloneNotSupportedException ex)
+      {
+	return null;
+      }
+  }
+
+  private static final String[] fieldNames = 
+                                             {
+                                               ",ERA=", ",YEAR=", ",MONTH=",
+                                               ",WEEK_OF_YEAR=",
+                                               ",WEEK_OF_MONTH=",
+                                               ",DAY_OF_MONTH=",
+                                               ",DAY_OF_YEAR=", ",DAY_OF_WEEK=",
+                                               ",DAY_OF_WEEK_IN_MONTH=",
+                                               ",AM_PM=", ",HOUR=",
+                                               ",HOUR_OF_DAY=", ",MINUTE=",
+                                               ",SECOND=", ",MILLISECOND=",
+                                               ",ZONE_OFFSET=", ",DST_OFFSET="
+                                             };
+
+  /**
+   * Returns a string representation of this object.  It is mainly
+   * for debugging purposes and its content is implementation
+   * specific.
+   */
+  public String toString()
+  {
+    StringBuffer sb = new StringBuffer();
+    sb.append(getClass().getName()).append('[');
+    sb.append("time=");
+    if (isTimeSet)
+      sb.append(time);
+    else
+      sb.append("?");
+    sb.append(",zone=" + zone);
+    sb.append(",areFieldsSet=" + areFieldsSet);
+    for (int i = 0; i < FIELD_COUNT; i++)
+      {
+	sb.append(fieldNames[i]);
+	if (isSet[i])
+	  sb.append(fields[i]);
+	else
+	  sb.append("?");
+      }
+    sb.append(",lenient=").append(lenient);
+    sb.append(",firstDayOfWeek=").append(firstDayOfWeek);
+    sb.append(",minimalDaysInFirstWeek=").append(minimalDaysInFirstWeek);
+    sb.append("]");
+    return sb.toString();
+  }
+
+  /**
+   * Saves the state of the object to the stream.  Ideally we would
+   * only write the time field, but we need to be compatible with
+   * earlier versions. <br>
+   *
+   * This doesn't write the JDK1.1 field nextStamp to the stream, as
+   * I don't know what it is good for, and because the documentation
+   * says, that it could be omitted.  */
+  private void writeObject(ObjectOutputStream stream) throws IOException
+  {
+    if (! isTimeSet)
+      computeTime();
+    stream.defaultWriteObject();
+  }
+
+  /**
+   * Reads the object back from stream (deserialization).
+   */
+  private void readObject(ObjectInputStream stream)
+    throws IOException, ClassNotFoundException
+  {
+    stream.defaultReadObject();
+    if (! isTimeSet)
+      computeTime();
+
+    if (serialVersionOnStream > 1)
+      {
+	// This is my interpretation of the serial number:
+	// Sun wants to remove all fields from the stream someday
+	// and will then increase the serialVersion number again.
+	// We prepare to be compatible.
+	fields = new int[FIELD_COUNT];
+	isSet = new boolean[FIELD_COUNT];
+	areFieldsSet = false;
+      }
+  }
+}





More information about the llvm-commits mailing list