diff options
author | Tom Tromey <tromey@gcc.gnu.org> | 2005-07-16 00:31:27 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2005-07-16 00:31:27 +0000 |
commit | 37d375fdc5fd13db547fb60bdd40b73355396587 (patch) | |
tree | ed80c7de91726768a42b235beffbaf622dc2553e /libjava/classpath | |
parent | f911ba985aa7fe0096c386c5be385ac5825ea527 (diff) | |
download | gcc-37d375fdc5fd13db547fb60bdd40b73355396587.zip gcc-37d375fdc5fd13db547fb60bdd40b73355396587.tar.gz gcc-37d375fdc5fd13db547fb60bdd40b73355396587.tar.bz2 |
Initial revision
From-SVN: r102075
Diffstat (limited to 'libjava/classpath')
32 files changed, 5340 insertions, 0 deletions
diff --git a/libjava/classpath/vm/.cvsignore b/libjava/classpath/vm/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/libjava/classpath/vm/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/libjava/classpath/vm/Makefile.am b/libjava/classpath/vm/Makefile.am new file mode 100644 index 0000000..d89e468 --- /dev/null +++ b/libjava/classpath/vm/Makefile.am @@ -0,0 +1,4 @@ +# used by automake to generate Makefile.in + + +SUBDIRS = reference diff --git a/libjava/classpath/vm/reference/.cvsignore b/libjava/classpath/vm/reference/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/libjava/classpath/vm/reference/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/libjava/classpath/vm/reference/Makefile.am b/libjava/classpath/vm/reference/Makefile.am new file mode 100644 index 0000000..84b0350 --- /dev/null +++ b/libjava/classpath/vm/reference/Makefile.am @@ -0,0 +1,3 @@ +# used by automake to generate Makefile.in + +SUBDIRS = java gnu diff --git a/libjava/classpath/vm/reference/gnu/classpath/VMStackWalker.java b/libjava/classpath/vm/reference/gnu/classpath/VMStackWalker.java new file mode 100644 index 0000000..28e4ce3 --- /dev/null +++ b/libjava/classpath/vm/reference/gnu/classpath/VMStackWalker.java @@ -0,0 +1,108 @@ +/* VMStackWalker.java -- Reference implementation of VM hooks for stack access + Copyright (C) 2005 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.classpath; + +/** + * This class provides access to the classes on the Java stack + * for reflection and security purposes. + * + * <p> + * This class is only available to privileged code (i.e., code loaded + * by the bootstrap loader). + * + * @author John Keiser + * @author Eric Blake <ebb9@email.byu.edu> + * @author Archie Cobbs + */ +public final class VMStackWalker +{ + /** + * Get a list of all the classes currently executing methods on the + * Java stack. <code>getClassContext()[0]</code> is the class associated + * with the currently executing method, i.e., the method that called + * <code>VMStackWalker.getClassContext()</code> (possibly through + * reflection). So you may need to pop off these stack frames from + * the top of the stack: + * <ul> + * <li><code>VMStackWalker.getClassContext()</code> + * <li><code>Method.invoke()</code> + * </ul> + * + * @return an array of the declaring classes of each stack frame + */ + public static native Class[] getClassContext(); + + /** + * Get the class associated with the method invoking the method + * invoking this method, or <code>null</code> if the stack is not + * that deep (e.g., invoked via JNI invocation API). This method + * is an optimization for the expression <code>getClassContext()[1]</code> + * and should return the same result. + * + * <p> + * VM implementers are encouraged to provide a more efficient + * version of this method. + */ + public static Class getCallingClass() + { + Class[] ctx = getClassContext(); + if (ctx.length < 3) + return null; + return ctx[2]; + } + + /** + * Get the class loader associated with the Class returned by + * <code>getCallingClass()</code>, or <code>null</code> if no + * such class exists or it is the boot loader. This method is an optimization + * for the expression <code>getClassContext()[1].getClassLoader()</code> + * and should return the same result. + * + * <p> + * VM implementers are encouraged to provide a more efficient + * version of this method. + */ + public static ClassLoader getCallingClassLoader() + { + Class[] ctx = getClassContext(); + if (ctx.length < 3) + return null; + return ctx[2].getClassLoader(); + } +} + diff --git a/libjava/classpath/vm/reference/gnu/classpath/VMSystemProperties.java b/libjava/classpath/vm/reference/gnu/classpath/VMSystemProperties.java new file mode 100644 index 0000000..e7cb91f --- /dev/null +++ b/libjava/classpath/vm/reference/gnu/classpath/VMSystemProperties.java @@ -0,0 +1,97 @@ +/* VMSystemProperties.java -- Allow the VM to set System properties. + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.classpath; + +import java.util.Properties; + +class VMSystemProperties +{ + /** + * Get the system properties. This is done here, instead of in System, + * because of the bootstrap sequence. Note that the native code should + * not try to use the Java I/O classes yet, as they rely on the properties + * already existing. The only safe method to use to insert these default + * system properties is {@link Properties#setProperty(String, String)}. + * + * <p>These properties MUST include: + * <dl> + * <dt>java.version <dd>Java version number + * <dt>java.vendor <dd>Java vendor specific string + * <dt>java.vendor.url <dd>Java vendor URL + * <dt>java.home <dd>Java installation directory + * <dt>java.vm.specification.version <dd>VM Spec version + * <dt>java.vm.specification.vendor <dd>VM Spec vendor + * <dt>java.vm.specification.name <dd>VM Spec name + * <dt>java.vm.version <dd>VM implementation version + * <dt>java.vm.vendor <dd>VM implementation vendor + * <dt>java.vm.name <dd>VM implementation name + * <dt>java.specification.version <dd>Java Runtime Environment version + * <dt>java.specification.vendor <dd>Java Runtime Environment vendor + * <dt>java.specification.name <dd>Java Runtime Environment name + * <dt>java.class.version <dd>Java class version number + * <dt>java.class.path <dd>Java classpath + * <dt>java.library.path <dd>Path for finding Java libraries + * <dt>java.io.tmpdir <dd>Default temp file path + * <dt>java.compiler <dd>Name of JIT to use + * <dt>java.ext.dirs <dd>Java extension path + * <dt>os.name <dd>Operating System Name + * <dt>os.arch <dd>Operating System Architecture + * <dt>os.version <dd>Operating System Version + * <dt>file.separator <dd>File separator ("/" on Unix) + * <dt>path.separator <dd>Path separator (":" on Unix) + * <dt>line.separator <dd>Line separator ("\n" on Unix) + * <dt>user.name <dd>User account name + * <dt>user.home <dd>User home directory + * <dt>user.dir <dd>User's current working directory + * <dt>gnu.cpu.endian <dd>"big" or "little" + * </dl> + * + * @param p the Properties object to insert the system properties into + */ + static native void preInit(Properties properties); + + /** + * Here you get a chance to overwrite some of the properties set by + * the common SystemProperties code. For example, it might be + * a good idea to process the properties specified on the command + * line here. + */ + static void postInit(Properties properties) + { + } +} diff --git a/libjava/classpath/vm/reference/gnu/java/nio/VMPipe.java b/libjava/classpath/vm/reference/gnu/java/nio/VMPipe.java new file mode 100644 index 0000000..11dd2aa --- /dev/null +++ b/libjava/classpath/vm/reference/gnu/java/nio/VMPipe.java @@ -0,0 +1,64 @@ +/* VMPipe.java -- Reference implementation for VM hooks used by PipeImpl + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.nio; + +import java.io.IOException; +import java.nio.channels.spi.SelectorProvider; +import gnu.classpath.Configuration; + +/** + * This class contains the native methods for gnu.java.nio.PipeImpl + * As such, it needs help from the VM. + * + * @author Patrik Reali + */ +final class VMPipe +{ + + static + { + // load the shared library needed for native methods. + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary ("javanio"); + } + } + + static native void init(PipeImpl self, SelectorProvider provider) + throws IOException; +} diff --git a/libjava/classpath/vm/reference/gnu/java/nio/VMSelector.java b/libjava/classpath/vm/reference/gnu/java/nio/VMSelector.java new file mode 100644 index 0000000..488132d --- /dev/null +++ b/libjava/classpath/vm/reference/gnu/java/nio/VMSelector.java @@ -0,0 +1,59 @@ +/* VMSelector.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.nio; + +import gnu.classpath.Configuration; +import java.io.IOException; + +public final class VMSelector +{ + static + { + // load the shared library needed for native methods. + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary ("javanio"); + } + } + + // A timeout value of 0 means block forever. + static native int select (int[] read, int[] write, + int[] except, long timeout) + throws IOException; + +} diff --git a/libjava/classpath/vm/reference/java/io/VMFile.java b/libjava/classpath/vm/reference/java/io/VMFile.java new file mode 100644 index 0000000..2931044 --- /dev/null +++ b/libjava/classpath/vm/reference/java/io/VMFile.java @@ -0,0 +1,229 @@ +/* VMFile.java -- Class for methods natively accessing files + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.io; + +import gnu.classpath.Configuration; +import gnu.java.io.PlatformHelper; + + +/** + * @author Michael Koch (konqueror@gmx.de) + */ +final class VMFile +{ + // FIXME: We support only case sensitive filesystems currently. + static final boolean IS_CASE_SENSITIVE = true; + static final boolean IS_DOS_8_3 = false; + + static + { + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary("javaio"); + } + } + + /* + * This native method does the actual work of getting the last file + * modification time. It also does the existence check to avoid the + * overhead of a call to exists() + */ + static native long lastModified(String path); + + /* + * This native method sets the permissions to make the file read only. + */ + static native boolean setReadOnly(String path); + + /** + * This method is used to create a temporary file + */ + static native boolean create(String path) throws IOException; + + /* + * This native function actually produces the list of file in this + * directory + */ + static native String[] list(String dirpath); + + /* + * This native method actually performs the rename. + */ + static native boolean renameTo(String targetpath, String destpath); + + /* + * This native method actually determines the length of the file and + * handles the existence check + */ + static native long length(String path); + + /* + * This native method does the actual checking of file existence. + */ + static native boolean exists(String path); + + /* + * This native method handles the actual deleting of the file + */ + static native boolean delete(String path); + + /* + * This method does the actual setting of the modification time. + */ + static native boolean setLastModified(String path, long time); + + /* + * This native method actually creates the directory + */ + static native boolean mkdir(String dirpath); + + /* + * This native method does the actual check of whether or not a file + * is a plain file or not. It also handles the existence check to + * eliminate the overhead of a call to exists() + */ + static native boolean isFile(String path); + + /** + * This native method checks file permissions for writing + */ + static synchronized native boolean canWrite(String path); + + /** + * This methods checks if a directory can be written to. + */ + static boolean canWriteDirectory(File dir) + { + try + { + String filename = IS_DOS_8_3 ? "tst" : "test-dir-write"; + File test = File.createTempFile(filename, null, dir); + return (test != null && test.delete()); + } + catch (IOException ioe) + { + return false; + } + } + + /** + * This native method checks file permissions for reading + */ + static synchronized native boolean canRead(String path); + + /* + * This method does the actual check of whether or not a file is a + * directory or not. It also handle the existence check to eliminate + * the overhead of a call to exists() + */ + static native boolean isDirectory(String dirpath); + + /** + * This method returns an array of filesystem roots. Some operating systems + * have volume oriented filesystem. This method provides a mechanism for + * determining which volumes exist. GNU systems use a single hierarchical + * filesystem, so will have only one "/" filesystem root. + * + * @return An array of <code>File</code> objects for each filesystem root + * available. + * + * @since 1.2 + */ + static File[] listRoots() + { + File[] roots = new File[1]; + roots[0] = new File("/"); + return roots; + } + + /** + * This method tests whether or not this file represents a "hidden" file. + * On GNU systems, a file is hidden if its name begins with a "." + * character. Files with these names are traditionally not shown with + * directory listing tools. + * + * @return <code>true</code> if the file is hidden, <code>false</code> + * otherwise. + * + * @since 1.2 + */ + static boolean isHidden(String path) + { + // FIXME: this only works on UNIX + return getName(path).startsWith("."); + } + + /** + * This method returns the name of the file. This is everything in the + * complete path of the file after the last instance of the separator + * string. + * + * @return The file name + */ + static String getName(String path) + { + int pos = PlatformHelper.lastIndexOfSeparator(path); + if (pos == -1) + return path; + + if (PlatformHelper.endWithSeparator(path)) + return ""; + + return path.substring(pos + File.separator.length()); + } + + /** + * This method returns a canonical representation of the pathname of + * the given path. The actual form of the canonical representation is + * different. On the GNU system, the canonical form differs from the + * absolute form in that all relative file references to "." and ".." + * are resolved and removed. + * <p> + * Note that this method, unlike the other methods which return path + * names, can throw an IOException. This is because native method + * might be required in order to resolve the canonical path + * + * @exception IOException If an error occurs + */ + public static String toCanonicalForm(String path) throws IOException + { + // FIXME: this only works on UNIX + return PlatformHelper.toCanonicalForm(path); + } +} diff --git a/libjava/classpath/vm/reference/java/io/VMObjectInputStream.java b/libjava/classpath/vm/reference/java/io/VMObjectInputStream.java new file mode 100644 index 0000000..7cd9719 --- /dev/null +++ b/libjava/classpath/vm/reference/java/io/VMObjectInputStream.java @@ -0,0 +1,86 @@ +/* ObjectInputStream.java -- Class used to read serialized objects + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 + Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.io; + +import gnu.classpath.VMStackWalker; +import java.lang.reflect.Constructor; +import java.security.AccessController; +import java.security.PrivilegedAction; + +final class VMObjectInputStream +{ + private static Class oisClass = ObjectInputStream.class; + private static Class vmoisClass = VMObjectInputStream.class; + + // PrivilegedAction needed for Class.getClassLoader() + private static PrivilegedAction loaderAction = new PrivilegedAction() + { + public Object run() + { + Class[] ctx = VMStackWalker.getClassContext(); + for (int i = 0; i < ctx.length; i++) + { + ClassLoader cl = ctx[i].getClassLoader(); + if (cl != null) + return cl; + } + return null; + } + }; + + /** + * Returns the first user defined class loader on the call stack, or + * null when no non-null class loader was found. + */ + static ClassLoader currentClassLoader() + { + return (ClassLoader) AccessController.doPrivileged(loaderAction); + } + + /** + * Allocates a new Object of type clazz but without running the + * default constructor on it. It then calls the given constructor on + * it. The given constructor method comes from the constr_clazz + * which is a super class of the given clazz. + */ + static native Object allocateObject(Class clazz, Class constr_clazz, + Constructor constructor) + throws InstantiationException; +} diff --git a/libjava/classpath/vm/reference/java/io/VMObjectStreamClass.java b/libjava/classpath/vm/reference/java/io/VMObjectStreamClass.java new file mode 100644 index 0000000..2aee7a9 --- /dev/null +++ b/libjava/classpath/vm/reference/java/io/VMObjectStreamClass.java @@ -0,0 +1,160 @@ +/* VMObjectStreamClass.java -- VM helper functions for ObjectStreamClass + Copyright (C) 2003 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.io; + +import java.lang.reflect.Field; + +final class VMObjectStreamClass +{ + /** + * Returns true if CLAZZ has a static class initializer + * (a.k.a. <clinit>). + */ + static native boolean hasClassInitializer (Class clazz); + + /** + * Sets the value of the specified field. This method handles "double". + * Warning ! The types are not truely checked here and final values may be + * assigned. + * + * @param field Field to set the value. + * @param obj Instance which will have its field set. + * @param val Value to put in the field. + */ + static native void setDoubleNative(Field field, Object obj, double val) + throws InternalError; + + /** + * Sets the value of the specified field. This method handles "float". + * Warning ! The types are not truely checked here and final values may be + * assigned. + * + * @param field Field to set the value. + * @param obj Instance which will have its field set. + * @param val Value to put in the field. + */ + static native void setFloatNative(Field field, Object obj, float val) + throws InternalError; + + /** + * Sets the value of the specified field. This method handles "long". + * Warning ! The types are not truely checked here and final values may be + * assigned. + * + * @param field Field to set the value. + * @param obj Instance which will have its field set. + * @param val Value to put in the field. + */ + static native void setLongNative(Field field, Object obj, long val) + throws InternalError; + + /** + * Sets the value of the specified field. This method handles "int". + * Warning ! The types are not truely checked here and final values may be + * assigned. + * + * @param field Field to set the value. + * @param obj Instance which will have its field set. + * @param val Value to put in the field. + */ + static native void setIntNative(Field field, Object obj, int val) + throws InternalError; + + /** + * Sets the value of the specified field. This method handles "short". + * Warning ! The types are not truely checked here and final values may be + * assigned. + * + * @param field Field to set the value. + * @param obj Instance which will have its field set. + * @param val Value to put in the field. + */ + static native void setShortNative(Field field, Object obj, short val) + throws InternalError; + + /** + * Sets the value of the specified field. This method handles "char". + * Warning ! The types are not truely checked here and final values may be + * assigned. + * + * @param field Field to set the value. + * @param obj Instance which will have its field set. + * @param val Value to put in the field. + */ + static native void setCharNative(Field field, Object obj, char val) + throws InternalError; + + /** + * Sets the value of the specified field. This method handles "byte". + * Warning ! The types are not truely checked here and final values may be + * assigned. + * + * @param field Field to set the value. + * @param obj Instance which will have its field set. + * @param val Value to put in the field. + */ + static native void setByteNative(Field field, Object obj, byte val) + throws InternalError; + + /** + * Sets the value of the specified field. This method handles "boolean". + * Warning ! The types are not truely checked here and final values may be + * assigned. + * + * @param field Field to set the value. + * @param obj Instance which will have its field set. + * @param val Value to put in the field. + */ + static native void setBooleanNative(Field field, Object obj, boolean val) + throws InternalError; + + /** + * Sets the value of the specified field. This method handles "object". + * Warning ! The types are not truely checked here and final values may be + * assigned. + * + * @param field Field to set the value. + * @param obj Instance which will have its field set. + * @param val Value to put in the field. + */ + static native void setObjectNative(Field field, Object obj, Object val) + throws InternalError; + +} + diff --git a/libjava/classpath/vm/reference/java/lang/VMClass.java b/libjava/classpath/vm/reference/java/lang/VMClass.java new file mode 100644 index 0000000..0ca0329 --- /dev/null +++ b/libjava/classpath/vm/reference/java/lang/VMClass.java @@ -0,0 +1,295 @@ +/* VMClass.java -- VM Specific Class methods + Copyright (C) 2003, 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/* + * This class is a reference version, mainly for compiling a class library + * jar. It is likely that VM implementers replace this with their own + * version that can communicate effectively with the VM. + */ + +/** + * + * @author Etienne Gagnon <etienne.gagnon@uqam.ca> + * @author Archie Cobbs <archie@dellroad.org> + * @author C. Brian Jones <cbj@gnu.org> + */ +final class VMClass +{ + + // Only static methods. Cannot be instantiated. + private VMClass() + { + } + + /** + * Discover whether an Object is an instance of this Class. Think of it + * as almost like <code>o instanceof (this class)</code>. + * + * @param klass the Class object that's calling us + * @param o the Object to check + * @return whether o is an instance of this class + * @since 1.1 + */ + static native boolean isInstance(Class klass, Object o); + + /** + * Discover whether an instance of the Class parameter would be an + * instance of this Class as well. Think of doing + * <code>isInstance(c.newInstance())</code> or even + * <code>c.newInstance() instanceof (this class)</code>. While this + * checks widening conversions for objects, it must be exact for primitive + * types. + * + * @param klass the Class object that's calling us + * @param c the class to check + * @return whether an instance of c would be an instance of this class + * as well + * @throws NullPointerException if c is null + * @since 1.1 + */ + static native boolean isAssignableFrom(Class klass, Class c); + + /** + * Check whether this class is an interface or not. Array types are not + * interfaces. + * + * @param klass the Class object that's calling us + * @return whether this class is an interface or not + */ + static native boolean isInterface(Class klass); + + /** + * Return whether this class is a primitive type. A primitive type class + * is a class representing a kind of "placeholder" for the various + * primitive types, or void. You can access the various primitive type + * classes through java.lang.Boolean.TYPE, java.lang.Integer.TYPE, etc., + * or through boolean.class, int.class, etc. + * + * @param klass the Class object that's calling us + * @return whether this class is a primitive type + * @see Boolean#TYPE + * @see Byte#TYPE + * @see Character#TYPE + * @see Short#TYPE + * @see Integer#TYPE + * @see Long#TYPE + * @see Float#TYPE + * @see Double#TYPE + * @see Void#TYPE + * @since 1.1 + */ + static native boolean isPrimitive(Class klass); + + /** + * Get the name of this class, separated by dots for package separators. + * Primitive types and arrays are encoded as: + * <pre> + * boolean Z + * byte B + * char C + * short S + * int I + * long J + * float F + * double D + * void V + * array type [<em>element type</em> + * class or interface, alone: <dotted name> + * class or interface, as element type: L<dotted name>; + * + * @param klass the Class object that's calling us + * @return the name of this class + */ + static native String getName(Class klass); + + /** + * Get the direct superclass of this class. If this is an interface, + * Object, a primitive type, or void, it will return null. If this is an + * array type, it will return Object. + * + * @param klass the Class object that's calling us + * @return the direct superclass of this class + */ + static native Class getSuperclass(Class klass); + + /** + * Get the interfaces this class <EM>directly</EM> implements, in the + * order that they were declared. This returns an empty array, not null, + * for Object, primitives, void, and classes or interfaces with no direct + * superinterface. Array types return Cloneable and Serializable. + * + * @param klass the Class object that's calling us + * @return the interfaces this class directly implements + */ + static native Class[] getInterfaces(Class klass); + + /** + * If this is an array, get the Class representing the type of array. + * Examples: "[[Ljava.lang.String;" would return "[Ljava.lang.String;", and + * calling getComponentType on that would give "java.lang.String". If + * this is not an array, returns null. + * + * @param klass the Class object that's calling us + * @return the array type of this class, or null + * @see Array + * @since 1.1 + */ + static native Class getComponentType(Class klass); + + /** + * Get the modifiers of this class. These can be decoded using Modifier, + * and is limited to one of public, protected, or private, and any of + * final, static, abstract, or interface. An array class has the same + * public, protected, or private modifier as its component type, and is + * marked final but not an interface. Primitive types and void are marked + * public and final, but not an interface. + * + * @param klass the Class object that's calling us + * @param ignoreInnerClassesAttrib if set, return the real modifiers, not + * the ones specified in the InnerClasses attribute. + * @return the modifiers of this class + * @see Modifer + * @since 1.1 + */ + static native int getModifiers(Class klass, boolean ignoreInnerClassesAttrib); + + /** + * If this is a nested or inner class, return the class that declared it. + * If not, return null. + * + * @param klass the Class object that's calling us + * @return the declaring class of this class + * @since 1.1 + */ + static native Class getDeclaringClass(Class klass); + + /** + * Like <code>getDeclaredClasses()</code> but without the security checks. + * + * @param klass the Class object that's calling us + * @param pulicOnly Only public classes should be returned + */ + static native Class[] getDeclaredClasses(Class klass, boolean publicOnly); + + /** + * Like <code>getDeclaredFields()</code> but without the security checks. + * + * @param klass the Class object that's calling us + * @param pulicOnly Only public fields should be returned + */ + static native Field[] getDeclaredFields(Class klass, boolean publicOnly); + + /** + * Like <code>getDeclaredMethods()</code> but without the security checks. + * + * @param klass the Class object that's calling us + * @param pulicOnly Only public methods should be returned + */ + static native Method[] getDeclaredMethods(Class klass, boolean publicOnly); + + /** + * Like <code>getDeclaredConstructors()</code> but without + * the security checks. + * + * @param klass the Class object that's calling us + * @param pulicOnly Only public constructors should be returned + */ + static native Constructor[] getDeclaredConstructors(Class klass, boolean publicOnly); + + /** + * Return the class loader of this class. + * + * @param klass the Class object that's calling us + * @return the class loader + */ + static native ClassLoader getClassLoader(Class klass); + + /** + * VM implementors are free to make this method a noop if + * the default implementation is acceptable. + * + * @param name the name of the class to find + * @return the Class object representing the class or null for noop + * @throws ClassNotFoundException if the class was not found by the + * classloader + * @throws LinkageError if linking the class fails + * @throws ExceptionInInitializerError if the class loads, but an exception + * occurs during initialization + */ + static native Class forName(String name) throws ClassNotFoundException; + + /** + * Return whether this class is an array type. + * + * @param klass the Class object that's calling us + * @return true if this class is an array type + * operation + */ + static native boolean isArray(Class klass); + + /** + * This method should trigger class initialization (if the + * class hasn't already been initialized) + * + * @param klass the Class object that's calling us + * @throws ExceptionInInitializerError if an exception + * occurs during initialization + */ + static native void initialize(Class klass); + + /** + * Load an array class. + * + * @return the Class object representing the class + * @throws ClassNotFoundException if the class was not found by the + * classloader + */ + static native Class loadArrayClass(String name, ClassLoader classloader) + throws ClassNotFoundException; + + /** + * Throw a checked exception without declaring it. + */ + static native void throwException(Throwable t); + +} // class VMClass diff --git a/libjava/classpath/vm/reference/java/lang/VMClassLoader.java b/libjava/classpath/vm/reference/java/lang/VMClassLoader.java new file mode 100644 index 0000000..c62f0a4 --- /dev/null +++ b/libjava/classpath/vm/reference/java/lang/VMClassLoader.java @@ -0,0 +1,285 @@ +/* VMClassLoader.java -- Reference implementation of native interface + required by ClassLoader + Copyright (C) 1998, 2001, 2002, 2004, 2005 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.lang; + +import gnu.classpath.SystemProperties; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.ProtectionDomain; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.Vector; +import java.util.zip.ZipFile; + +/** + * java.lang.VMClassLoader is a package-private helper for VMs to implement + * on behalf of java.lang.ClassLoader. + * + * @author John Keiser + * @author Mark Wielaard (mark@klomp.org) + * @author Eric Blake (ebb9@email.byu.edu) + */ +final class VMClassLoader +{ + /** + * Helper to define a class using a string of bytes. This assumes that + * the security checks have already been performed, if necessary. + * + * Implementations of this method are advised to consider the + * situation where user code modifies the byte array after it has + * been passed to defineClass. This can be handled by making a + * private copy of the array, or arranging to only read any given + * byte a single time. + * + * @param name the name to give the class, or null if unknown + * @param data the data representing the classfile, in classfile format + * @param offset the offset into the data where the classfile starts + * @param len the length of the classfile data in the array + * @param pd the protection domain + * @return the class that was defined + * @throws ClassFormatError if data is not in proper classfile format + */ + static final native Class defineClass(ClassLoader cl, String name, + byte[] data, int offset, int len, + ProtectionDomain pd) + throws ClassFormatError; + + /** + * Helper to resolve all references to other classes from this class. + * + * @param c the class to resolve + */ + static final native void resolveClass(Class c); + + /** + * Helper to load a class from the bootstrap class loader. + * + * @param name the class name to load + * @param resolve whether to resolve it + * @return the class, loaded by the bootstrap classloader or null + * if the class wasn't found. Returning null is equivalent to throwing + * a ClassNotFoundException (but a possible performance optimization). + */ + static final native Class loadClass(String name, boolean resolve) + throws ClassNotFoundException; + + /** + * Helper to load a resource from the bootstrap class loader. + * + * @param name the resource to find + * @return the URL to the resource + */ + static URL getResource(String name) + { + Enumeration e = getResources(name); + if (e.hasMoreElements()) + return (URL)e.nextElement(); + return null; + } + + /** + * Helper to get a list of resources from the bootstrap class loader. + * + * @param name the resource to find + * @return an enumeration of resources + * @throws IOException if one occurs + */ + static Enumeration getResources(String name) + { + StringTokenizer st = new StringTokenizer( + SystemProperties.getProperty("java.boot.class.path", "."), + File.pathSeparator); + Vector v = new Vector(); + while (st.hasMoreTokens()) + { + File file = new File(st.nextToken()); + if (file.isDirectory()) + { + try + { + v.add(new URL("file://" + + new File(file, name).getAbsolutePath())); + } + catch (MalformedURLException e) + { + throw new Error(e); + } + } + else if (file.isFile()) + { + ZipFile zip; + try + { + zip = new ZipFile(file); + } + catch (IOException e) + { + continue; + } + String zname = name.startsWith("/") ? name.substring(1) : name; + try + { + if (zip.getEntry(zname) == null) + continue; + } + finally + { + try + { + zip.close(); + } + catch (IOException e) + { + } + } + try + { + v.add(new URL("jar:file://" + + file.getAbsolutePath() + "!/" + zname)); + } + catch (MalformedURLException e) + { + throw new Error(e); + } + } + } + return v.elements(); + } + + /** + * Helper to get a package from the bootstrap class loader. The default + * implementation of returning null may be adequate, or you may decide + * that this needs some native help. + * + * @param name the name to find + * @return the named package, if it exists + */ + static Package getPackage(String name) + { + return null; + } + + /** + * Helper to get all packages from the bootstrap class loader. The default + * implementation of returning an empty array may be adequate, or you may + * decide that this needs some native help. + * + * @return all named packages, if any exist + */ + static Package[] getPackages() + { + return new Package[0]; + } + + /** + * Helper for java.lang.Integer, Byte, etc to get the TYPE class + * at initialization time. The type code is one of the chars that + * represents the primitive type as in JNI. + * + * <ul> + * <li>'Z' - boolean</li> + * <li>'B' - byte</li> + * <li>'C' - char</li> + * <li>'D' - double</li> + * <li>'F' - float</li> + * <li>'I' - int</li> + * <li>'J' - long</li> + * <li>'S' - short</li> + * <li>'V' - void</li> + * </ul> + * + * @param type the primitive type + * @return a "bogus" class representing the primitive type + */ + static final native Class getPrimitiveClass(char type); + + /** + * The system default for assertion status. This is used for all system + * classes (those with a null ClassLoader), as well as the initial value for + * every ClassLoader's default assertion status. + * + * XXX - Not implemented yet; this requires native help. + * + * @return the system-wide default assertion status + */ + static final boolean defaultAssertionStatus() + { + return true; + } + + /** + * The system default for package assertion status. This is used for all + * ClassLoader's packageAssertionStatus defaults. It must be a map of + * package names to Boolean.TRUE or Boolean.FALSE, with the unnamed package + * represented as a null key. + * + * XXX - Not implemented yet; this requires native help. + * + * @return a (read-only) map for the default packageAssertionStatus + */ + static final Map packageAssertionStatus() + { + return new HashMap(); + } + + /** + * The system default for class assertion status. This is used for all + * ClassLoader's classAssertionStatus defaults. It must be a map of + * class names to Boolean.TRUE or Boolean.FALSE + * + * XXX - Not implemented yet; this requires native help. + * + * @return a (read-only) map for the default classAssertionStatus + */ + static final Map classAssertionStatus() + { + return new HashMap(); + } + + static ClassLoader getSystemClassLoader() + { + return ClassLoader.defaultGetSystemClassLoader(); + } +} diff --git a/libjava/classpath/vm/reference/java/lang/VMCompiler.java b/libjava/classpath/vm/reference/java/lang/VMCompiler.java new file mode 100644 index 0000000..fe74007 --- /dev/null +++ b/libjava/classpath/vm/reference/java/lang/VMCompiler.java @@ -0,0 +1,112 @@ +/* VMClassLoader.java -- Reference implementation of compiler interface + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang; + +/** + * This class is just a per-VM reflection of java.lang.Compiler. + * All methods are defined identically. + */ +final class VMCompiler +{ + /** + * Don't allow new `Compiler's to be made. + */ + private VMCompiler() + { + } + + /** + * Compile the class named by <code>oneClass</code>. + * + * @param oneClass the class to compile + * @return <code>false</code> if no compiler is available or + * compilation failed, <code>true</code> if compilation succeeded + * @throws NullPointerException if oneClass is null + */ + public static boolean compileClass(Class oneClass) + { + // Never succeed. + return false; + } + + /** + * Compile the classes whose name matches <code>classNames</code>. + * + * @param classNames the name of classes to compile + * @return <code>false</code> if no compiler is available or + * compilation failed, <code>true</code> if compilation succeeded + * @throws NullPointerException if classNames is null + */ + public static boolean compileClasses(String classNames) + { + // Note the incredibly lame interface. Always fail. + return false; + } + + /** + * This method examines the argument and performs an operation + * according to the compilers documentation. No specific operation + * is required. + * + * @param arg a compiler-specific argument + * @return a compiler-specific value, including null + * @throws NullPointerException if the compiler doesn't like a null arg + */ + public static Object command(Object arg) + { + // Our implementation defines this to a no-op. + return null; + } + + /** + * Calling <code>Compiler.enable()</code> will cause the compiler + * to resume operation if it was previously disabled; provided that a + * compiler even exists. + */ + public static void enable() + { + } + + /** + * Calling <code>Compiler.disable()</code> will cause the compiler + * to be suspended; provided that a compiler even exists. + */ + public static void disable() + { + } +} diff --git a/libjava/classpath/vm/reference/java/lang/VMDouble.java b/libjava/classpath/vm/reference/java/lang/VMDouble.java new file mode 100644 index 0000000..8a991c9 --- /dev/null +++ b/libjava/classpath/vm/reference/java/lang/VMDouble.java @@ -0,0 +1,131 @@ +/* VMDouble.java -- VM Specific Double methods + Copyright (C) 2003, 2005 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang; + +import gnu.classpath.Configuration; + +/* + * This class is a reference version, mainly for compiling a class library + * jar. It is likely that VM implementers replace this with their own + * version that can communicate effectively with the VM. + */ + +/** + * Code relocated from java.lang.Double by + * @author Dave Grove (groved@us.ibm.com) + */ +final class VMDouble +{ + + /** + * Load native routines necessary for this class. + */ + static + { + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary("javalang"); + } + + initIDs(); + } + + /** + * Convert the double to the IEEE 754 floating-point "double format" bit + * layout. Bit 63 (the most significant) is the sign bit, bits 62-52 + * (masked by 0x7ff0000000000000L) represent the exponent, and bits 51-0 + * (masked by 0x000fffffffffffffL) are the mantissa. This function + * collapses all versions of NaN to 0x7ff8000000000000L. The result of this + * function can be used as the argument to + * <code>Double.longBitsToDouble(long)</code> to obtain the original + * <code>double</code> value. + * + * @param value the <code>double</code> to convert + * @return the bits of the <code>double</code> + * @see #longBitsToDouble(long) + */ + public static native long doubleToLongBits(double value); + + /** + * Convert the double to the IEEE 754 floating-point "double format" bit + * layout. Bit 63 (the most significant) is the sign bit, bits 62-52 + * (masked by 0x7ff0000000000000L) represent the exponent, and bits 51-0 + * (masked by 0x000fffffffffffffL) are the mantissa. This function + * leaves NaN alone, rather than collapsing to a canonical value. The + * result of this function can be used as the argument to + * <code>Double.longBitsToDouble(long)</code> to obtain the original + * <code>double</code> value. + * + * @param value the <code>double</code> to convert + * @return the bits of the <code>double</code> + * @see #longBitsToDouble(long) + */ + public static native long doubleToRawLongBits(double value); + + /** + * Convert the argument in IEEE 754 floating-point "double format" bit + * layout to the corresponding float. Bit 63 (the most significant) is the + * sign bit, bits 62-52 (masked by 0x7ff0000000000000L) represent the + * exponent, and bits 51-0 (masked by 0x000fffffffffffffL) are the mantissa. + * This function leaves NaN alone, so that you can recover the bit pattern + * with <code>Double.doubleToRawLongBits(double)</code>. + * + * @param bits the bits to convert + * @return the <code>double</code> represented by the bits + * @see #doubleToLongBits(double) + * @see #doubleToRawLongBits(double) + */ + public static native double longBitsToDouble(long bits); + + /** + * Helper method to convert to string. + * + * @param d the double to convert + * @param isFloat true if the conversion is requested by Float (results in + * fewer digits) + */ + public static native String toString(double d, boolean isFloat); + + /** + * Initialize JNI cache. This method is called only by the + * static initializer when using JNI. + */ + public static native void initIDs(); + + public static native double parseDouble(String str); +} diff --git a/libjava/classpath/vm/reference/java/lang/VMFloat.java b/libjava/classpath/vm/reference/java/lang/VMFloat.java new file mode 100644 index 0000000..2e7f439 --- /dev/null +++ b/libjava/classpath/vm/reference/java/lang/VMFloat.java @@ -0,0 +1,111 @@ +/* VMFloat.java -- VM Specific Float methods + Copyright (C) 2003 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang; + +import gnu.classpath.Configuration; + +/* + * This class is a reference version, mainly for compiling a class library + * jar. It is likely that VM implementers replace this with their own + * version that can communicate effectively with the VM. + */ + +/** + * Code relocated from java.lang.Float by + * @author Dave Grove <groved@us.ibm.com> + */ +final class VMFloat +{ + + /** + * Load native routines necessary for this class. + */ + static + { + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary("javalang"); + } + } + + /** + * Convert the float to the IEEE 754 floating-point "single format" bit + * layout. Bit 31 (the most significant) is the sign bit, bits 30-23 + * (masked by 0x7f800000) represent the exponent, and bits 22-0 + * (masked by 0x007fffff) are the mantissa. This function collapses all + * versions of NaN to 0x7fc00000. The result of this function can be used + * as the argument to <code>Float.intBitsToFloat(int)</code> to obtain the + * original <code>float</code> value. + * + * @param value the <code>float</code> to convert + * @return the bits of the <code>float</code> + * @see #intBitsToFloat(int) + */ + static native int floatToIntBits(float value); + + /** + * Convert the float to the IEEE 754 floating-point "single format" bit + * layout. Bit 31 (the most significant) is the sign bit, bits 30-23 + * (masked by 0x7f800000) represent the exponent, and bits 22-0 + * (masked by 0x007fffff) are the mantissa. This function leaves NaN alone, + * rather than collapsing to a canonical value. The result of this function + * can be used as the argument to <code>Float.intBitsToFloat(int)</code> to + * obtain the original <code>float</code> value. + * + * @param value the <code>float</code> to convert + * @return the bits of the <code>float</code> + * @see #intBitsToFloat(int) + */ + static native int floatToRawIntBits(float value); + + /** + * Convert the argument in IEEE 754 floating-point "single format" bit + * layout to the corresponding float. Bit 31 (the most significant) is the + * sign bit, bits 30-23 (masked by 0x7f800000) represent the exponent, and + * bits 22-0 (masked by 0x007fffff) are the mantissa. This function leaves + * NaN alone, so that you can recover the bit pattern with + * <code>Float.floatToRawIntBits(float)</code>. + * + * @param bits the bits to convert + * @return the <code>float</code> represented by the bits + * @see #floatToIntBits(float) + * @see #floatToRawIntBits(float) + */ + static native float intBitsToFloat(int bits); + +} // class VMFloat diff --git a/libjava/classpath/vm/reference/java/lang/VMObject.java b/libjava/classpath/vm/reference/java/lang/VMObject.java new file mode 100644 index 0000000..1d1ec40 --- /dev/null +++ b/libjava/classpath/vm/reference/java/lang/VMObject.java @@ -0,0 +1,105 @@ +/* VMObject.java -- Reference implementation for VM hooks used by Object + Copyright (C) 1998, 2002, 2005 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang; + +/** + * Object is the ultimate superclass of every class (excepting interfaces). + * As such, it needs help from the VM. + * + * @author John Keiser + * @author Eric Blake (ebb9@email.byu.edu) + */ +final class VMObject +{ + /** + * Returns the runtime {@link Class} of a given Object. + * + * @param obj the object to return the class for. + * + * @return the class of the Object. + */ + static native Class getClass(Object obj); + + /** + * The VM is expected to make a field-for-field shallow copy of the + * argument. Thus, the copy has the same runtime type as the argument. + * Note, however, that the cloned object must still be finalizable, even + * if the original has already had finalize() invoked on it. + * + * @param c the Cloneable to clone + * @return the clone + */ + static native Object clone(Cloneable c); + + /** + * Wakes up one of the threads that is waiting on this Object's monitor. + * Only the owner of a lock on the Object may call this method. The Thread + * to wake up is chosen arbitrarily. + * + * @param o the object doing the notify + * @throw IllegalMonitorStateException if this Thread does not own the + * lock on the Object + */ + static native void notify(Object o) throws IllegalMonitorStateException; + + /** + * Wakes up all of the threads waiting on this Object's monitor. Only + * the owner of the lock on this Object may call this method. + * + * @param o the object doing the notifyAll + * @throws IllegalMonitorStateException if this Thread does not own the + * lock on the Object + */ + static native void notifyAll(Object o) throws IllegalMonitorStateException; + + /** + * Waits a specified amount of time for notify() or notifyAll() to be + * called on this Object. The VM does not have to pay attention to the + * ns argument, if it does not have that much granularity. + * + * @param o the object to suspend on + * @param ms milliseconds to wait (1,000 milliseconds = 1 second) + * @param ns nanoseconds to wait beyond ms (1,000,000 nanoseconds + * == 1 millisecond) + * @throws IllegalMonitorStateException if this Thread does not own the + * lock on the Object + * @throws InterruptedException if some other Thread interrupts this Thread + */ + static native void wait(Object o, long ms, int ns) + throws IllegalMonitorStateException, InterruptedException; +} diff --git a/libjava/classpath/vm/reference/java/lang/VMProcess.java b/libjava/classpath/vm/reference/java/lang/VMProcess.java new file mode 100644 index 0000000..fa157d7 --- /dev/null +++ b/libjava/classpath/vm/reference/java/lang/VMProcess.java @@ -0,0 +1,368 @@ +/* java.lang.VMProcess -- VM implementation of java.lang.Process + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.LinkedList; + +/** + * Represents one external process. Each instance of this class is in + * one of three states: INITIAL, RUNNING, or TERMINATED. The instance + * is {@link Object#notifyAll notifyAll()}'d each time the state changes. + * The state of all instances is managed by a single dedicated thread + * which does the actual fork()/exec() and wait() system calls. User + * threads {@link Object#wait wait()} on the instance when creating the + * process or waiting for it to terminate. + * + * <p> + * See + * <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11801">GCC bug + * #11801</a> for the motivation behind the design of this class. + * + * @author Archie Cobbs + * @see Process + * @see Runtime#exec + */ +final class VMProcess extends Process +{ + + // Possible states for a VMProcess + private static final int INITIAL = 0; + private static final int RUNNING = 1; + private static final int TERMINATED = 2; + + // Dedicated thread that does all the fork()'ing and wait()'ing. + static Thread processThread; + + // New processes waiting to be spawned by processThread. + static final LinkedList workList = new LinkedList(); + + // Return values set by nativeReap() when a child is reaped. + // These are only accessed by processThread so no locking required. + static long reapedPid; + static int reapedExitValue; + + // Information about this process + int state; // current state of process + final String[] cmd; // copied from Runtime.exec() + final String[] env; // copied from Runtime.exec() + final File dir; // copied from Runtime.exec() + Throwable exception; // if process failed to start + long pid; // process id + OutputStream stdin; // process input stream + InputStream stdout; // process output stream + InputStream stderr; // process error stream + int exitValue; // process exit value + + // + // Dedicated thread that does all the fork()'ing and wait()'ing + // for external processes. This is needed because some systems like + // Linux use a process-per-thread model, which means the same thread + // that did the fork()/exec() must also do the wait(). + // + private static class ProcessThread extends Thread + { + + // Max time (in ms) we'll delay before trying to reap another child. + private static final int MAX_REAP_DELAY = 1000; + + // Processes created but not yet terminated; maps Long(pid) -> VMProcess + // Only used in run() and spawn() method from this Thread, so no locking. + private final HashMap activeMap = new HashMap(); + + // We have an explicit constructor, because the default + // constructor will be private, which means the compiler will have + // to generate a second package-private constructor, which is + // bogus. + ProcessThread () + { + } + + public void run() + { + final LinkedList workList = VMProcess.workList; + while (true) + { + + // Get the next process to spawn (if any) and spawn it. Spawn + // at most one at a time before checking for reapable children. + VMProcess process = null; + synchronized (workList) + { + if (!workList.isEmpty()) + process = (VMProcess)workList.removeFirst(); + } + + if (process != null) + spawn(process); + + + // Check for termination of active child processes + while (!activeMap.isEmpty() && VMProcess.nativeReap()) + { + long pid = VMProcess.reapedPid; + int exitValue = VMProcess.reapedExitValue; + process = (VMProcess)activeMap.remove(new Long(pid)); + if (process != null) + { + synchronized (process) + { + process.exitValue = exitValue; + process.state = TERMINATED; + process.notify(); + } + } + else + System.err.println("VMProcess WARNING reaped unknown process: " + + pid); + } + + + // If there are more new processes to create, go do that now. + // If there is nothing left to do, exit this thread. Otherwise, + // sleep a little while, and then check again for reapable children. + // We will get woken up immediately if there are new processes to + // spawn, but not if there are new children to reap. So we only + // sleep a short time, in effect polling while processes are active. + synchronized (workList) + { + if (!workList.isEmpty()) + continue; + if (activeMap.isEmpty()) + { + processThread = null; + break; + } + + try + { + workList.wait(MAX_REAP_DELAY); + } + catch (InterruptedException e) + { + /* ignore */ + } + } + } + } + + // Spawn a process + private void spawn(VMProcess process) + { + + // Spawn the process and put it in our active map indexed by pid. + // If the spawn operation fails, store the exception with the process. + // In either case, wake up thread that created the process. + synchronized (process) + { + try + { + process.nativeSpawn(process.cmd, process.env, process.dir); + process.state = RUNNING; + activeMap.put(new Long(process.pid), process); + } + catch (ThreadDeath death) + { + throw death; + } + catch (Throwable t) + { + process.state = TERMINATED; + process.exception = t; + } + process.notify(); + } + } + } + + // Constructor + private VMProcess(String[] cmd, String[] env, File dir) throws IOException + { + + // Initialize this process + this.state = INITIAL; + this.cmd = cmd; + this.env = env; + this.dir = dir; + + // Add process to the new process work list and wakeup processThread + synchronized (workList) + { + workList.add(this); + if (processThread == null) + { + processThread = new ProcessThread(); + processThread.setDaemon(true); + processThread.start(); + } + else + { + workList.notify(); + } + } + + // Wait for processThread to spawn this process and update its state + synchronized (this) + { + while (state == INITIAL) + { + try + { + wait(); + } + catch (InterruptedException e) + { + /* ignore */ + } + } + } + + // If spawning failed, rethrow the exception in this thread + if (exception != null) + { + exception.fillInStackTrace(); + if (exception instanceof IOException) + throw (IOException)exception; + + if (exception instanceof Error) + throw (Error)exception; + + if (exception instanceof RuntimeException) + throw (RuntimeException)exception; + + throw new RuntimeException(exception); + } + } + + // Invoked by native code (from nativeSpawn()) to record process info. + private void setProcessInfo(OutputStream stdin, + InputStream stdout, InputStream stderr, long pid) + { + this.stdin = stdin; + this.stdout = stdout; + this.stderr = stderr; + this.pid = pid; + } + + /** + * Entry point from Runtime.exec(). + */ + static Process exec(String[] cmd, String[] env, File dir) throws IOException + { + return new VMProcess(cmd, env, dir); + } + + public OutputStream getOutputStream() + { + return stdin; + } + + public InputStream getInputStream() + { + return stdout; + } + + public InputStream getErrorStream() + { + return stderr; + } + + public synchronized int waitFor() throws InterruptedException + { + while (state != TERMINATED) + wait(); + return exitValue; + } + + public synchronized int exitValue() + { + if (state != TERMINATED) + throw new IllegalThreadStateException(); + return exitValue; + } + + public synchronized void destroy() + { + if (state == TERMINATED) + return; + + nativeKill(pid); + + while (state != TERMINATED) + { + try + { + wait(); + } + catch (InterruptedException e) + { + /* ignore */ + } + } + } + + /** + * Does the fork()/exec() thing to create the O/S process. + * Must invoke setProcessInfo() before returning successfully. + * This method is only invoked by processThread. + * + * @throws IOException if the O/S process could not be created. + */ + native void nativeSpawn(String[] cmd, String[] env, File dir) + throws IOException; + + /** + * Test for a reapable child process, and reap if so. Does not block. + * If a child was reaped, this method must set reapedPid and + * reapedExitValue appropriately before returning. + * This method is only invoked by processThread. + * + * @return true if a child was reaped, otherwise false + */ + // This is not private as it is called from an inner class. + static native boolean nativeReap(); + + /** + * Kill a process. This sends it a fatal signal but does not reap it. + */ + private static native void nativeKill(long pid); +} diff --git a/libjava/classpath/vm/reference/java/lang/VMRuntime.java b/libjava/classpath/vm/reference/java/lang/VMRuntime.java new file mode 100644 index 0000000..b685b35 --- /dev/null +++ b/libjava/classpath/vm/reference/java/lang/VMRuntime.java @@ -0,0 +1,192 @@ +/* VMRuntime.java -- VM interface to Runtime + Copyright (C) 2003 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang; + +import java.io.File; +import java.io.IOException; + +/** + * VMRuntime represents the interface to the Virtual Machine. + * + * @author Jeroen Frijters + */ +final class VMRuntime +{ + /** + * No instance is ever created. + */ + private VMRuntime() + { + } + + /** + * Returns the number of available processors currently available to the + * virtual machine. This number may change over time; so a multi-processor + * program want to poll this to determine maximal resource usage. + * + * @return the number of processors available, at least 1 + */ + static native int availableProcessors(); + + /** + * Find out how much memory is still free for allocating Objects on the heap. + * + * @return the number of bytes of free memory for more Objects + */ + static native long freeMemory(); + + /** + * Find out how much memory total is available on the heap for allocating + * Objects. + * + * @return the total number of bytes of memory for Objects + */ + static native long totalMemory(); + + /** + * Returns the maximum amount of memory the virtual machine can attempt to + * use. This may be <code>Long.MAX_VALUE</code> if there is no inherent + * limit (or if you really do have a 8 exabyte memory!). + * + * @return the maximum number of bytes the virtual machine will attempt + * to allocate + */ + static native long maxMemory(); + + /** + * Run the garbage collector. This method is more of a suggestion than + * anything. All this method guarantees is that the garbage collector will + * have "done its best" by the time it returns. Notice that garbage + * collection takes place even without calling this method. + */ + static native void gc(); + + /** + * Run finalization on all Objects that are waiting to be finalized. Again, + * a suggestion, though a stronger one than {@link #gc()}. This calls the + * <code>finalize</code> method of all objects waiting to be collected. + * + * @see #finalize() + */ + static native void runFinalization(); + + /** + * Run finalization on all finalizable Objects (even live ones). This + * should only be called immediately prior to VM termination. + * + * @see #finalize() + */ + static native void runFinalizationForExit(); + + /** + * Tell the VM to trace every bytecode instruction that executes (print out + * a trace of it). No guarantees are made as to where it will be printed, + * and the VM is allowed to ignore this request. + * + * @param on whether to turn instruction tracing on + */ + static native void traceInstructions(boolean on); + + /** + * Tell the VM to trace every method call that executes (print out a trace + * of it). No guarantees are made as to where it will be printed, and the + * VM is allowed to ignore this request. + * + * @param on whether to turn method tracing on + */ + static native void traceMethodCalls(boolean on); + + /** + * Native method that actually sets the finalizer setting. + * + * @param value whether to run finalizers on exit + */ + static native void runFinalizersOnExit(boolean value); + + /** + * Native method that actually shuts down the virtual machine. + * + * @param status the status to end the process with + */ + static native void exit(int status); + + /** + * Load a file. If it has already been loaded, do nothing. The name has + * already been mapped to a true filename. + * + * @param filename the file to load + * @param loader class loader, or <code>null</code> for the boot loader + * @return 0 on failure, nonzero on success + */ + static native int nativeLoad(String filename, ClassLoader loader); + + /** + * Map a system-independent "short name" to the full file name. + * + * @param libname the short version of the library name + * @return the full filename + */ + static native String mapLibraryName(String libname); + + /** + * Execute a process. The command line has already been tokenized, and + * the environment should contain name=value mappings. If directory is null, + * use the current working directory; otherwise start the process in that + * directory. If env is null, then the new process should inherit + * the environment of this process. + * + * @param cmd the non-null command tokens + * @param env the environment setup + * @param dir the directory to use, may be null + * @return the newly created process + * @throws NullPointerException if cmd or env have null elements + */ + static Process exec(String[] cmd, String[] env, File dir) + throws IOException { + return VMProcess.exec(cmd, env, dir); + } + + /** + * This method is called by Runtime.addShutdownHook() when it is + * called for the first time. It enables the VM to lazily setup + * an exit handler, should it so desire. + */ + static void enableShutdownHooks() + { + } +} // class VMRuntime diff --git a/libjava/classpath/vm/reference/java/lang/VMString.java b/libjava/classpath/vm/reference/java/lang/VMString.java new file mode 100644 index 0000000..7e65eed9 --- /dev/null +++ b/libjava/classpath/vm/reference/java/lang/VMString.java @@ -0,0 +1,91 @@ +/* VMString.java -- VM Specific String methods + Copyright (C) 2003 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang; + +import java.lang.ref.WeakReference; +import java.util.WeakHashMap; + +/* + * This class is a reference version, mainly for compiling a class library + * jar. It is likely that VM implementers replace this with their own + * version that can communicate effectively with the VM. + */ + +/** + * Code relocated from java.lang.String by + * @author Dave Grove <groved@us.ibm.com> + */ +final class VMString +{ + + /** + * Holds the references for each intern()'d String. If all references to + * the string disappear, and the VM properly supports weak references, + * the String will be GC'd. + */ + private static final WeakHashMap internTable = new WeakHashMap(); + + /** + * Fetches this String from the intern hashtable. If two Strings are + * considered equal, by the equals() method, then intern() will return the + * same String instance. ie. if (s1.equals(s2)) then + * (s1.intern() == s2.intern()). All string literals and string-valued + * constant expressions are already interned. + * + * @param str the String to intern + * @return the interned String + */ + static String intern(String str) + { + synchronized (internTable) + { + WeakReference ref = (WeakReference) internTable.get(str); + if (ref != null) + { + String s = (String) ref.get(); + // If s is null, then no strong references exist to the String; + // the weak hash map will soon delete the key. + if (s != null) + return s; + } + internTable.put(str, new WeakReference(str)); + } + return str; + } + +} // class VMString diff --git a/libjava/classpath/vm/reference/java/lang/VMSystem.java b/libjava/classpath/vm/reference/java/lang/VMSystem.java new file mode 100644 index 0000000..70f9dba --- /dev/null +++ b/libjava/classpath/vm/reference/java/lang/VMSystem.java @@ -0,0 +1,181 @@ +/* VMSystem.java -- helper for java.lang.system + Copyright (C) 1998, 2002, 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.PrintStream; + +/** + * VMSystem is a package-private helper class for System that the + * VM must implement. + * + * @author John Keiser + */ +final class VMSystem +{ + /** + * Copy one array onto another from <code>src[srcStart]</code> ... + * <code>src[srcStart+len-1]</code> to <code>dest[destStart]</code> ... + * <code>dest[destStart+len-1]</code>. First, the arguments are validated: + * neither array may be null, they must be of compatible types, and the + * start and length must fit within both arrays. Then the copying starts, + * and proceeds through increasing slots. If src and dest are the same + * array, this will appear to copy the data to a temporary location first. + * An ArrayStoreException in the middle of copying will leave earlier + * elements copied, but later elements unchanged. + * + * @param src the array to copy elements from + * @param srcStart the starting position in src + * @param dest the array to copy elements to + * @param destStart the starting position in dest + * @param len the number of elements to copy + * @throws NullPointerException if src or dest is null + * @throws ArrayStoreException if src or dest is not an array, if they are + * not compatible array types, or if an incompatible runtime type + * is stored in dest + * @throws IndexOutOfBoundsException if len is negative, or if the start or + * end copy position in either array is out of bounds + */ + static native void arraycopy(Object src, int srcStart, + Object dest, int destStart, int len); + + /** + * Get a hash code computed by the VM for the Object. This hash code will + * be the same as Object's hashCode() method. It is usually some + * convolution of the pointer to the Object internal to the VM. It + * follows standard hash code rules, in that it will remain the same for a + * given Object for the lifetime of that Object. + * + * @param o the Object to get the hash code for + * @return the VM-dependent hash code for this Object + */ + static native int identityHashCode(Object o); + + /** + * Convert a library name to its platform-specific variant. + * + * @param libname the library name, as used in <code>loadLibrary</code> + * @return the platform-specific mangling of the name + * @XXX Add this method + static native String mapLibraryName(String libname); + */ + + /** + * Set {@link #in} to a new InputStream. + * + * @param in the new InputStream + * @see #setIn(InputStream) + */ + static native void setIn(InputStream in); + + /** + * Set {@link #out} to a new PrintStream. + * + * @param out the new PrintStream + * @see #setOut(PrintStream) + */ + static native void setOut(PrintStream out); + + /** + * Set {@link #err} to a new PrintStream. + * + * @param err the new PrintStream + * @see #setErr(PrintStream) + */ + static native void setErr(PrintStream err); + + /** + * Get the current time, measured in the number of milliseconds from the + * beginning of Jan. 1, 1970. This is gathered from the system clock, with + * any attendant incorrectness (it may be timezone dependent). + * + * @return the current time + * @see java.util.Date + */ + public static native long currentTimeMillis(); + + /** + * Helper method which creates the standard input stream. + * VM implementors may choose to construct these streams differently. + * This method can also return null if the stream is created somewhere + * else in the VM startup sequence. + */ + + static InputStream makeStandardInputStream() + { + return new BufferedInputStream(new FileInputStream(FileDescriptor.in)); + } + + /** + * Helper method which creates the standard output stream. + * VM implementors may choose to construct these streams differently. + * This method can also return null if the stream is created somewhere + * else in the VM startup sequence. + */ + + static PrintStream makeStandardOutputStream() + { + return new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)), true); + } + /** + * Helper method which creates the standard error stream. + * VM implementors may choose to construct these streams differently. + * This method can also return null if the stream is created somewhere + * else in the VM startup sequence. + */ + + static PrintStream makeStandardErrorStream() + { + return new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.err)), true); + } + + /** + * Gets the value of an environment variable. + * Always returning null is a valid (but not very useful) implementation. + * + * @param name The name of the environment variable (will not be null). + * @return The string value of the variable or null when the + * environment variable is not defined. + */ + static native String getenv(String name); +} diff --git a/libjava/classpath/vm/reference/java/lang/VMThread.java b/libjava/classpath/vm/reference/java/lang/VMThread.java new file mode 100644 index 0000000..6b9102b --- /dev/null +++ b/libjava/classpath/vm/reference/java/lang/VMThread.java @@ -0,0 +1,450 @@ +/* VMThread -- VM interface for Thread of executable code + Copyright (C) 2003, 2004, 2005 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang; + +/** + * VM interface for Thread of executable code. Holds VM dependent state. + * It is deliberately package local and final and should only be accessed + * by the Thread class. + * <p> + * This is the GNU Classpath reference implementation, it should be adapted + * for a specific VM. + * <p> + * The following methods must be implemented: + * <ul> + * <li>native void start(long stacksize); + * <li>native void interrupt(); + * <li>native boolean isInterrupted(); + * <li>native void suspend(); + * <li>native void resume(); + * <li>native void nativeSetPriority(int priority); + * <li>native void nativeStop(Throwable t); + * <li>native static Thread currentThread(); + * <li>static native void yield(); + * <li>static native boolean interrupted(); + * </ul> + * All other methods may be implemented to make Thread handling more efficient + * or to implement some optional (and sometimes deprecated) behaviour. Default + * implementations are provided but it is highly recommended to optimize them + * for a specific VM. + * + * @author Jeroen Frijters (jeroen@frijters.net) + * @author Dalibor Topic (robilad@kaffe.org) + */ +final class VMThread +{ + /** + * The Thread object that this VM state belongs to. + * Used in currentThread() and start(). + * Note: when this thread dies, this reference is *not* cleared + */ + volatile Thread thread; + + /** + * Flag that is set when the thread runs, used by stop() to protect against + * stop's getting lost. + */ + private volatile boolean running; + + /** + * VM private data. + */ + private transient Object vmdata; + + /** + * Private constructor, create VMThreads with the static create method. + * + * @param thread The Thread object that was just created. + */ + private VMThread(Thread thread) + { + this.thread = thread; + } + + /** + * This method is the initial Java code that gets executed when a native + * thread starts. It's job is to coordinate with the rest of the VMThread + * logic and to start executing user code and afterwards handle clean up. + */ + private void run() + { + try + { + try + { + running = true; + synchronized(thread) + { + Throwable t = thread.stillborn; + if(t != null) + { + thread.stillborn = null; + throw t; + } + } + thread.run(); + } + catch(Throwable t) + { + try + { + thread.group.uncaughtException(thread, t); + } + catch(Throwable ignore) + { + } + } + } + finally + { + // Setting runnable to false is partial protection against stop + // being called while we're cleaning up. To be safe all code in + // VMThread be unstoppable. + running = false; + thread.die(); + synchronized(this) + { + // release the threads waiting to join us + notifyAll(); + } + } + } + + /** + * Creates a native Thread. This is called from the start method of Thread. + * The Thread is started. + * + * @param thread The newly created Thread object + * @param stacksize Indicates the requested stacksize. Normally zero, + * non-zero values indicate requested stack size in bytes but it is up + * to the specific VM implementation to interpret them and may be ignored. + */ + static void create(Thread thread, long stacksize) + { + VMThread vmThread = new VMThread(thread); + vmThread.start(stacksize); + thread.vmThread = vmThread; + } + + /** + * Gets the name of the thread. Usually this is the name field of the + * associated Thread object, but some implementation might choose to + * return the name of the underlying platform thread. + */ + String getName() + { + return thread.name; + } + + /** + * Set the name of the thread. Usually this sets the name field of the + * associated Thread object, but some implementations might choose to + * set the name of the underlying platform thread. + * @param name The new name + */ + void setName(String name) + { + thread.name = name; + } + + /** + * Set the thread priority field in the associated Thread object and + * calls the native method to set the priority of the underlying + * platform thread. + * @param priority The new priority + */ + void setPriority(int priority) + { + thread.priority = priority; + nativeSetPriority(priority); + } + + /** + * Returns the priority. Usually this is the priority field from the + * associated Thread object, but some implementation might choose to + * return the priority of the underlying platform thread. + * @return this Thread's priority + */ + int getPriority() + { + return thread.priority; + } + + /** + * Returns true if the thread is a daemon thread. Usually this is the + * daemon field from the associated Thread object, but some + * implementation might choose to return the daemon state of the underlying + * platform thread. + * @return whether this is a daemon Thread or not + */ + boolean isDaemon() + { + return thread.daemon; + } + + /** + * Returns the number of stack frames in this Thread. + * Will only be called when when a previous call to suspend() returned true. + * + * @deprecated unsafe operation + */ + native int countStackFrames(); + + /** + * Wait the specified amount of time for the Thread in question to die. + * + * <p>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do + * not offer that fine a grain of timing resolution. Besides, there is + * no guarantee that this thread can start up immediately when time expires, + * because some other thread may be active. So don't expect real-time + * performance. + * + * @param ms the number of milliseconds to wait, or 0 for forever + * @param ns the number of extra nanoseconds to sleep (0-999999) + * @throws InterruptedException if the Thread is interrupted; it's + * <i>interrupted status</i> will be cleared + */ + synchronized void join(long ms, int ns) throws InterruptedException + { + // Round up + ms += (ns != 0) ? 1 : 0; + + // Compute end time, but don't overflow + long now = System.currentTimeMillis(); + long end = now + ms; + if (end < now) + end = Long.MAX_VALUE; + + // A VM is allowed to return from wait() without notify() having been + // called, so we loop to handle possible spurious wakeups. + while(thread.vmThread != null) + { + // We use the VMThread object to wait on, because this is a private + // object, so client code cannot call notify on us. + wait(ms); + if(ms != 0) + { + now = System.currentTimeMillis(); + ms = end - now; + if(ms <= 0) + { + break; + } + } + } + } + + /** + * Cause this Thread to stop abnormally and throw the specified exception. + * If you stop a Thread that has not yet started, the stop is ignored + * (contrary to what the JDK documentation says). + * <b>WARNING</b>This bypasses Java security, and can throw a checked + * exception which the call stack is unprepared to handle. Do not abuse + * this power. + * + * <p>This is inherently unsafe, as it can interrupt synchronized blocks and + * leave data in bad states. + * + * <p><b>NOTE</b> stop() should take care not to stop a thread if it is + * executing code in this class. + * + * @param t the Throwable to throw when the Thread dies + * @deprecated unsafe operation, try not to use + */ + void stop(Throwable t) + { + // Note: we assume that we own the lock on thread + // (i.e. that Thread.stop() is synchronized) + if(running) + nativeStop(t); + else + thread.stillborn = t; + } + + /** + * Create a native thread on the underlying platform and start it executing + * on the run method of this object. + * @param stacksize the requested size of the native thread stack + */ + native void start(long stacksize); + + /** + * Interrupt this thread. + */ + native void interrupt(); + + /** + * Determine whether this Thread has been interrupted, but leave + * the <i>interrupted status</i> alone in the process. + * + * @return whether the Thread has been interrupted + */ + native boolean isInterrupted(); + + /** + * Suspend this Thread. It will not come back, ever, unless it is resumed. + */ + native void suspend(); + + /** + * Resume this Thread. If the thread is not suspended, this method does + * nothing. + */ + native void resume(); + + /** + * Set the priority of the underlying platform thread. + * + * @param priority the new priority + */ + native void nativeSetPriority(int priority); + + /** + * Asynchronously throw the specified throwable in this Thread. + * + * @param t the exception to throw + */ + native void nativeStop(Throwable t); + + /** + * Return the Thread object associated with the currently executing + * thread. + * + * @return the currently executing Thread + */ + static native Thread currentThread(); + + /** + * Yield to another thread. The Thread will not lose any locks it holds + * during this time. There are no guarantees which thread will be + * next to run, and it could even be this one, but most VMs will choose + * the highest priority thread that has been waiting longest. + */ + static native void yield(); + + /** + * Suspend the current Thread's execution for the specified amount of + * time. The Thread will not lose any locks it has during this time. There + * are no guarantees which thread will be next to run, but most VMs will + * choose the highest priority thread that has been waiting longest. + * + * <p>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do + * not offer that fine a grain of timing resolution. Besides, there is + * no guarantee that this thread can start up immediately when time expires, + * because some other thread may be active. So don't expect real-time + * performance. + * + * @param ms the number of milliseconds to sleep. + * @param ns the number of extra nanoseconds to sleep (0-999999) + * @throws InterruptedException if the Thread is (or was) interrupted; + * it's <i>interrupted status</i> will be cleared + */ + static void sleep(long ms, int ns) throws InterruptedException + { + + // Round up + ms += (ns != 0) ? 1 : 0; + + // Note: JDK treats a zero length sleep is like Thread.yield(), + // without checking the interrupted status of the thread. + // It's unclear if this is a bug in the implementation or the spec. + // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203 + if (ms == 0) + { + if (Thread.interrupted()) + throw new InterruptedException(); + return; + } + + // Compute end time, but don't overflow + long now = System.currentTimeMillis(); + long end = now + ms; + if (end < now) + end = Long.MAX_VALUE; + + // A VM is allowed to return from wait() without notify() having been + // called, so we loop to handle possible spurious wakeups. + VMThread vt = Thread.currentThread().vmThread; + synchronized (vt) + { + while (true) + { + vt.wait(ms); + now = System.currentTimeMillis(); + if (now >= end) + break; + ms = end - now; + } + } + } + + /** + * Determine whether the current Thread has been interrupted, and clear + * the <i>interrupted status</i> in the process. + * + * @return whether the current Thread has been interrupted + */ + static native boolean interrupted(); + + /** + * Checks whether the current thread holds the monitor on a given object. + * This allows you to do <code>assert Thread.holdsLock(obj)</code>. + * + * @param obj the object to check + * @return true if the current thread is currently synchronized on obj + * @throws NullPointerException if obj is null + */ + static boolean holdsLock(Object obj) + { + /* Use obj.notify to check if the current thread holds + * the monitor of the object. + * If it doesn't, notify will throw an exception. + */ + try + { + obj.notify(); + // okay, current thread holds lock + return true; + } + catch (IllegalMonitorStateException e) + { + // it doesn't hold the lock + return false; + } + } +} diff --git a/libjava/classpath/vm/reference/java/lang/VMThrowable.java b/libjava/classpath/vm/reference/java/lang/VMThrowable.java new file mode 100644 index 0000000..19a204e --- /dev/null +++ b/libjava/classpath/vm/reference/java/lang/VMThrowable.java @@ -0,0 +1,82 @@ +/* java.lang.VMThrowable -- VM support methods for Throwable. + Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang; + +/** + * VM dependant state and support methods for Throwable. + * It is deliberately package local and final and should only be accessed + * by the Throwable class. + * <p> + * This is the GNU Classpath reference implementation, it should be adapted + * for a specific VM. The reference implementation does nothing. + * + * @author Mark Wielaard (mark@klomp.org) + */ +final class VMThrowable +{ + /** + * VM private data. + */ + private transient Object vmdata; + + /** + * Private contructor, create VMThrowables with fillInStackTrace(); + */ + private VMThrowable() { } + + /** + * Fill in the stack trace with the current execution stack. + * Called by <code>Throwable.fillInStackTrace()</code> to get the state of + * the VM. Can return null when the VM does not support caputing the VM + * execution state. + * + * @return a new VMThrowable containing the current execution stack trace. + * @see Throwable#fillInStackTrace() + */ + static native VMThrowable fillInStackTrace(Throwable t); + + /** + * Returns an <code>StackTraceElement</code> array based on the execution + * state of the VM as captured by <code>fillInStackTrace</code>. + * Called by <code>Throwable.getStackTrace()</code>. + * + * @return a non-null but possible zero length array of StackTraceElement. + * @see Throwable#getStackTrace() + */ + native StackTraceElement[] getStackTrace(Throwable t); +} diff --git a/libjava/classpath/vm/reference/java/lang/reflect/Constructor.java b/libjava/classpath/vm/reference/java/lang/reflect/Constructor.java new file mode 100644 index 0000000..cddb9ad --- /dev/null +++ b/libjava/classpath/vm/reference/java/lang/reflect/Constructor.java @@ -0,0 +1,249 @@ +/* java.lang.reflect.Constructor - reflection of Java constructors + Copyright (C) 1998, 2001 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.lang.reflect; + +import java.util.Arrays; + +/** + * The Constructor class represents a constructor of a class. It also allows + * dynamic creation of an object, via reflection. Invocation on Constructor + * objects knows how to do widening conversions, but throws + * {@link IllegalArgumentException} if a narrowing conversion would be + * necessary. You can query for information on this Constructor regardless + * of location, but construction access may be limited by Java language + * access controls. If you can't do it in the compiler, you can't normally + * do it here either.<p> + * + * <B>Note:</B> This class returns and accepts types as Classes, even + * primitive types; there are Class types defined that represent each + * different primitive type. They are <code>java.lang.Boolean.TYPE, + * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class, + * byte.class</code>, etc. These are not to be confused with the + * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are + * real classes.<p> + * + * Also note that this is not a serializable class. It is entirely feasible + * to make it serializable using the Externalizable interface, but this is + * on Sun, not me. + * + * @author John Keiser + * @author Eric Blake <ebb9@email.byu.edu> + * @see Member + * @see Class + * @see java.lang.Class#getConstructor(Object[]) + * @see java.lang.Class#getDeclaredConstructor(Object[]) + * @see java.lang.Class#getConstructors() + * @see java.lang.Class#getDeclaredConstructors() + * @since 1.1 + * @status updated to 1.4 + */ +public final class Constructor +extends AccessibleObject implements Member +{ + private Class clazz; + private int slot; + + /** + * This class is uninstantiable except from native code. + */ + private Constructor(Class declaringClass,int slot) + { + this.clazz = declaringClass; + this.slot = slot; + } + + private Constructor() + { + } + + /** + * Gets the class that declared this constructor. + * @return the class that declared this member + */ + public Class getDeclaringClass() + { + return clazz; + } + + /** + * Gets the name of this constructor (the non-qualified name of the class + * it was declared in). + * @return the name of this constructor + */ + public String getName() + { + return getDeclaringClass().getName(); + } + + /** + * Gets the modifiers this constructor uses. Use the <code>Modifier</code> + * class to interpret the values. A constructor can only have a subset of the + * following modifiers: public, private, protected. + * + * @return an integer representing the modifiers to this Member + * @see Modifier + */ + public native int getModifiers(); + + /** + * Get the parameter list for this constructor, in declaration order. If the + * constructor takes no parameters, returns a 0-length array (not null). + * + * @return a list of the types of the constructor's parameters + */ + public native Class[] getParameterTypes(); + + /** + * Get the exception types this constructor says it throws, in no particular + * order. If the constructor has no throws clause, returns a 0-length array + * (not null). + * + * @return a list of the types in the constructor's throws clause + */ + public native Class[] getExceptionTypes(); + + /** + * Compare two objects to see if they are semantically equivalent. + * Two Constructors are semantically equivalent if they have the same + * declaring class and the same parameter list. This ignores different + * exception clauses, but since you can't create a Method except through the + * VM, this is just the == relation. + * + * @param o the object to compare to + * @return <code>true</code> if they are equal; <code>false</code> if not. + */ + public boolean equals(Object o) + { + if (!(o instanceof Constructor)) + return false; + Constructor that = (Constructor)o; + if (this.getDeclaringClass() != that.getDeclaringClass()) + return false; + if (!Arrays.equals(this.getParameterTypes(), that.getParameterTypes())) + return false; + return true; + } + + /** + * Get the hash code for the Constructor. The Constructor hash code is the + * hash code of the declaring class's name. + * + * @return the hash code for the object + */ + public int hashCode() + { + return getDeclaringClass().getName().hashCode(); + } + + /** + * Get a String representation of the Constructor. A Constructor's String + * representation is "<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() + { + // 128 is a reasonable buffer initial size for constructor + StringBuffer sb = new StringBuffer(128); + Modifier.toString(getModifiers(), sb).append(' '); + sb.append(getDeclaringClass().getName()).append('('); + Class[] c = getParameterTypes(); + if (c.length > 0) + { + sb.append(c[0].getName()); + for (int i = 1; i < c.length; i++) + sb.append(',').append(c[i].getName()); + } + sb.append(')'); + c = getExceptionTypes(); + if (c.length > 0) + { + sb.append(" throws ").append(c[0].getName()); + for (int i = 1; i < c.length; i++) + sb.append(',').append(c[i].getName()); + } + return sb.toString(); + } + + /** + * Create a new instance by invoking the constructor. Arguments are + * automatically unwrapped and widened, if needed.<p> + * + * If this class is abstract, you will get an + * <code>InstantiationException</code>. If the constructor takes 0 + * arguments, you may use null or a 0-length array for <code>args</code>.<p> + * + * If this Constructor enforces access control, your runtime context is + * evaluated, and you may have an <code>IllegalAccessException</code> if + * you could not create this object in similar compiled code. If the class + * is uninitialized, you trigger class initialization, which may end in a + * <code>ExceptionInInitializerError</code>.<p> + * + * Then, the constructor is invoked. If it completes normally, the return + * value will be the new object. If it completes abruptly, the exception is + * wrapped in an <code>InvocationTargetException</code>. + * + * @param args the arguments to the constructor + * @return the newly created object + * @throws IllegalAccessException if the constructor could not normally be + * called by the Java code (i.e. it is not public) + * @throws IllegalArgumentException if the number of arguments is incorrect; + * or if the arguments types are wrong even with a widening + * conversion + * @throws InstantiationException if the class is abstract + * @throws InvocationTargetException if the constructor throws an exception + * @throws ExceptionInInitializerError if construction triggered class + * initialization, which then failed + */ + public Object newInstance(Object args[]) + throws InstantiationException, IllegalAccessException, + InvocationTargetException + { + return constructNative(args, clazz, slot); + } + + private native Object constructNative(Object[] args, Class declaringClass, + int slot) + throws InstantiationException, IllegalAccessException, + InvocationTargetException; +} diff --git a/libjava/classpath/vm/reference/java/lang/reflect/Field.java b/libjava/classpath/vm/reference/java/lang/reflect/Field.java new file mode 100644 index 0000000..85e76d6 --- /dev/null +++ b/libjava/classpath/vm/reference/java/lang/reflect/Field.java @@ -0,0 +1,589 @@ +/* java.lang.reflect.Field - reflection of Java fields + Copyright (C) 1998, 2001 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.lang.reflect; + +/** + * The Field class represents a member variable of a class. It also allows + * dynamic access to a member, via reflection. This works for both + * static and instance fields. Operations on Field objects know how to + * do widening conversions, but throw {@link IllegalArgumentException} if + * a narrowing conversion would be necessary. You can query for information + * on this Field regardless of location, but get and set access may be limited + * by Java language access controls. If you can't do it in the compiler, you + * can't normally do it here either.<p> + * + * <B>Note:</B> This class returns and accepts types as Classes, even + * primitive types; there are Class types defined that represent each + * different primitive type. They are <code>java.lang.Boolean.TYPE, + * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class, + * byte.class</code>, etc. These are not to be confused with the + * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are + * real classes.<p> + * + * Also note that this is not a serializable class. It is entirely feasible + * to make it serializable using the Externalizable interface, but this is + * on Sun, not me. + * + * @author John Keiser + * @author Eric Blake <ebb9@email.byu.edu> + * @see Member + * @see Class + * @see Class#getField(String) + * @see Class#getDeclaredField(String) + * @see Class#getFields() + * @see Class#getDeclaredFields() + * @since 1.1 + * @status updated to 1.4 + */ +public final class Field +extends AccessibleObject implements Member +{ + private Class declaringClass; + private String name; + private int slot; + + /** + * This class is uninstantiable except natively. + */ + private Field(Class declaringClass, String name, int slot) + { + this.declaringClass = declaringClass; + this.name = name; + this.slot = slot; + } + + /** + * Gets the class that declared this field, or the class where this field + * is a non-inherited member. + * @return the class that declared this member + */ + public Class getDeclaringClass() + { + return declaringClass; + } + + /** + * Gets the name of this field. + * @return the name of this field + */ + public String getName() + { + return name; + } + + /** + * Gets the modifiers this field uses. Use the <code>Modifier</code> + * class to interpret the values. A field can only have a subset of the + * following modifiers: public, private, protected, static, final, + * transient, and volatile. + * + * @return an integer representing the modifiers to this Member + * @see Modifier + */ + public native int getModifiers(); + + /** + * Gets the type of this field. + * @return the type of this field + */ + public native Class getType(); + + /** + * Compare two objects to see if they are semantically equivalent. + * Two Fields are semantically equivalent if they have the same declaring + * class, name, and type. Since you can't creat a Field except through + * the VM, this is just the == relation. + * + * @param o the object to compare to + * @return <code>true</code> if they are equal; <code>false</code> if not + */ + public boolean equals(Object o) + { + if (!(o instanceof Field)) + return false; + Field that = (Field)o; + if (this.getDeclaringClass() != that.getDeclaringClass()) + return false; + if (!this.getName().equals(that.getName())) + return false; + if (this.getType() != that.getType()) + return false; + return true; + } + + /** + * Get the hash code for the Field. The Field hash code is the hash code + * of its name XOR'd with the hash code of its class name. + * + * @return the hash code for the object. + */ + public int hashCode() + { + return getDeclaringClass().getName().hashCode() ^ getName().hashCode(); + } + + /** + * Get a String representation of the Field. A Field's String + * representation is "<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() + { + // 64 is a reasonable buffer initial size for field + StringBuffer sb = new StringBuffer(64); + Modifier.toString(getModifiers(), sb).append(' '); + sb.append(getType().getName()).append(' '); + sb.append(getDeclaringClass().getName()).append('.'); + sb.append(getName()); + return sb.toString(); + } + + /** + * Get the value of this Field. If it is primitive, it will be wrapped + * in the appropriate wrapper type (boolean = java.lang.Boolean).<p> + * + * If the field is static, <code>o</code> will be ignored. Otherwise, if + * <code>o</code> is null, you get a <code>NullPointerException</code>, + * and if it is incompatible with the declaring class of the field, you + * get an <code>IllegalArgumentException</code>.<p> + * + * Next, if this Field enforces access control, your runtime context is + * evaluated, and you may have an <code>IllegalAccessException</code> if + * you could not access this field in similar compiled code. If the field + * is static, and its class is uninitialized, you trigger class + * initialization, which may end in a + * <code>ExceptionInInitializerError</code>.<p> + * + * Finally, the field is accessed, and primitives are wrapped (but not + * necessarily in new objects). This method accesses the field of the + * declaring class, even if the instance passed in belongs to a subclass + * which declares another field to hide this one. + * + * @param o the object to get the value of this Field from + * @return the value of the Field + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if <code>o</code> is not an instance of + * the class or interface declaring this field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #getBoolean(Object) + * @see #getByte(Object) + * @see #getChar(Object) + * @see #getShort(Object) + * @see #getInt(Object) + * @see #getLong(Object) + * @see #getFloat(Object) + * @see #getDouble(Object) + */ + public native Object get(Object o) + throws IllegalAccessException; + + /** + * Get the value of this boolean Field. If the field is static, + * <code>o</code> will be ignored. + * + * @param o the object to get the value of this Field from + * @return the value of the Field + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if this is not a boolean field of + * <code>o</code>, or if <code>o</code> is not an instance of the + * declaring class of this field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #get(Object) + */ + public native boolean getBoolean(Object o) + throws IllegalAccessException; + + /** + * Get the value of this byte Field. If the field is static, + * <code>o</code> will be ignored. + * + * @param o the object to get the value of this Field from + * @return the value of the Field + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if this is not a byte field of + * <code>o</code>, or if <code>o</code> is not an instance of the + * declaring class of this field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #get(Object) + */ + public native byte getByte(Object o) + throws IllegalAccessException; + + /** + * Get the value of this Field as a char. If the field is static, + * <code>o</code> will be ignored. + * + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if this is not a char field of + * <code>o</code>, or if <code>o</code> is not an instance + * of the declaring class of this field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #get(Object) + */ + public native char getChar(Object o) + throws IllegalAccessException; + + /** + * Get the value of this Field as a short. If the field is static, + * <code>o</code> will be ignored. + * + * @param o the object to get the value of this Field from + * @return the value of the Field + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if this is not a byte or short + * field of <code>o</code>, or if <code>o</code> is not an instance + * of the declaring class of this field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #get(Object) + */ + public native short getShort(Object o) + throws IllegalAccessException; + + /** + * Get the value of this Field as an int. If the field is static, + * <code>o</code> will be ignored. + * + * @param o the object to get the value of this Field from + * @return the value of the Field + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if this is not a byte, short, char, or + * int field of <code>o</code>, or if <code>o</code> is not an + * instance of the declaring class of this field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #get(Object) + */ + public native int getInt(Object o) + throws IllegalAccessException; + + /** + * Get the value of this Field as a long. If the field is static, + * <code>o</code> will be ignored. + * + * @param o the object to get the value of this Field from + * @return the value of the Field + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if this is not a byte, short, char, int, + * or long field of <code>o</code>, or if <code>o</code> is not an + * instance of the declaring class of this field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #get(Object) + */ + public native long getLong(Object o) + throws IllegalAccessException; + + /** + * Get the value of this Field as a float. If the field is static, + * <code>o</code> will be ignored. + * + * @param o the object to get the value of this Field from + * @return the value of the Field + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if this is not a byte, short, char, int, + * long, or float field of <code>o</code>, or if <code>o</code> is + * not an instance of the declaring class of this field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #get(Object) + */ + public native float getFloat(Object o) + throws IllegalAccessException; + + /** + * Get the value of this Field as a double. If the field is static, + * <code>o</code> will be ignored. + * + * @param o the object to get the value of this Field from + * @return the value of the Field + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if this is not a byte, short, char, int, + * long, float, or double field of <code>o</code>, or if + * <code>o</code> is not an instance of the declaring class of this + * field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #get(Object) + */ + public native double getDouble(Object o) + throws IllegalAccessException; + + /** + * Set the value of this Field. If it is a primitive field, the value + * will be unwrapped from the passed object (boolean = java.lang.Boolean).<p> + * + * If the field is static, <code>o</code> will be ignored. Otherwise, if + * <code>o</code> is null, you get a <code>NullPointerException</code>, + * and if it is incompatible with the declaring class of the field, you + * get an <code>IllegalArgumentException</code>.<p> + * + * Next, if this Field enforces access control, your runtime context is + * evaluated, and you may have an <code>IllegalAccessException</code> if + * you could not access this field in similar compiled code. This also + * occurs whether or not there is access control if the field is final. + * If the field is primitive, and unwrapping your argument fails, you will + * get an <code>IllegalArgumentException</code>; likewise, this error + * happens if <code>value</code> cannot be cast to the correct object type. + * If the field is static, and its class is uninitialized, you trigger class + * initialization, which may end in a + * <code>ExceptionInInitializerError</code>.<p> + * + * Finally, the field is set with the widened value. This method accesses + * the field of the declaring class, even if the instance passed in belongs + * to a subclass which declares another field to hide this one. + * + * @param o the object to set this Field on + * @param value the value to set this Field to + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if <code>value</code> cannot be + * converted by a widening conversion to the underlying type of + * the Field, or if <code>o</code> is not an instance of the class + * declaring this field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #setBoolean(Object, boolean) + * @see #setByte(Object, byte) + * @see #setChar(Object, char) + * @see #setShort(Object, short) + * @see #setInt(Object, int) + * @see #setLong(Object, long) + * @see #setFloat(Object, float) + * @see #setDouble(Object, double) + */ + public native void set(Object o, Object value) + throws IllegalAccessException; + + /** + * Set this boolean Field. If the field is static, <code>o</code> will be + * ignored. + * + * @param o the object to set this Field on + * @param value the value to set this Field to + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if this is not a boolean field, or if + * <code>o</code> is not an instance of the class declaring this + * field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #set(Object, Object) + */ + public native void setBoolean(Object o, boolean value) + throws IllegalAccessException; + + /** + * Set this byte Field. If the field is static, <code>o</code> will be + * ignored. + * + * @param o the object to set this Field on + * @param value the value to set this Field to + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if this is not a byte, short, int, long, + * float, or double field, or if <code>o</code> is not an instance + * of the class declaring this field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #set(Object, Object) + */ + public native void setByte(Object o, byte value) + throws IllegalAccessException; + + /** + * Set this char Field. If the field is static, <code>o</code> will be + * ignored. + * + * @param o the object to set this Field on + * @param value the value to set this Field to + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if this is not a char, int, long, + * float, or double field, or if <code>o</code> is not an instance + * of the class declaring this field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #set(Object, Object) + */ + public native void setChar(Object o, char value) + throws IllegalAccessException; + + /** + * Set this short Field. If the field is static, <code>o</code> will be + * ignored. + * + * @param o the object to set this Field on + * @param value the value to set this Field to + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if this is not a short, int, long, + * float, or double field, or if <code>o</code> is not an instance + * of the class declaring this field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #set(Object, Object) + */ + public native void setShort(Object o, short value) + throws IllegalAccessException; + + /** + * Set this int Field. If the field is static, <code>o</code> will be + * ignored. + * + * @param o the object to set this Field on + * @param value the value to set this Field to + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if this is not an int, long, float, or + * double field, or if <code>o</code> is not an instance of the + * class declaring this field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #set(Object, Object) + */ + public native void setInt(Object o, int value) + throws IllegalAccessException; + + /** + * Set this long Field. If the field is static, <code>o</code> will be + * ignored. + * + * @param o the object to set this Field on + * @param value the value to set this Field to + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if this is not a long, float, or double + * field, or if <code>o</code> is not an instance of the class + * declaring this field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #set(Object, Object) + */ + public native void setLong(Object o, long value) + throws IllegalAccessException; + + /** + * Set this float Field. If the field is static, <code>o</code> will be + * ignored. + * + * @param o the object to set this Field on + * @param value the value to set this Field to + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if this is not a float or long field, or + * if <code>o</code> is not an instance of the class declaring this + * field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #set(Object, Object) + */ + public native void setFloat(Object o, float value) + throws IllegalAccessException; + + /** + * Set this double Field. If the field is static, <code>o</code> will be + * ignored. + * + * @param o the object to set this Field on + * @param value the value to set this Field to + * @throws IllegalAccessException if you could not normally access this field + * (i.e. it is not public) + * @throws IllegalArgumentException if this is not a double field, or if + * <code>o</code> is not an instance of the class declaring this + * field + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #set(Object, Object) + */ + public native void setDouble(Object o, double value) + throws IllegalAccessException; +} diff --git a/libjava/classpath/vm/reference/java/lang/reflect/Method.java b/libjava/classpath/vm/reference/java/lang/reflect/Method.java new file mode 100644 index 0000000..f289e77 --- /dev/null +++ b/libjava/classpath/vm/reference/java/lang/reflect/Method.java @@ -0,0 +1,339 @@ +/* java.lang.reflect.Method - reflection of Java methods + Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.lang.reflect; + +import java.util.Arrays; + +/** + * The Method class represents a member method of a class. It also allows + * dynamic invocation, via reflection. This works for both static and + * instance methods. Invocation on Method objects knows how to do + * widening conversions, but throws {@link IllegalArgumentException} if + * a narrowing conversion would be necessary. You can query for information + * on this Method regardless of location, but invocation access may be limited + * by Java language access controls. If you can't do it in the compiler, you + * can't normally do it here either.<p> + * + * <B>Note:</B> This class returns and accepts types as Classes, even + * primitive types; there are Class types defined that represent each + * different primitive type. They are <code>java.lang.Boolean.TYPE, + * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class, + * byte.class</code>, etc. These are not to be confused with the + * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are + * real classes.<p> + * + * Also note that this is not a serializable class. It is entirely feasible + * to make it serializable using the Externalizable interface, but this is + * on Sun, not me. + * + * @author John Keiser + * @author Eric Blake <ebb9@email.byu.edu> + * @see Member + * @see Class + * @see java.lang.Class#getMethod(String,Object[]) + * @see java.lang.Class#getDeclaredMethod(String,Object[]) + * @see java.lang.Class#getMethods() + * @see java.lang.Class#getDeclaredMethods() + * @since 1.1 + * @status updated to 1.4 + */ +public final class Method +extends AccessibleObject implements Member +{ + Class declaringClass; + String name; + int slot; + + /** + * This class is uninstantiable. + */ + private Method(Class declaringClass, String name, int slot) + { + this.declaringClass = declaringClass; + this.name = name; + this.slot = slot; + } + + /** + * Gets the class that declared this method, or the class where this method + * is a non-inherited member. + * @return the class that declared this member + */ + public Class getDeclaringClass() + { + return declaringClass; + } + + /** + * Gets the name of this method. + * @return the name of this method + */ + public String getName() + { + return name; + } + + /** + * Gets the modifiers this method uses. Use the <code>Modifier</code> + * class to interpret the values. A method can only have a subset of the + * following modifiers: public, private, protected, abstract, static, + * final, synchronized, native, and strictfp. + * + * @return an integer representing the modifiers to this Member + * @see Modifier + */ + public native int getModifiers(); + + /** + * Gets the return type of this method. + * @return the type of this method + */ + public native Class getReturnType(); + + /** + * Get the parameter list for this method, in declaration order. If the + * method takes no parameters, returns a 0-length array (not null). + * + * @return a list of the types of the method's parameters + */ + public native Class[] getParameterTypes(); + + /** + * Get the exception types this method says it throws, in no particular + * order. If the method has no throws clause, returns a 0-length array + * (not null). + * + * @return a list of the types in the method's throws clause + */ + public native Class[] getExceptionTypes(); + + /** + * Compare two objects to see if they are semantically equivalent. + * Two Methods are semantically equivalent if they have the same declaring + * class, name, parameter list, and return type. + * + * @param o the object to compare to + * @return <code>true</code> if they are equal; <code>false</code> if not + */ + public boolean equals(Object o) + { + // Implementation note: + // The following is a correct but possibly slow implementation. + // + // This class has a private field 'slot' that could be used by + // the VM implementation to "link" a particular method to a Class. + // In that case equals could be simply implemented as: + // + // if (o instanceof Method) + // { + // Method m = (Method)o; + // return m.declaringClass == this.declaringClass + // && m.slot == this.slot; + // } + // return false; + // + // If a VM uses the Method class as their native/internal representation + // then just using the following would be optimal: + // + // return this == o; + // + if (!(o instanceof Method)) + return false; + Method that = (Method)o; + if (this.getDeclaringClass() != that.getDeclaringClass()) + return false; + if (!this.getName().equals(that.getName())) + return false; + if (this.getReturnType() != that.getReturnType()) + return false; + if (!Arrays.equals(this.getParameterTypes(), that.getParameterTypes())) + return false; + return true; + } + + /** + * Get the hash code for the Method. The Method hash code is the hash code + * of its name XOR'd with the hash code of its class name. + * + * @return the hash code for the object + */ + public int hashCode() + { + return getDeclaringClass().getName().hashCode() ^ getName().hashCode(); + } + + /** + * Get a String representation of the Method. A Method's String + * representation is "<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() + { + // 128 is a reasonable buffer initial size for constructor + StringBuffer sb = new StringBuffer(128); + Modifier.toString(getModifiers(), sb).append(' '); + sb.append(getUserTypeName(getReturnType().getName())).append(' '); + sb.append(getDeclaringClass().getName()).append('.'); + sb.append(getName()).append('('); + Class[] c = getParameterTypes(); + if (c.length > 0) + { + sb.append(getUserTypeName(c[0].getName())); + for (int i = 1; i < c.length; i++) + sb.append(',').append(getUserTypeName(c[i].getName())); + } + sb.append(')'); + c = getExceptionTypes(); + if (c.length > 0) + { + sb.append(" throws ").append(c[0].getName()); + for (int i = 1; i < c.length; i++) + sb.append(',').append(c[i].getName()); + } + return sb.toString(); + } + + private static String getUserTypeName(String typeSpec) + { + int pos = 0; + String typeName = ""; + String arrayPart = ""; + + while (typeSpec.charAt(pos) == '[') + { + arrayPart += "[]"; + ++pos; + } + + switch (typeSpec.charAt(pos)) + { + case 'Z': + typeName = "boolean"; + break; + case 'B': + typeName = "byte"; + break; + case 'C': + typeName = "char"; + break; + case 'D': + typeName = "double"; + break; + case 'F': + typeName = "float"; + break; + case 'I': + typeName = "int"; + break; + case 'J': + typeName = "long"; + break; + case 'S': + typeName = "short"; + break; + case 'L': + typeName = typeSpec.substring(pos + 1, typeSpec.length() - 1); + break; + default: + typeName = typeSpec; + break; + } + + return typeName + arrayPart; + } + + /** + * Invoke the method. Arguments are automatically unwrapped and widened, + * and the result is automatically wrapped, if needed.<p> + * + * If the method is static, <code>o</code> will be ignored. Otherwise, + * the method uses dynamic lookup as described in JLS 15.12.4.4. You cannot + * mimic the behavior of nonvirtual lookup (as in super.foo()). This means + * you will get a <code>NullPointerException</code> if <code>o</code> is + * null, and an <code>IllegalArgumentException</code> if it is incompatible + * with the declaring class of the method. If the method takes 0 arguments, + * you may use null or a 0-length array for <code>args</code>.<p> + * + * Next, if this Method enforces access control, your runtime context is + * evaluated, and you may have an <code>IllegalAccessException</code> if + * you could not acces this method in similar compiled code. If the method + * is static, and its class is uninitialized, you trigger class + * initialization, which may end in a + * <code>ExceptionInInitializerError</code>.<p> + * + * Finally, the method is invoked. If it completes normally, the return value + * will be null for a void method, a wrapped object for a primitive return + * method, or the actual return of an Object method. If it completes + * abruptly, the exception is wrapped in an + * <code>InvocationTargetException</code>. + * + * @param o the object to invoke the method on + * @param args the arguments to the method + * @return the return value of the method, wrapped in the appropriate + * wrapper if it is primitive + * @throws IllegalAccessException if the method could not normally be called + * by the Java code (i.e. it is not public) + * @throws IllegalArgumentException if the number of arguments is incorrect; + * if the arguments types are wrong even with a widening conversion; + * or if <code>o</code> is not an instance of the class or interface + * declaring this method + * @throws InvocationTargetException if the method throws an exception + * @throws NullPointerException if <code>o</code> is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static method triggered + * class initialization, which then failed + */ + public Object invoke(Object o, Object[] args) + throws IllegalAccessException, InvocationTargetException + { + return invokeNative(o, args, declaringClass, slot); + } + + /* + * NATIVE HELPERS + */ + + private native Object invokeNative(Object o, Object[] args, + Class declaringClass, int slot) + throws IllegalAccessException, InvocationTargetException; +} diff --git a/libjava/classpath/vm/reference/java/net/VMInetAddress.java b/libjava/classpath/vm/reference/java/net/VMInetAddress.java new file mode 100644 index 0000000..1253ded --- /dev/null +++ b/libjava/classpath/vm/reference/java/net/VMInetAddress.java @@ -0,0 +1,93 @@ +/* VMInetAddress.java -- Class to model an Internet address + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.net; + +import gnu.classpath.Configuration; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamException; +import java.io.Serializable; +import java.util.HashMap; +import java.util.StringTokenizer; + +class VMInetAddress implements Serializable +{ + static + { + if (Configuration.INIT_LOAD_LIBRARY) + System.loadLibrary("javanet"); + } + + /** + * This method looks up the hostname of the local machine + * we are on. If the actual hostname cannot be determined, then the + * value "localhost" will be used. This native method wrappers the + * "gethostname" function. + * + * @return The local hostname. + */ + public static native String getLocalHostname(); + + /** + * Returns the value of the special address INADDR_ANY + */ + public static native byte[] lookupInaddrAny() throws UnknownHostException; + + /** + * This method returns the hostname for a given IP address. It will + * throw an UnknownHostException if the hostname cannot be determined. + * + * @param ip The IP address as a byte array + * + * @return The hostname + * + * @exception UnknownHostException If the reverse lookup fails + */ + public static native String getHostByAddr(byte[] ip) + throws UnknownHostException; + + /** + * Returns a list of all IP addresses for a given hostname. Will throw + * an UnknownHostException if the hostname cannot be resolved. + */ + public static native byte[][] getHostByName(String hostname) + throws UnknownHostException; +} diff --git a/libjava/classpath/vm/reference/java/net/VMNetworkInterface.java b/libjava/classpath/vm/reference/java/net/VMNetworkInterface.java new file mode 100644 index 0000000..af71ce2 --- /dev/null +++ b/libjava/classpath/vm/reference/java/net/VMNetworkInterface.java @@ -0,0 +1,66 @@ +/* VMNetworkInterface.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.net; + +import gnu.classpath.Configuration; + +import java.util.Enumeration; +import java.util.Vector; + +/** + * This class models a network interface on the host computer. A network + * interface contains a name (typically associated with a specific + * hardware adapter) and a list of addresses that are bound to it. + * For example, an ethernet interface may be named "eth0" and have the + * address 192.168.1.101 assigned to it. + * + * @author Michael Koch (konqueror@gmx.de) + * @since 1.4 + */ +final class VMNetworkInterface +{ + static + { + if (Configuration.INIT_LOAD_LIBRARY) + System.loadLibrary("javanet"); + } + + public static native Vector getInterfaces() + throws SocketException; +} diff --git a/libjava/classpath/vm/reference/java/nio/VMDirectByteBuffer.java b/libjava/classpath/vm/reference/java/nio/VMDirectByteBuffer.java new file mode 100644 index 0000000..e42f5038 --- /dev/null +++ b/libjava/classpath/vm/reference/java/nio/VMDirectByteBuffer.java @@ -0,0 +1,66 @@ +/* VMDirectByteBuffer.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.nio; + +import gnu.classpath.Configuration; +import gnu.classpath.RawData; + +final class VMDirectByteBuffer +{ + static + { + // load the shared library needed for native methods. + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary("javanio"); + } + + init(); + } + + private static native void init(); + + static native RawData allocate (int capacity); + static native void free(RawData address); + static native byte get(RawData address, int index); + static native void get(RawData address, int index, byte[] dst, int offset, int length); + static native void put(RawData address, int index, byte value); + static native RawData adjustAddress(RawData address, int offset); + static native void shiftDown(RawData address, int dst_offset, int src_offset, int count); +} diff --git a/libjava/classpath/vm/reference/java/nio/channels/VMChannels.java b/libjava/classpath/vm/reference/java/nio/channels/VMChannels.java new file mode 100644 index 0000000..e58d7fb --- /dev/null +++ b/libjava/classpath/vm/reference/java/nio/channels/VMChannels.java @@ -0,0 +1,116 @@ +/* VMChannels.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.nio.channels; + +import gnu.java.nio.ChannelInputStream; +import gnu.java.nio.ChannelOutputStream; +import gnu.java.nio.channels.FileChannelImpl; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +final class VMChannels +{ + /** + * This class isn't intended to be instantiated. + */ + private VMChannels() + { + // Do nothing here. + } + + private static Object createStream(Class streamClass, Channel ch) + { + try + { + Class[] argTypes = new Class[1]; + argTypes[0] = FileChannelImpl.class; + Constructor constructor = + streamClass.getDeclaredConstructor(argTypes); + constructor.setAccessible(true); + Object[] args = new Object[1]; + args[0] = ch; + return constructor.newInstance(args); + } + catch (IllegalAccessException e) + { + // Ignored. + } + catch (InstantiationException e) + { + // Ignored. + } + catch (InvocationTargetException e) + { + // Ignored. + } + catch (NoSuchMethodException e) + { + // Ignored. + } + + return null; + } + + /** + * Constructs a stream that reads bytes from the given channel. + */ + static InputStream newInputStream(ReadableByteChannel ch) + { + if (ch instanceof FileChannelImpl) + return (FileInputStream) createStream(FileInputStream.class, ch); + + return new ChannelInputStream(ch); + } + + /** + * Constructs a stream that writes bytes to the given channel. + */ + static OutputStream newOutputStream(WritableByteChannel ch) + { + if (ch instanceof FileChannelImpl) + return (FileOutputStream) createStream(FileOutputStream.class, ch); + + return new ChannelOutputStream(ch); + } +} diff --git a/libjava/classpath/vm/reference/java/security/VMAccessController.java b/libjava/classpath/vm/reference/java/security/VMAccessController.java new file mode 100644 index 0000000..7058a5e --- /dev/null +++ b/libjava/classpath/vm/reference/java/security/VMAccessController.java @@ -0,0 +1,260 @@ +/* VMAccessController.java -- VM-specific access controller methods. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.security; + +import java.util.HashSet; +import java.util.LinkedList; + +final class VMAccessController +{ + + // Fields. + // ------------------------------------------------------------------------- + + /** + * This is a per-thread stack of AccessControlContext objects (which can + * be null) for each call to AccessController.doPrivileged in each thread's + * call stack. We use this to remember which context object corresponds to + * which call. + */ + private static final ThreadLocal contexts = new ThreadLocal(); + + /** + * This is a Boolean that, if set, tells getContext that it has already + * been called once, allowing us to handle recursive permission checks + * caused by methods getContext calls. + */ + private static final ThreadLocal inGetContext = new ThreadLocal(); + + /** + * And we return this all-permissive context to ensure that privileged + * methods called from getContext succeed. + */ + private static final AccessControlContext DEFAULT_CONTEXT; + static + { + CodeSource source = new CodeSource(null, null); + Permissions permissions = new Permissions(); + permissions.add(new AllPermission()); + ProtectionDomain[] domain = new ProtectionDomain[] { + new ProtectionDomain(source, permissions) + }; + DEFAULT_CONTEXT = new AccessControlContext(domain); + } + + private static final boolean DEBUG = false; + private static void debug(String msg) + { + System.err.print(">>> VMAccessController: "); + System.err.println(msg); + } + + // Constructors. + // ------------------------------------------------------------------------- + + private VMAccessController() { } + + // Class methods. + // ------------------------------------------------------------------------- + + /** + * Relate a class (which should be an instance of {@link PrivilegedAction} + * with an access control context. This method is used by {@link + * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)} + * to set up the context that will be returned by {@link #getContext()}. + * This method relates the class to the current thread, so contexts + * pushed from one thread will not be available to another. + * + * @param acc The access control context. + */ + static void pushContext (AccessControlContext acc) + { + if (DEBUG) + debug("pushing " + acc); + LinkedList stack = (LinkedList) contexts.get(); + if (stack == null) + { + stack = new LinkedList(); + contexts.set(stack); + } + stack.addFirst(acc); + } + + /** + * Removes the relation of a class to an {@link AccessControlContext}. + * This method is used by {@link AccessController} when exiting from a + * call to {@link + * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}. + */ + static void popContext() + { + if (DEBUG) + debug("popping context"); + + // Stack should never be null, nor should it be empty, if this method + // and its counterpart has been called properly. + LinkedList stack = (LinkedList) contexts.get(); + if (stack != null) + { + stack.removeFirst(); + if (stack.isEmpty()) + contexts.set(null); + } + } + + /** + * Examine the method stack of the currently running thread, and create + * an {@link AccessControlContext} filled in with the appropriate {@link + * ProtectionDomain} objects given this stack. + * + * @return The context. + */ + static AccessControlContext getContext() + { + // If we are already in getContext, but called a method that needs + // a permission check, return the all-permissive context so methods + // called from here succeed. + // + // XXX is this necessary? We should verify if there are any calls in + // the stack below this method that require permission checks. + Boolean inCall = (Boolean) inGetContext.get(); + if (inCall != null && inCall.booleanValue()) + { + if (DEBUG) + debug("already in getContext"); + return DEFAULT_CONTEXT; + } + + inGetContext.set(Boolean.TRUE); + + Object[][] stack = getStack(); + Class[] classes = (Class[]) stack[0]; + String[] methods = (String[]) stack[1]; + + if (DEBUG) + debug(">>> got trace of length " + classes.length); + + HashSet domains = new HashSet(); + HashSet seenDomains = new HashSet(); + AccessControlContext context = null; + int privileged = 0; + + // We walk down the stack, adding each ProtectionDomain for each + // class in the call stack. If we reach a call to doPrivileged, + // we don't add any more stack frames. We skip the first three stack + // frames, since they comprise the calls to getStack, getContext, + // and AccessController.getContext. + for (int i = 3; i < classes.length && privileged < 2; i++) + { + Class clazz = classes[i]; + String method = methods[i]; + + if (DEBUG) + { + debug(">>> checking " + clazz + "." + method); + debug(">>> loader = " + clazz.getClassLoader()); + } + + // If the previous frame was a call to doPrivileged, then this is + // the last frame we look at. + if (privileged == 1) + privileged = 2; + + if (clazz.equals (AccessController.class) + && method.equals ("doPrivileged")) + { + // If there was a call to doPrivileged with a supplied context, + // return that context. + LinkedList l = (LinkedList) contexts.get(); + if (l != null) + context = (AccessControlContext) l.getFirst(); + privileged = 1; + } + + ProtectionDomain domain = clazz.getProtectionDomain(); + + if (domain == null) + continue; + if (seenDomains.contains(domain)) + continue; + seenDomains.add(domain); + + // Create a static snapshot of this domain, which may change over time + // if the current policy changes. + domains.add(new ProtectionDomain(domain.getCodeSource(), + domain.getPermissions())); + } + + if (DEBUG) + debug("created domains: " + domains); + + ProtectionDomain[] result = (ProtectionDomain[]) + domains.toArray(new ProtectionDomain[domains.size()]); + + // Intersect the derived protection domain with the context supplied + // to doPrivileged. + if (context != null) + context = new AccessControlContext(result, context, + IntersectingDomainCombiner.SINGLETON); + // No context was supplied. Return the derived one. + else + context = new AccessControlContext(result); + + inGetContext.set(Boolean.FALSE); + return context; + } + + /** + * Returns a snapshot of the current call stack as a pair of arrays: + * the first an array of classes in the call stack, the second an array + * of strings containing the method names in the call stack. The two + * arrays match up, meaning that method <i>i</i> is declared in class + * <i>i</i>. The arrays are clean; it will only contain Java methods, + * and no element of the list should be null. + * + * <p>The default implementation returns an empty stack, which will be + * interpreted as having no permissions whatsoever. + * + * @return A pair of arrays describing the current call stack. The first + * element is an array of Class objects, and the second is an array + * of Strings comprising the method names. + */ + private static Object[][] getStack() + { + return new Object[][] { new Class[0], new String[0] }; + } +} diff --git a/libjava/classpath/vm/reference/java/util/VMTimeZone.java b/libjava/classpath/vm/reference/java/util/VMTimeZone.java new file mode 100644 index 0000000..86b6258 --- /dev/null +++ b/libjava/classpath/vm/reference/java/util/VMTimeZone.java @@ -0,0 +1,345 @@ +/* java.util.VMTimeZone + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +import gnu.classpath.Configuration; + +import java.io.*; + +/** + * + */ +final class VMTimeZone +{ + static + { + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary("javautil"); + } + } + + /** + * This method returns a time zone id string which is in the form + * (standard zone name) or (standard zone name)(GMT offset) or + * (standard zone name)(GMT offset)(daylight time zone name). The + * GMT offset can be in seconds, or where it is evenly divisible by + * 3600, then it can be in hours. The offset must be the time to + * add to the local time to get GMT. If a offset is given and the + * time zone observes daylight saving then the (daylight time zone + * name) must also be given (otherwise it is assumed the time zone + * does not observe any daylight savings). + * <p> + * The result of this method is given to the method + * TimeZone.getDefaultTimeZone(String) which tries to map the time + * zone id to a known TimeZone. See that method on how the returned + * String is mapped to a real TimeZone object. + * <p> + * The reference implementation which is made for GNU/Posix like + * systems calls <code>System.getenv("TZ")</code>, + * <code>readTimeZoneFile("/etc/timezone")</code>, + * <code>readtzFile("/etc/localtime")</code> and finally + * <code>getSystemTimeZoneId()</code> till a supported TimeZone is + * found through <code>TimeZone.getDefaultTimeZone(String)</code>. + * If every method fails <code>null</code> is returned (which means + * the TimeZone code will fall back on GMT as default time zone). + * <p> + * Note that this method is called inside a + * <code>AccessController.doPrivileged()</code> block and runs with + * the priviliges of the java.util system classes. It will only be + * called when the default time zone is not yet set, the system + * property user.timezone isn't set and it is requested for the + * first time. + */ + static TimeZone getDefaultTimeZoneId() + { + TimeZone zone = null; + + // See if TZ environment variable is set and accessible. + String tzid = System.getenv("TZ"); + if (tzid != null && !tzid.equals("")) + zone = TimeZone.getDefaultTimeZone(tzid); + + // Try to parse /etc/timezone. + if (zone == null) + { + tzid = readTimeZoneFile("/etc/timezone"); + if (tzid != null && !tzid.equals("")) + zone = TimeZone.getDefaultTimeZone(tzid); + } + + // Try to parse /etc/localtime + if (zone == null) + { + tzid = readtzFile("/etc/localtime"); + if (tzid != null && !tzid.equals("")) + zone = TimeZone.getDefaultTimeZone(tzid); + } + + // Try some system specific way + if (zone == null) + { + tzid = getSystemTimeZoneId(); + if (tzid != null && !tzid.equals("")) + zone = TimeZone.getDefaultTimeZone(tzid); + } + + return zone; + } + + /** + * Tries to read the time zone name from a file. Only the first + * consecutive letters, digits, slashes, dashes and underscores are + * read from the file. If the file cannot be read or an IOException + * occurs null is returned. + * <p> + * The /etc/timezone file is not standard, but a lot of systems have + * it. If it exist the first line always contains a string + * describing the timezone of the host of domain. Some systems + * contain a /etc/TIMEZONE file which is used to set the TZ + * environment variable (which is checked before /etc/timezone is + * read). + */ + private static String readTimeZoneFile(String file) + { + File f = new File(file); + if (!f.exists()) + return null; + + InputStreamReader isr = null; + try + { + FileInputStream fis = new FileInputStream(f); + BufferedInputStream bis = new BufferedInputStream(fis); + isr = new InputStreamReader(bis); + + StringBuffer sb = new StringBuffer(); + int i = isr.read(); + while (i != -1) + { + char c = (char) i; + if (Character.isLetter(c) || Character.isDigit(c) + || c == '/' || c == '-' || c == '_') + { + sb.append(c); + i = isr.read(); + } + else + break; + } + return sb.toString(); + } + catch (IOException ioe) + { + // Parse error, not a proper tzfile. + return null; + } + finally + { + try + { + if (isr != null) + isr.close(); + } + catch (IOException ioe) + { + // Error while close, nothing we can do. + } + } + } + + /** + * Tries to read a file as a "standard" tzfile and return a time + * zone id string as expected by <code>getDefaultTimeZone(String)</code>. + * If the file doesn't exist, an IOException occurs or it isn't a tzfile + * that can be parsed null is returned. + * <p> + * The tzfile structure (as also used by glibc) is described in the Olson + * tz database archive as can be found at + * <code>ftp://elsie.nci.nih.gov/pub/</code>. + * <p> + * At least the following platforms support the tzdata file format + * and /etc/localtime (GNU/Linux, Darwin, Solaris and FreeBSD at + * least). Some systems (like Darwin) don't start the file with the + * required magic bytes 'TZif', this implementation can handle + * that). + */ + private static String readtzFile(String file) + { + File f = new File(file); + if (!f.exists()) + return null; + + DataInputStream dis = null; + try + { + FileInputStream fis = new FileInputStream(f); + BufferedInputStream bis = new BufferedInputStream(fis); + dis = new DataInputStream(bis); + + // Make sure we are reading a tzfile. + byte[] tzif = new byte[4]; + dis.readFully(tzif); + if (tzif[0] == 'T' && tzif[1] == 'Z' + && tzif[2] == 'i' && tzif[3] == 'f') + // Reserved bytes, ttisgmtcnt, ttisstdcnt and leapcnt + skipFully(dis, 16 + 3 * 4); + else + // Darwin has tzdata files that don't start with the TZif marker + skipFully(dis, 16 + 3 * 4 - 4); + + int timecnt = dis.readInt(); + int typecnt = dis.readInt(); + if (typecnt > 0) + { + int charcnt = dis.readInt(); + // Transition times plus indexed transition times. + skipFully(dis, timecnt * (4 + 1)); + + // Get last gmt_offset and dst/non-dst time zone names. + int abbrind = -1; + int dst_abbrind = -1; + int gmt_offset = 0; + while (typecnt-- > 0) + { + // gmtoff + int offset = dis.readInt(); + int dst = dis.readByte(); + if (dst == 0) + { + abbrind = dis.readByte(); + gmt_offset = offset; + } + else + dst_abbrind = dis.readByte(); + } + + // gmt_offset is the offset you must add to UTC/GMT to + // get the local time, we need the offset to add to + // the local time to get UTC/GMT. + gmt_offset *= -1; + + // Turn into hours if possible. + if (gmt_offset % 3600 == 0) + gmt_offset /= 3600; + + if (abbrind >= 0) + { + byte[] names = new byte[charcnt]; + dis.readFully(names); + int j = abbrind; + while (j < charcnt && names[j] != 0) + j++; + + String zonename = new String(names, abbrind, j - abbrind, + "ASCII"); + + String dst_zonename; + if (dst_abbrind >= 0) + { + j = dst_abbrind; + while (j < charcnt && names[j] != 0) + j++; + dst_zonename = new String(names, dst_abbrind, + j - dst_abbrind, "ASCII"); + } + else + dst_zonename = ""; + + // Only use gmt offset when necessary. + // Also special case GMT+/- timezones. + String offset_string; + if ("".equals(dst_zonename) + && (gmt_offset == 0 + || zonename.startsWith("GMT+") + || zonename.startsWith("GMT-"))) + offset_string = ""; + else + offset_string = Integer.toString(gmt_offset); + + String id = zonename + offset_string + dst_zonename; + + return id; + } + } + + // Something didn't match while reading the file. + return null; + } + catch (IOException ioe) + { + // Parse error, not a proper tzfile. + return null; + } + finally + { + try + { + if (dis != null) + dis.close(); + } + catch(IOException ioe) + { + // Error while close, nothing we can do. + } + } + } + + /** + * Skips the requested number of bytes in the given InputStream. + * Throws EOFException if not enough bytes could be skipped. + * Negative numbers of bytes to skip are ignored. + */ + private static void skipFully(InputStream is, long l) throws IOException + { + while (l > 0) + { + long k = is.skip(l); + if (k <= 0) + throw new EOFException(); + l -= k; + } + } + + /** + * Tries to get the system time zone id through native code. + */ + private static native String getSystemTimeZoneId(); +} |