|
From: <ls...@us...> - 2007-01-07 05:41:45
|
Revision: 2994
http://jnode.svn.sourceforge.net/jnode/?rev=2994&view=rev
Author: lsantha
Date: 2007-01-06 21:41:44 -0800 (Sat, 06 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/lang/System.java
trunk/core/src/classpath/java/java/security/PrivilegedExceptionAction.java
trunk/core/src/classpath/vm/java/lang/Thread.java
Modified: trunk/core/src/classpath/java/java/lang/System.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/System.java 2007-01-07 05:41:17 UTC (rev 2993)
+++ trunk/core/src/classpath/java/java/lang/System.java 2007-01-07 05:41:44 UTC (rev 2994)
@@ -44,6 +44,14 @@
import java.io.InputStream;
import java.io.PrintStream;
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.Properties;
import java.util.PropertyPermission;
@@ -98,6 +106,11 @@
public static final PrintStream err = VMSystem.makeStandardErrorStream();
/**
+ * A cached copy of the environment variable map.
+ */
+ private static Map<String,String> environmentMap;
+
+ /**
* This class is uninstantiable.
*/
private System()
@@ -118,6 +131,7 @@
SecurityManager sm = SecurityManager.current; // Be thread-safe.
if (sm != null)
sm.checkPermission(new RuntimePermission("setIO"));
+
VMSystem.setIn(in);
}
@@ -223,6 +237,38 @@
}
/**
+ * <p>
+ * Returns the current value of a nanosecond-precise system timer.
+ * The value of the timer is an offset relative to some arbitrary fixed
+ * time, which may be in the future (making the value negative). This
+ * method is useful for timing events where nanosecond precision is
+ * required. This is achieved by calling this method before and after the
+ * event, and taking the difference betweent the two times:
+ * </p>
+ * <p>
+ * <code>long startTime = System.nanoTime();</code><br />
+ * <code>... <emph>event code</emph> ...</code><br />
+ * <code>long endTime = System.nanoTime();</code><br />
+ * <code>long duration = endTime - startTime;</code><br />
+ * </p>
+ * <p>
+ * Note that the value is only nanosecond-precise, and not accurate; there
+ * is no guarantee that the difference between two values is really a
+ * nanosecond. Also, the value is prone to overflow if the offset
+ * exceeds 2^63.
+ * </p>
+ *
+ * @return the time of a system timer in nanoseconds.
+ * @since 1.5
+ */
+ public static long nanoTime()
+ {
+ //todo
+ throw new RuntimeException("Implement it");
+ //return VMSystem.nanoTime();
+ }
+
+ /**
* Copy one array onto another from <code>src[srcStart]</code> ...
* <code>src[srcStart+len-1]</code> to <code>dest[destStart]</code> ...
* <code>dest[destStart+len-1]</code>. First, the arguments are validated:
@@ -319,6 +365,7 @@
* <dt>gnu.java.io.encoding_scheme_alias.iso-latin-_?</dt> <dd>8859_?</dd>
* <dt>gnu.java.io.encoding_scheme_alias.latin?</dt> <dd>8859_?</dd>
* <dt>gnu.java.io.encoding_scheme_alias.utf-8</dt> <dd>UTF8</dd>
+ * <dt>gnu.javax.print.server</dt> <dd>Hostname of external CUPS server.</dd>
* </dl>
*
* @return the system properties, will never be null
@@ -364,7 +411,7 @@
SecurityManager sm = SecurityManager.current; // Be thread-safe.
if (sm != null)
sm.checkPropertyAccess(key);
- else if (key.length() == 0)
+ if (key.length() == 0)
throw new IllegalArgumentException("key can't be empty");
return SystemProperties.getProperty(key);
}
@@ -385,6 +432,10 @@
SecurityManager sm = SecurityManager.current; // Be thread-safe.
if (sm != null)
sm.checkPropertyAccess(key);
+ // This handles both the null pointer exception and the illegal
+ // argument exception.
+ if (key.length() == 0)
+ throw new IllegalArgumentException("key can't be empty");
return SystemProperties.getProperty(key, def);
}
@@ -405,6 +456,10 @@
SecurityManager sm = SecurityManager.current; // Be thread-safe.
if (sm != null)
sm.checkPermission(new PropertyPermission(key, "write"));
+ // This handles both the null pointer exception and the illegal
+ // argument exception.
+ if (key.length() == 0)
+ throw new IllegalArgumentException("key can't be empty");
return SystemProperties.setProperty(key, value);
}
Modified: trunk/core/src/classpath/java/java/security/PrivilegedExceptionAction.java
===================================================================
--- trunk/core/src/classpath/java/java/security/PrivilegedExceptionAction.java 2007-01-07 05:41:17 UTC (rev 2993)
+++ trunk/core/src/classpath/java/java/security/PrivilegedExceptionAction.java 2007-01-07 05:41:44 UTC (rev 2994)
@@ -46,9 +46,9 @@
*
* @author Aaron M. Renn (ar...@ur...)
* @since 1.1
- * @status updated to 1.4
+ * @status updated to 1.5
*/
-public interface PrivilegedExceptionAction
+public interface PrivilegedExceptionAction<T>
{
/**
* This method performs an operation that requires higher privileges to
@@ -61,5 +61,5 @@
* @see AccessController#doPrivileged(PrivilegedExceptionAction,
* AccessControlContext)
*/
- Object run() throws Exception;
+ T run() throws Exception;
} // interface PrivilegedExceptionAction
Modified: trunk/core/src/classpath/vm/java/lang/Thread.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/Thread.java 2007-01-07 05:41:17 UTC (rev 2993)
+++ trunk/core/src/classpath/vm/java/lang/Thread.java 2007-01-07 05:41:44 UTC (rev 2994)
@@ -262,6 +262,56 @@
InheritableThreadLocal.newChildThread(this); // FDy : CLASSPATH patch ?
}
+ /**
+ * Allocate a new Thread object, as if by
+ * <code>Thread(group, null, name)</code>, and give it the specified stack
+ * size, in bytes. The stack size is <b>highly platform independent</b>,
+ * and the virtual machine is free to round up or down, or ignore it
+ * completely. A higher value might let you go longer before a
+ * <code>StackOverflowError</code>, while a lower value might let you go
+ * longer before an <code>OutOfMemoryError</code>. Or, it may do absolutely
+ * nothing! So be careful, and expect to need to tune this value if your
+ * virtual machine even supports it.
+ *
+ * @param group the group to put the Thread into
+ * @param target the Runnable object to execute
+ * @param name the name for the Thread
+ * @param size the stack size, in bytes; 0 to be ignored
+ * @throws NullPointerException if name is null
+ * @throws SecurityException if this thread cannot access <code>group</code>
+ * @throws IllegalThreadStateException if group is destroyed
+ * @since 1.4
+ */
+ public Thread(ThreadGroup group, Runnable target, String name, long size)
+ {
+ Thread current = currentThread();
+
+ if (group != null) {
+ group.checkAccess();
+ } else {
+ group = current.getThreadGroup();
+ }
+
+ if (group == null) {
+ throw new InternalError("Live thread has invalid group: " + name);
+ }
+
+ group.addThread(this);
+
+ this.group = group;
+ this.target = target;
+ this.name = name;
+ this.parent = current;
+
+ this.daemon = current.isDaemon();
+
+ this.vmThread = VmProcessor.current().createThread(this);
+ this.vmThread.setPriority(current.getPriority());
+ this.vmThread.updateName();
+
+ InheritableThreadLocal.newChildThread(this); // FDy : CLASSPATH patch ?
+ }
+
/**
* Create a new instance with a given group as containing group, a runnable
* as thread runner and a given name.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-07 05:43:42
|
Revision: 2997
http://jnode.svn.sourceforge.net/jnode/?rev=2997&view=rev
Author: lsantha
Date: 2007-01-06 21:43:40 -0800 (Sat, 06 Jan 2007)
Log Message:
-----------
Classpath patches.
Added Paths:
-----------
trunk/core/src/classpath/sun/
trunk/core/src/classpath/sun/sun/
trunk/core/src/classpath/sun/sun/misc/
trunk/core/src/classpath/sun/sun/misc/Service.java
trunk/core/src/classpath/sun/sun/misc/ServiceConfigurationError.java
trunk/core/src/classpath/sun/sun/reflect/
trunk/core/src/classpath/sun/sun/reflect/annotation/
trunk/core/src/classpath/sun/sun/reflect/annotation/AnnotationInvocationHandler.java
trunk/core/src/classpath/sun/sun/reflect/annotation/AnnotationParser.java
trunk/core/src/classpath/sun/sun/reflect/annotation/AnnotationType.java
trunk/core/src/classpath/sun/sun/reflect/annotation/EnumConstantNotPresentExceptionProxy.java
trunk/core/src/classpath/sun/sun/reflect/annotation/ExceptionProxy.java
Added: trunk/core/src/classpath/sun/sun/misc/Service.java
===================================================================
--- trunk/core/src/classpath/sun/sun/misc/Service.java (rev 0)
+++ trunk/core/src/classpath/sun/sun/misc/Service.java 2007-01-07 05:43:40 UTC (rev 2997)
@@ -0,0 +1,66 @@
+/* Service.java -- A wrapper around GNU service provision.
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package sun.misc;
+
+import gnu.classpath.ServiceFactory;
+
+import java.util.Iterator;
+
+public class Service
+{
+
+ /**
+ * Returns an {@link Iterator} over the service providers which
+ * provide a service of the given class, and are available from
+ * the specified classloader.
+ *
+ * @param c the service provider interface which must be
+ * implemented by any loaded service providers.
+ * @param cl the class loader that will be used to load the
+ * service providers, or <code>null</code> for the system class
+ * loader.
+ * @return an iterator over the service providers.
+ */
+ public static <P> Iterator<P> providers(Class<P> c, ClassLoader cl)
+ {
+ return (Iterator<P>) ServiceFactory.lookupProviders(c, cl);
+ }
+
+}
+
Added: trunk/core/src/classpath/sun/sun/misc/ServiceConfigurationError.java
===================================================================
--- trunk/core/src/classpath/sun/sun/misc/ServiceConfigurationError.java (rev 0)
+++ trunk/core/src/classpath/sun/sun/misc/ServiceConfigurationError.java 2007-01-07 05:43:40 UTC (rev 2997)
@@ -0,0 +1,64 @@
+/* ServiceConfigurationError.java -- An error from service configuration.
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package sun.misc;
+
+public class ServiceConfigurationError
+ extends Error
+{
+
+ /**
+ * Constructs a new {@link ServiceConfigurationError}
+ */
+ public ServiceConfigurationError()
+ {
+ super();
+ }
+
+ /**
+ * Constructs a new {@link ServiceConfigurationError}
+ * with the specified message.
+ */
+ public ServiceConfigurationError(String message)
+ {
+ super(message);
+ }
+
+
+}
+
Added: trunk/core/src/classpath/sun/sun/reflect/annotation/AnnotationInvocationHandler.java
===================================================================
--- trunk/core/src/classpath/sun/sun/reflect/annotation/AnnotationInvocationHandler.java (rev 0)
+++ trunk/core/src/classpath/sun/sun/reflect/annotation/AnnotationInvocationHandler.java 2007-01-07 05:43:40 UTC (rev 2997)
@@ -0,0 +1,340 @@
+/* sun.reflect.annotation.AnnotationInvocationHandler
+ Copyright (C) 2006
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package sun.reflect.annotation;
+
+import java.io.Serializable;
+import java.lang.annotation.AnnotationTypeMismatchException;
+import java.lang.annotation.IncompleteAnnotationException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * This class exists for serialization compatibility with the JDK.
+ * VMs can choose to implement annotations by constructing proxies
+ * with this invocation handler, but that is not required.
+ * If a different strategy for proxy objects is chosen, they can
+ * have a writeReplace method to substitute a Proxy based on this
+ * invocation handler is used for serialization.
+ */
+public final class AnnotationInvocationHandler
+ implements InvocationHandler, Serializable
+{
+ private static final long serialVersionUID = 6182022883658399397L;
+ private final Class type;
+ private final Map memberValues;
+
+ /**
+ * Construct a new invocation handler for an annotation proxy.
+ * Note that the VM is responsible for filling the memberValues map
+ * with the default values of all the annotation members.
+ */
+ public AnnotationInvocationHandler(Class type, Map memberValues)
+ {
+ this.type = type;
+ this.memberValues = memberValues;
+ }
+
+ /**
+ * Compare an instance of AnnotationInvocationHandler with another object.
+ * Note that the other object does not have to be an
+ * AnnotationInvocationHandler, any implementation of the annotation
+ * interface is allowed to be compared for equality.
+ * Note that this makes the equals method asymmetric, but this behavior
+ * is specified by Annotation.equals and identical to the JDK.
+ *
+ * This method is public for use by other parts of the VM. Some VMs
+ * (can) use different representations of annotations that reuse this
+ * method.
+ */
+ public static boolean equals(Class type, Map memberValues, Object other)
+ {
+ if (type.isInstance(other))
+ {
+ try
+ {
+ Method[] methods = type.getDeclaredMethods();
+ if (methods.length == memberValues.size())
+ {
+ for (int i = 0; i < methods.length; i++)
+ {
+ String key = methods[i].getName();
+ Object val = methods[i].invoke(other, new Object[0]);
+ if (! deepEquals(memberValues.get(key), val))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ catch (IllegalAccessException _)
+ {
+ // Ignore exception, like the JDK
+ }
+ catch (InvocationTargetException _)
+ {
+ // Ignore exception, like the JDK
+ }
+ }
+ return false;
+ }
+
+ private static boolean deepEquals(Object o1, Object o2)
+ {
+ if (o1 == o2)
+ return true;
+
+ if (o1 == null || o2 == null)
+ return false;
+
+ if (o1 instanceof boolean[] && o2 instanceof boolean[])
+ return Arrays.equals((boolean[]) o1, (boolean[]) o2);
+
+ if (o1 instanceof byte[] && o2 instanceof byte[])
+ return Arrays.equals((byte[]) o1, (byte[]) o2);
+
+ if (o1 instanceof char[] && o2 instanceof char[])
+ return Arrays.equals((char[]) o1, (char[]) o2);
+
+ if (o1 instanceof short[] && o2 instanceof short[])
+ return Arrays.equals((short[]) o1, (short[]) o2);
+
+ if (o1 instanceof int[] && o2 instanceof int[])
+ return Arrays.equals((int[]) o1, (int[]) o2);
+
+ if (o1 instanceof float[] && o2 instanceof float[])
+ return Arrays.equals((float[]) o1, (float[]) o2);
+
+ if (o1 instanceof long[] && o2 instanceof long[])
+ return Arrays.equals((long[]) o1, (long[]) o2);
+
+ if (o1 instanceof double[] && o2 instanceof double[])
+ return Arrays.equals((double[]) o1, (double[]) o2);
+
+ if (o1 instanceof Object[] && o2 instanceof Object[])
+ return Arrays.equals((Object[]) o1, (Object[]) o2);
+
+ return o1.equals(o2);
+ }
+
+ private static int deepHashCode(Object obj)
+ {
+ if (obj instanceof boolean[])
+ return Arrays.hashCode((boolean[]) obj);
+
+ if (obj instanceof byte[])
+ return Arrays.hashCode((byte[]) obj);
+
+ if (obj instanceof char[])
+ return Arrays.hashCode((char[]) obj);
+
+ if (obj instanceof short[])
+ return Arrays.hashCode((short[]) obj);
+
+ if (obj instanceof int[])
+ return Arrays.hashCode((int[]) obj);
+
+ if (obj instanceof float[])
+ return Arrays.hashCode((float[]) obj);
+
+ if (obj instanceof long[])
+ return Arrays.hashCode((long[]) obj);
+
+ if (obj instanceof double[])
+ return Arrays.hashCode((double[]) obj);
+
+ if (obj instanceof Object[])
+ return Arrays.hashCode((Object[]) obj);
+
+ return obj.hashCode();
+ }
+
+ /**
+ * Compute the hashCode for an annotation. Note that the algorithm is
+ * specified by Annotation.hashCode.
+ *
+ * This method is public for use by other parts of the VM. Some VMs
+ * (can) use different representations of annotations that reuse this
+ * method.
+ */
+ public static int hashCode(Class type, Map memberValues)
+ {
+ int h = 0;
+ Iterator iter = memberValues.keySet().iterator();
+ while (iter.hasNext())
+ {
+ Object key = iter.next();
+ Object val = memberValues.get(key);
+ h += deepHashCode(val) ^ 127 * key.hashCode();
+ }
+ return h;
+ }
+
+ private static String deepToString(Object obj)
+ {
+ if (obj instanceof boolean[])
+ return Arrays.toString((boolean[]) obj);
+
+ if (obj instanceof byte[])
+ return Arrays.toString((byte[]) obj);
+
+ if (obj instanceof char[])
+ return Arrays.toString((char[]) obj);
+
+ if (obj instanceof short[])
+ return Arrays.toString((short[]) obj);
+
+ if (obj instanceof int[])
+ return Arrays.toString((int[]) obj);
+
+ if (obj instanceof float[])
+ return Arrays.toString((float[]) obj);
+
+ if (obj instanceof long[])
+ return Arrays.toString((long[]) obj);
+
+ if (obj instanceof double[])
+ return Arrays.toString((double[]) obj);
+
+ if (obj instanceof Object[])
+ return Arrays.toString((Object[]) obj);
+
+ return obj.toString();
+ }
+
+ /**
+ * This method is public for use by other parts of the VM. Some VMs
+ * (can) use different representations of annotations that reuse this
+ * method.
+ */
+ public static String toString(Class type, Map memberValues)
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append('@').append(type.getName()).append('(');
+ String sep = "";
+ Iterator iter = memberValues.keySet().iterator();
+ while (iter.hasNext())
+ {
+ Object key = iter.next();
+ Object val = memberValues.get(key);
+ sb.append(sep).append(key).append('=').append(deepToString(val));
+ sep = ", ";
+ }
+ sb.append(')');
+ return sb.toString();
+ }
+
+ private static Class getBoxedReturnType(Method method)
+ {
+ Class returnType = method.getReturnType();
+
+ if (returnType == boolean.class)
+ return Boolean.class;
+
+ if (returnType == byte.class)
+ return Byte.class;
+
+ if (returnType == char.class)
+ return Character.class;
+
+ if (returnType == short.class)
+ return Short.class;
+
+ if (returnType == int.class)
+ return Integer.class;
+
+ if (returnType == float.class)
+ return Float.class;
+
+ if (returnType == long.class)
+ return Long.class;
+
+ if (returnType == double.class)
+ return Double.class;
+
+ return returnType;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable
+ {
+ String methodName = method.getName().intern();
+ if (args == null || args.length == 0)
+ {
+ if (methodName == "toString")
+ {
+ return toString(type, memberValues);
+ }
+ else if (methodName == "hashCode")
+ {
+ return Integer.valueOf(hashCode(type, memberValues));
+ }
+ else if (methodName == "annotationType")
+ {
+ return type;
+ }
+ else
+ {
+ Object val = memberValues.get(methodName);
+ if (val == null)
+ {
+ throw new IncompleteAnnotationException(type, methodName);
+ }
+ if (! getBoxedReturnType(method).isInstance(val))
+ {
+ throw new AnnotationTypeMismatchException(method,
+ val.getClass().getName());
+ }
+ return val;
+ }
+ }
+ else if (args.length == 1)
+ {
+ if (methodName == "equals")
+ {
+ return Boolean.valueOf(equals(type, memberValues, args[0]));
+ }
+ }
+ throw new InternalError("Invalid annotation proxy");
+ }
+}
Added: trunk/core/src/classpath/sun/sun/reflect/annotation/AnnotationParser.java
===================================================================
--- trunk/core/src/classpath/sun/sun/reflect/annotation/AnnotationParser.java (rev 0)
+++ trunk/core/src/classpath/sun/sun/reflect/annotation/AnnotationParser.java 2007-01-07 05:43:40 UTC (rev 2997)
@@ -0,0 +1,57 @@
+/* sun.reflect.annotation.AnnotationParser
+ Copyright (C) 2006
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package sun.reflect.annotation;
+
+import gnu.classpath.NotImplementedException;
+
+import java.lang.annotation.Annotation;
+
+import java.util.Map;
+
+public class AnnotationParser
+{
+
+ public static Annotation annotationForMap(Class<? extends Annotation> annoType,
+ Map<String, Object> map)
+ throws NotImplementedException
+ {
+ return null;
+ }
+
+}
Added: trunk/core/src/classpath/sun/sun/reflect/annotation/AnnotationType.java
===================================================================
--- trunk/core/src/classpath/sun/sun/reflect/annotation/AnnotationType.java (rev 0)
+++ trunk/core/src/classpath/sun/sun/reflect/annotation/AnnotationType.java 2007-01-07 05:43:40 UTC (rev 2997)
@@ -0,0 +1,52 @@
+/* sun.reflect.annotation.AnnotationType
+ Copyright (C) 2006
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package sun.reflect.annotation;
+
+import gnu.classpath.NotImplementedException;
+
+public class AnnotationType
+{
+
+ public static Class<?> invocationHandlerReturnType(Class<?> returnClass)
+ throws NotImplementedException
+ {
+ return null;
+ }
+
+}
Added: trunk/core/src/classpath/sun/sun/reflect/annotation/EnumConstantNotPresentExceptionProxy.java
===================================================================
--- trunk/core/src/classpath/sun/sun/reflect/annotation/EnumConstantNotPresentExceptionProxy.java (rev 0)
+++ trunk/core/src/classpath/sun/sun/reflect/annotation/EnumConstantNotPresentExceptionProxy.java 2007-01-07 05:43:40 UTC (rev 2997)
@@ -0,0 +1,52 @@
+/* sun.reflect.annotation.EnumConstantNotPresentExceptionProxy
+ Copyright (C) 2006
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package sun.reflect.annotation;
+
+import gnu.classpath.NotImplementedException;
+
+public class EnumConstantNotPresentExceptionProxy
+ extends ExceptionProxy
+{
+
+ public EnumConstantNotPresentExceptionProxy(Class c, String s)
+ throws NotImplementedException
+ {
+ }
+
+}
Added: trunk/core/src/classpath/sun/sun/reflect/annotation/ExceptionProxy.java
===================================================================
--- trunk/core/src/classpath/sun/sun/reflect/annotation/ExceptionProxy.java (rev 0)
+++ trunk/core/src/classpath/sun/sun/reflect/annotation/ExceptionProxy.java 2007-01-07 05:43:40 UTC (rev 2997)
@@ -0,0 +1,46 @@
+/* sun.reflect.annotation.ExceptionProxy
+ Copyright (C) 2006
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package sun.reflect.annotation;
+
+import gnu.classpath.NotImplementedException;
+
+public class ExceptionProxy
+{
+
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-07 12:59:53
|
Revision: 3026
http://jnode.svn.sourceforge.net/jnode/?rev=3026&view=rev
Author: lsantha
Date: 2007-01-07 04:59:51 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/tools/gnu/classpath/tools/rmid/ActivationSystemImpl.java
trunk/core/src/classpath/vm/java/lang/Class.java
trunk/core/src/classpath/vm/java/lang/Thread.java
trunk/core/src/classpath/vm/java/lang/VMSystem.java
trunk/core/src/classpath/vm/java/lang/reflect/Method.java
Added Paths:
-----------
trunk/core/src/classpath/vm/java/lang/VMProcess.java
Modified: trunk/core/src/classpath/tools/gnu/classpath/tools/rmid/ActivationSystemImpl.java
===================================================================
--- trunk/core/src/classpath/tools/gnu/classpath/tools/rmid/ActivationSystemImpl.java 2007-01-07 12:57:57 UTC (rev 3025)
+++ trunk/core/src/classpath/tools/gnu/classpath/tools/rmid/ActivationSystemImpl.java 2007-01-07 12:59:51 UTC (rev 3026)
@@ -238,6 +238,6 @@
ClassNotFoundException
{
// Write no fields.
- };
+ }
}
Modified: trunk/core/src/classpath/vm/java/lang/Class.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/Class.java 2007-01-07 12:57:57 UTC (rev 3025)
+++ trunk/core/src/classpath/vm/java/lang/Class.java 2007-01-07 12:59:51 UTC (rev 3026)
@@ -1,24 +1,41 @@
-/*
- * $Id$
- *
- * JNode.org
- * Copyright (C) 2003-2006 JNode.org
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; If not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
+/* Class.java -- Representation of a Java class.
+ Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
package java.lang;
import gnu.java.lang.VMClassHelper;
@@ -56,10 +73,34 @@
import org.jnode.vm.classmgr.VmType;
/**
- * Class. If you change any fields in this class, also change
- * <code>emitClass</code> in <code>org.jnode.build.ObjectEmitter</code>.
+ * A Class represents a Java type. There will never be multiple Class
+ * objects with identical names and ClassLoaders. Primitive types, array
+ * types, and void also have a Class object.
*
- * @author epr
+ * <p>Arrays with identical type and number of dimensions share the same class.
+ * The array class ClassLoader is the same as the ClassLoader of the element
+ * type of the array (which can be null to indicate the bootstrap classloader).
+ * The name of an array class is <code>[<signature format>;</code>.
+ * <p> For example,
+ * String[]'s class is <code>[Ljava.lang.String;</code>. boolean, byte,
+ * short, char, int, long, float and double have the "type name" of
+ * Z,B,S,C,I,J,F,D for the purposes of array classes. If it's a
+ * multidimensioned array, the same principle applies:
+ * <code>int[][][]</code> == <code>[[[I</code>.
+ *
+ * <p>There is no public constructor - Class objects are obtained only through
+ * the virtual machine, as defined in ClassLoaders.
+ *
+ * @serialData Class objects serialize specially:
+ * <code>TC_CLASS ClassDescriptor</code>. For more serialization information,
+ * see {@link ObjectStreamClass}.
+ *
+ * @author John Keiser
+ * @author Eric Blake (eb...@em...)
+ * @author Tom Tromey (tr...@re...)
+ * @author Andrew John Hughes (gnu...@me...)
+ * @since 1.0
+ * @see ClassLoader
*/
public final class Class<T> implements AnnotatedElement, Serializable, Type,
GenericDeclaration {
@@ -369,7 +410,7 @@
* @throws InstantiationException
* @throws IllegalAccessException
*/
- public final Object newInstance() throws InstantiationException,
+ public final T newInstance() throws InstantiationException,
IllegalAccessException {
if (defaultConstructor == null) {
defaultConstructor = getLinkedVmClass().getDeclaredMethod("<init>",
@@ -379,7 +420,7 @@
throw new InstantiationException("No default constructor");
}
try {
- return VmReflection.newInstance(defaultConstructor);
+ return (T)VmReflection.newInstance(defaultConstructor);
} catch (InvocationTargetException ex) {
final InstantiationException ie = new InstantiationException();
ie.initCause(ex);
Modified: trunk/core/src/classpath/vm/java/lang/Thread.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/Thread.java 2007-01-07 12:57:57 UTC (rev 3025)
+++ trunk/core/src/classpath/vm/java/lang/Thread.java 2007-01-07 12:59:51 UTC (rev 3026)
@@ -1,21 +1,18 @@
-/*
- * $Id$
+/* Thread -- an independent thread of executable code
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
*
- * JNode.org
- * Copyright (C) 2003-2006 JNode.org
- *
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
- * This library is distributed in the hope that it will be useful, but
+ * This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
- * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -712,7 +709,37 @@
}
return locals;
}
+ /**
+ * <p>
+ * Represents the current state of a thread, according to the VM rather
+ * than the operating system. It can be one of the following:
+ * </p>
+ * <ul>
+ * <li>NEW -- The thread has just been created but is not yet running.</li>
+ * <li>RUNNABLE -- The thread is currently running or can be scheduled
+ * to run.</li>
+ * <li>BLOCKED -- The thread is blocked waiting on an I/O operation
+ * or to obtain a lock.</li>
+ * <li>WAITING -- The thread is waiting indefinitely for another thread
+ * to do something.</li>
+ * <li>TIMED_WAITING -- The thread is waiting for a specific amount of time
+ * for another thread to do something.</li>
+ * <li>TERMINATED -- The thread has exited.</li>
+ * </ul>
+ *
+ * @since 1.5
+ */
+ public enum State
+ {
+ BLOCKED, NEW, RUNNABLE, TERMINATED, TIMED_WAITING, WAITING;
+ /**
+ * For compatability with Sun's JDK
+ */
+ private static final long serialVersionUID = 605505746047245783L;
+ }
+
+
/**
* Returns the current state of the thread. This
* is designed for monitoring thread behaviour, rather
@@ -720,9 +747,9 @@
*
* @return the current thread state.
*/
- public String getState()
+ public State getState()
{
//todo implement
- return "UNKNOWN";
+ throw new UnsupportedClassVersionError();
}
}
Added: trunk/core/src/classpath/vm/java/lang/VMProcess.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/VMProcess.java (rev 0)
+++ trunk/core/src/classpath/vm/java/lang/VMProcess.java 2007-01-07 12:59:51 UTC (rev 3026)
@@ -0,0 +1,410 @@
+/* java.lang.VMProcess -- VM implementation of java.lang.Process
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Represents one external process. Each instance of this class is in
+ * one of three states: INITIAL, RUNNING, or TERMINATED. The instance
+ * is {@link Object#notifyAll notifyAll()}'d each time the state changes.
+ * The state of all instances is managed by a single dedicated thread
+ * which does the actual fork()/exec() and wait() system calls. User
+ * threads {@link Object#wait()} on the instance when creating the
+ * process or waiting for it to terminate.
+ *
+ * <p>
+ * See
+ * <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11801">GCC bug
+ * #11801</a> for the motivation behind the design of this class.
+ *
+ * @author Archie Cobbs
+ * @see Process
+ * @see Runtime#exec(String)
+ */
+final class VMProcess extends Process
+{
+
+ // Possible states for a VMProcess
+ private static final int INITIAL = 0;
+ private static final int RUNNING = 1;
+ private static final int TERMINATED = 2;
+
+ // Dedicated thread that does all the fork()'ing and wait()'ing.
+ static Thread processThread;
+
+ // New processes waiting to be spawned by processThread.
+ static final LinkedList workList = new LinkedList();
+
+ // Return values set by nativeReap() when a child is reaped.
+ // These are only accessed by processThread so no locking required.
+ static long reapedPid;
+ static int reapedExitValue;
+
+ // Information about this process
+ int state; // current state of process
+ final String[] cmd; // copied from Runtime.exec()
+ final String[] env; // copied from Runtime.exec()
+ final File dir; // copied from Runtime.exec()
+ Throwable exception; // if process failed to start
+ long pid; // process id
+ OutputStream stdin; // process input stream
+ InputStream stdout; // process output stream
+ InputStream stderr; // process error stream
+ int exitValue; // process exit value
+ boolean redirect; // redirect stderr -> stdout
+
+ //
+ // Dedicated thread that does all the fork()'ing and wait()'ing
+ // for external processes. This is needed because some systems like
+ // Linux use a process-per-thread model, which means the same thread
+ // that did the fork()/exec() must also do the wait().
+ //
+ private static class ProcessThread extends Thread
+ {
+
+ // Max time (in ms) we'll delay before trying to reap another child.
+ private static final int MAX_REAP_DELAY = 1000;
+
+ // Processes created but not yet terminated; maps Long(pid) -> VMProcess
+ // Only used in run() and spawn() method from this Thread, so no locking.
+ private final HashMap activeMap = new HashMap();
+
+ // We have an explicit constructor, because the default
+ // constructor will be private, which means the compiler will have
+ // to generate a second package-private constructor, which is
+ // bogus.
+ ProcessThread ()
+ {
+ }
+
+ public void run()
+ {
+ final LinkedList workList = VMProcess.workList;
+ while (true)
+ {
+
+ // Get the next process to spawn (if any) and spawn it. Spawn
+ // at most one at a time before checking for reapable children.
+ VMProcess process = null;
+ synchronized (workList)
+ {
+ if (!workList.isEmpty())
+ process = (VMProcess)workList.removeFirst();
+ }
+
+ if (process != null)
+ spawn(process);
+
+
+ // Check for termination of active child processes
+ while (!activeMap.isEmpty() && VMProcess.nativeReap())
+ {
+ long pid = VMProcess.reapedPid;
+ int exitValue = VMProcess.reapedExitValue;
+ process = (VMProcess)activeMap.remove(new Long(pid));
+ if (process != null)
+ {
+ synchronized (process)
+ {
+ process.exitValue = exitValue;
+ process.state = TERMINATED;
+ process.notify();
+ }
+ }
+ else
+ System.err.println("VMProcess WARNING reaped unknown process: "
+ + pid);
+ }
+
+
+ // If there are more new processes to create, go do that now.
+ // If there is nothing left to do, exit this thread. Otherwise,
+ // sleep a little while, and then check again for reapable children.
+ // We will get woken up immediately if there are new processes to
+ // spawn, but not if there are new children to reap. So we only
+ // sleep a short time, in effect polling while processes are active.
+ synchronized (workList)
+ {
+ if (!workList.isEmpty())
+ continue;
+ if (activeMap.isEmpty())
+ {
+ processThread = null;
+ break;
+ }
+
+ try
+ {
+ workList.wait(MAX_REAP_DELAY);
+ }
+ catch (InterruptedException e)
+ {
+ /* ignore */
+ }
+ }
+ }
+ }
+
+ // Spawn a process
+ private void spawn(VMProcess process)
+ {
+
+ // Spawn the process and put it in our active map indexed by pid.
+ // If the spawn operation fails, store the exception with the process.
+ // In either case, wake up thread that created the process.
+ synchronized (process)
+ {
+ try
+ {
+ process.nativeSpawn(process.cmd, process.env, process.dir,
+ process.redirect);
+ process.state = RUNNING;
+ activeMap.put(new Long(process.pid), process);
+ }
+ catch (ThreadDeath death)
+ {
+ throw death;
+ }
+ catch (Throwable t)
+ {
+ process.state = TERMINATED;
+ process.exception = t;
+ }
+ process.notify();
+ }
+ }
+ }
+
+ // Constructor
+ private VMProcess(String[] cmd, String[] env, File dir, boolean redirect)
+ throws IOException
+ {
+
+ // Initialize this process
+ this.state = INITIAL;
+ this.cmd = cmd;
+ this.env = env;
+ this.dir = dir;
+ this.redirect = redirect;
+
+ // Add process to the new process work list and wakeup processThread
+ synchronized (workList)
+ {
+ workList.add(this);
+ if (processThread == null)
+ {
+ processThread = new ProcessThread();
+ processThread.setDaemon(true);
+ processThread.start();
+ }
+ else
+ {
+ workList.notify();
+ }
+ }
+
+ // Wait for processThread to spawn this process and update its state
+ synchronized (this)
+ {
+ while (state == INITIAL)
+ {
+ try
+ {
+ wait();
+ }
+ catch (InterruptedException e)
+ {
+ /* ignore */
+ }
+ }
+ }
+
+ // If spawning failed, rethrow the exception in this thread
+ if (exception != null)
+ {
+ exception.fillInStackTrace();
+ if (exception instanceof IOException)
+ throw (IOException)exception;
+
+ if (exception instanceof Error)
+ throw (Error)exception;
+
+ if (exception instanceof RuntimeException)
+ throw (RuntimeException)exception;
+
+ throw new RuntimeException(exception);
+ }
+ }
+
+ // Invoked by native code (from nativeSpawn()) to record process info.
+ private void setProcessInfo(OutputStream stdin,
+ InputStream stdout, InputStream stderr, long pid)
+ {
+ this.stdin = stdin;
+ this.stdout = stdout;
+ if (stderr == null)
+ this.stderr = new InputStream()
+ {
+ public int read() throws IOException
+ {
+ return -1;
+ }
+ };
+ else
+ this.stderr = stderr;
+ this.pid = pid;
+ }
+
+ /**
+ * Entry point from Runtime.exec().
+ */
+ static Process exec(String[] cmd, String[] env, File dir) throws IOException
+ {
+ return new VMProcess(cmd, env, dir, false);
+ }
+
+ static Process exec(List cmd, Map env,
+ File dir, boolean redirect) throws IOException
+ {
+ String[] acmd = (String[]) cmd.toArray(new String[cmd.size()]);
+ String[] aenv = new String[env.size()];
+
+ int i = 0;
+ Iterator iter = env.entrySet().iterator();
+ while (iter.hasNext())
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ aenv[i++] = entry.getKey() + "=" + entry.getValue();
+ }
+
+ return new VMProcess(acmd, aenv, dir, redirect);
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return stdin;
+ }
+
+ public InputStream getInputStream()
+ {
+ return stdout;
+ }
+
+ public InputStream getErrorStream()
+ {
+ return stderr;
+ }
+
+ public synchronized int waitFor() throws InterruptedException
+ {
+ while (state != TERMINATED)
+ wait();
+ return exitValue;
+ }
+
+ public synchronized int exitValue()
+ {
+ if (state != TERMINATED)
+ throw new IllegalThreadStateException();
+ return exitValue;
+ }
+
+ public synchronized void destroy()
+ {
+ if (state == TERMINATED)
+ return;
+
+ nativeKill(pid);
+
+ while (state != TERMINATED)
+ {
+ try
+ {
+ wait();
+ }
+ catch (InterruptedException e)
+ {
+ /* ignore */
+ }
+ }
+ }
+
+ /**
+ * Does the fork()/exec() thing to create the O/S process.
+ * Must invoke setProcessInfo() before returning successfully.
+ * This method is only invoked by processThread.
+ *
+ * @throws IOException if the O/S process could not be created.
+ */
+ void nativeSpawn(String[] cmd, String[] env, File dir,
+ boolean redirect) throws IOException{
+ //TODO implement it
+ throw new UnsupportedOperationException();
+ };
+
+ /**
+ * 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 boolean nativeReap(){
+ //TODO implement it
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Kill a process. This sends it a fatal signal but does not reap it.
+ */
+ private static void nativeKill(long pid){
+ //TODO implement it
+ throw new UnsupportedOperationException();
+ }
+}
Modified: trunk/core/src/classpath/vm/java/lang/VMSystem.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/VMSystem.java 2007-01-07 12:57:57 UTC (rev 3025)
+++ trunk/core/src/classpath/vm/java/lang/VMSystem.java 2007-01-07 12:59:51 UTC (rev 3026)
@@ -1,29 +1,46 @@
-/*
- * $Id$
- *
- * JNode.org
- * Copyright (C) 2003-2006 JNode.org
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; If not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
+/* 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.InputStream;
import java.io.PrintStream;
import java.nio.ByteOrder;
+import java.util.List;
import org.jnode.util.EmptyInputStream;
import org.jnode.util.SystemInputStream;
@@ -152,14 +169,53 @@
return VmSystem.currentTimeMillis();
}
- /**
+ /**
+ * <p>
+ * Returns the current value of a nanosecond-precise system timer.
+ * The value of the timer is an offset relative to some arbitrary fixed
+ * time, which may be in the future (making the value negative). This
+ * method is useful for timing events where nanosecond precision is
+ * required. This is achieved by calling this method before and after the
+ * event, and taking the difference betweent the two times:
+ * </p>
+ * <p>
+ * <code>long startTime = System.nanoTime();</code><br />
+ * <code>... <emph>event code</emph> ...</code><br />
+ * <code>long endTime = System.nanoTime();</code><br />
+ * <code>long duration = endTime - startTime;</code><br />
+ * </p>
+ * <p>
+ * Note that the value is only nanosecond-precise, and not accurate; there
+ * is no guarantee that the difference between two values is really a
+ * nanosecond. Also, the value is prone to overflow if the offset
+ * exceeds 2^63.
+ * </p>
+ *
+ * @return the time of a system timer in nanoseconds.
+ * @since 1.5
+ */
+ public static long nanoTime(){
+ //TODO implement it
+ throw new UnsupportedOperationException();
+ };
+
+ /**
+ * Returns a list of 'name=value' pairs representing the current environment
+ * variables.
+ *
+ * @return a list of 'name=value' pairs.
+ */
+ static List environ(){
+ //TODO implement it
+ throw new UnsupportedOperationException();
+ }
+ /**
* 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() {
+ static InputStream makeStandardInputStream() {
return SystemInputStream.getInstance(); // JNode specific
}
@@ -169,7 +225,6 @@
* return null if the stream is created somewhere else in the VM startup
* sequence.
*/
-
static PrintStream makeStandardOutputStream() {
return VmSystem.getSystemOut();
}
Modified: trunk/core/src/classpath/vm/java/lang/reflect/Method.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/reflect/Method.java 2007-01-07 12:57:57 UTC (rev 3025)
+++ trunk/core/src/classpath/vm/java/lang/reflect/Method.java 2007-01-07 12:59:51 UTC (rev 3026)
@@ -323,7 +323,7 @@
* @throws ExceptionInInitializerError if accessing a static method triggered
* class initialization, which then failed
*/
- public Object invoke(Object o, Object[] args)
+ public Object invoke(Object o, Object... args)
throws IllegalAccessException, InvocationTargetException {
return VmReflection.invoke(vmMethod, o, args);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-07 18:42:55
|
Revision: 3045
http://jnode.svn.sourceforge.net/jnode/?rev=3045&view=rev
Author: lsantha
Date: 2007-01-07 10:42:54 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/tools/gnu/classpath/tools/appletviewer/Main.java
trunk/core/src/classpath/tools/gnu/classpath/tools/appletviewer/TagParser.java
trunk/core/src/classpath/vm/java/lang/reflect/Constructor.java
Modified: trunk/core/src/classpath/tools/gnu/classpath/tools/appletviewer/Main.java
===================================================================
--- trunk/core/src/classpath/tools/gnu/classpath/tools/appletviewer/Main.java 2007-01-07 18:42:15 UTC (rev 3044)
+++ trunk/core/src/classpath/tools/gnu/classpath/tools/appletviewer/Main.java 2007-01-07 18:42:54 UTC (rev 3045)
@@ -266,7 +266,6 @@
else
{
// Warn user about missing security manager.
- /* @jnode disable security warning
System.err.println(Messages.getString("Main.SecurityWarning") + "\n");
System.err.println(Messages.getString("Main.ContinuationPrompt"));
@@ -290,7 +289,6 @@
System.exit(0);
}
- */
if (code == null)
{
// The --code option wasn't given and there are no URL
Modified: trunk/core/src/classpath/tools/gnu/classpath/tools/appletviewer/TagParser.java
===================================================================
--- trunk/core/src/classpath/tools/gnu/classpath/tools/appletviewer/TagParser.java 2007-01-07 18:42:15 UTC (rev 3044)
+++ trunk/core/src/classpath/tools/gnu/classpath/tools/appletviewer/TagParser.java 2007-01-07 18:42:54 UTC (rev 3045)
@@ -130,7 +130,7 @@
{
ArrayList allTags = new ArrayList();
if (document == null)
- return null;;
+ return null;
recurseDocument(document.getChildNodes());
Modified: trunk/core/src/classpath/vm/java/lang/reflect/Constructor.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/reflect/Constructor.java 2007-01-07 18:42:15 UTC (rev 3044)
+++ trunk/core/src/classpath/vm/java/lang/reflect/Constructor.java 2007-01-07 18:42:54 UTC (rev 3045)
@@ -79,7 +79,12 @@
* @since 1.1
* @status updated to 1.4
*/
-public final class Constructor extends AccessibleObject implements Member, AnnotatedElement, GenericDeclaration {
+public final class Constructor<T>
+ extends AccessibleObject
+ implements GenericDeclaration, Member
+{
+ private Class<T> clazz;
+ private int slot;
private final VmMethod vmMethod;
private ArrayList<Class> parameterTypes;
@@ -99,8 +104,8 @@
* Gets the class that declared this constructor.
* @return the class that declared this member
*/
- public Class getDeclaringClass() {
- return vmMethod.getDeclaringClass().asClass();
+ public Class<T> getDeclaringClass() {
+ return (Class<T>) vmMethod.getDeclaringClass().asClass();
}
/**
@@ -108,9 +113,9 @@
* it was declared in).
* @return the name of this constructor
*/
- public String getName() {
- final Class<?> declClass = getDeclaringClass();
- return declClass.getName();
+ public String getName()
+ {
+ return getDeclaringClass().getName();
}
/**
@@ -164,7 +169,7 @@
*
* @return a list of the types of the constructor's parameters
*/
- public Class[] getParameterTypes() {
+ public Class<?>[] getParameterTypes() {
if (parameterTypes == null) {
int cnt = vmMethod.getNoArguments();
ArrayList<Class> list = new ArrayList<Class>(cnt);
@@ -183,7 +188,7 @@
*
* @return a list of the types in the constructor's throws clause
*/
- public Class[] getExceptionTypes() {
+ public Class<?>[] getExceptionTypes() {
if (exceptionTypes == null) {
final VmExceptions exceptions = vmMethod.getExceptions();
final int cnt = exceptions.getLength();
@@ -216,9 +221,9 @@
*
* @return the hash code for the object
*/
- public int hashCode() {
- final Class<?> declClass = getDeclaringClass();
- return declClass.getName().hashCode();
+ public int hashCode()
+ {
+ return getDeclaringClass().getName().hashCode();
}
/**
@@ -233,7 +238,7 @@
*/
public String toString() {
// 128 is a reasonable buffer initial size for constructor
- StringBuffer sb = new StringBuffer(128);
+ StringBuilder sb = new StringBuilder(128);
Modifier.toString(getModifiers(), sb).append(' ');
final Class<?> declClass = getDeclaringClass();
sb.append(declClass.getName()).append('(');
@@ -285,8 +290,8 @@
* @throws ExceptionInInitializerError if construction triggered class
* initialization, which then failed
*/
- public Object newInstance(Object args[]) throws InstantiationException, IllegalAccessException, InvocationTargetException {
- return VmReflection.newInstance(vmMethod, args);
+ public T newInstance(Object... args) throws InstantiationException, IllegalAccessException, InvocationTargetException {
+ return (T) VmReflection.newInstance(vmMethod, args);
}
/**
@@ -318,6 +323,7 @@
MethodSignatureParser p = new MethodSignatureParser(this, sig);
return p.getTypeParameters();
}
+
/**
* Returns an array of <code>Type</code> objects that represents
* the exception types declared by this constructor, in declaration order.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-27 07:54:11
|
Revision: 3087
http://jnode.svn.sourceforge.net/jnode/?rev=3087&view=rev
Author: lsantha
Date: 2007-01-26 23:54:10 -0800 (Fri, 26 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/lang/reflect/AccessibleObject.java
trunk/core/src/classpath/java/java/lang/reflect/Proxy.java
trunk/core/src/classpath/vm/java/lang/reflect/Constructor.java
trunk/core/src/classpath/vm/java/lang/reflect/Field.java
trunk/core/src/classpath/vm/java/lang/reflect/Method.java
Modified: trunk/core/src/classpath/java/java/lang/reflect/AccessibleObject.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/reflect/AccessibleObject.java 2007-01-20 08:55:33 UTC (rev 3086)
+++ trunk/core/src/classpath/java/java/lang/reflect/AccessibleObject.java 2007-01-27 07:54:10 UTC (rev 3087)
@@ -1,5 +1,5 @@
/* java.lang.reflect.AccessibleObject
- Copyright (C) 2001, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,6 +38,8 @@
package java.lang.reflect;
+import java.lang.annotation.Annotation;
+
/**
* This class is the superclass of various reflection classes, and
* allows sufficiently trusted code to bypass normal restrictions to
@@ -53,9 +55,10 @@
* @see Method
* @see ReflectPermission
* @since 1.2
- * @status updated to 1.4
+ * @status updated to 1.5
*/
public class AccessibleObject
+ implements AnnotatedElement
{
/**
* True if this object is marked accessible, which means the reflected
@@ -156,4 +159,24 @@
throw new SecurityException("Cannot make object accessible: " + this);
this.flag = flag;
}
+
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+ {
+ throw new AssertionError("Subclass must override this method");
+ }
+
+ public Annotation[] getAnnotations()
+ {
+ return getDeclaredAnnotations();
+ }
+
+ public Annotation[] getDeclaredAnnotations()
+ {
+ throw new AssertionError("Subclass must override this method");
+ }
+
+ public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
+ {
+ return getAnnotation(annotationClass) != null;
+ }
}
Modified: trunk/core/src/classpath/java/java/lang/reflect/Proxy.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/reflect/Proxy.java 2007-01-20 08:55:33 UTC (rev 3086)
+++ trunk/core/src/classpath/java/java/lang/reflect/Proxy.java 2007-01-27 07:54:10 UTC (rev 3087)
@@ -158,7 +158,7 @@
* @see Class
* @author Eric Blake (eb...@em...)
* @since 1.3
- * @status updated to 1.4, except for the use of ProtectionDomain
+ * @status updated to 1.5, except for the use of ProtectionDomain
*/
public class Proxy implements Serializable
{
@@ -257,8 +257,8 @@
*/
// synchronized so that we aren't trying to build the same class
// simultaneously in two threads
- public static synchronized Class getProxyClass(ClassLoader loader,
- Class[] interfaces)
+ public static synchronized Class<?> getProxyClass(ClassLoader loader,
+ Class<?>... interfaces)
{
interfaces = (Class[]) interfaces.clone();
ProxyType pt = new ProxyType(loader, interfaces);
@@ -312,7 +312,7 @@
* @see Constructor#newInstance(Object[])
*/
public static Object newProxyInstance(ClassLoader loader,
- Class[] interfaces,
+ Class<?>[] interfaces,
InvocationHandler handler)
{
try
@@ -360,7 +360,7 @@
*/
// This is synchronized on the off chance that another thread is
// trying to add a class to the map at the same time we read it.
- public static synchronized boolean isProxyClass(Class clazz)
+ public static synchronized boolean isProxyClass(Class<?> clazz)
{
if (! Proxy.class.isAssignableFrom(clazz))
return false;
@@ -889,7 +889,7 @@
// constant_pool[], filled in as we go
// access_flags
- putU2(/*Modifier.SUPER |*/ Modifier.FINAL | Modifier.PUBLIC);
+ putU2(Modifier.SUPER | Modifier.FINAL | Modifier.PUBLIC);
// this_class
qualName = (data.pack + "$Proxy" + data.id);
putU2(classInfo(TypeSignature.getEncodingOfClass(qualName, false)));
Modified: trunk/core/src/classpath/vm/java/lang/reflect/Constructor.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/reflect/Constructor.java 2007-01-20 08:55:33 UTC (rev 3086)
+++ trunk/core/src/classpath/vm/java/lang/reflect/Constructor.java 2007-01-27 07:54:10 UTC (rev 3087)
@@ -38,6 +38,7 @@
package java.lang.reflect;
+import gnu.java.lang.ClassHelper;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
@@ -46,6 +47,8 @@
import org.jnode.vm.classmgr.VmMethod;
import gnu.java.lang.reflect.MethodSignatureParser;
+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
@@ -104,7 +107,8 @@
* Gets the class that declared this constructor.
* @return the class that declared this member
*/
- public Class<T> getDeclaringClass() {
+ public Class<T> getDeclaringClass()
+ {
return (Class<T>) vmMethod.getDeclaringClass().asClass();
}
@@ -123,12 +127,11 @@
* this will include the synthetic and varargs bits.
* @return the constructor's modifiers
*/
- private int getModifiersInternal() {
+ private int getModifiersInternal()
+ {
return vmMethod.getModifiers();
}
-
-
/**
* 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
@@ -169,7 +172,8 @@
*
* @return a list of the types of the constructor's parameters
*/
- public Class<?>[] getParameterTypes() {
+ public Class<?>[] getParameterTypes()
+ {
if (parameterTypes == null) {
int cnt = vmMethod.getNoArguments();
ArrayList<Class> list = new ArrayList<Class>(cnt);
@@ -211,8 +215,16 @@
* @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) {
- return (this == o);
+ 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;
}
/**
@@ -240,23 +252,60 @@
// 128 is a reasonable buffer initial size for constructor
StringBuilder sb = new StringBuilder(128);
Modifier.toString(getModifiers(), sb).append(' ');
- final Class<?> declClass = getDeclaringClass();
- sb.append(declClass.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(getDeclaringClass().getName()).append('(');
+ Class[] c = getParameterTypes();
+ if (c.length > 0)
+ {
+ sb.append(ClassHelper.getUserName(c[0]));
+ for (int i = 1; i < c.length; i++)
+ sb.append(',').append(ClassHelper.getUserName(c[i]));
}
- }
sb.append(')');
c = getExceptionTypes();
if (c.length > 0) {
sb.append(" throws ").append(c[0].getName());
- for (int i = 1; i < c.length; i++) {
+ for (int i = 1; i < c.length; i++)
sb.append(',').append(c[i].getName());
}
+ return sb.toString();
}
+
+ static <X extends GenericDeclaration>
+ void addTypeParameters(StringBuilder sb, TypeVariable<X>[] typeArgs)
+ {
+ if (typeArgs.length == 0)
+ return;
+ sb.append('<');
+ for (int i = 0; i < typeArgs.length; ++i)
+ {
+ if (i > 0)
+ sb.append(',');
+ sb.append(typeArgs[i]);
+ }
+ sb.append("> ");
+ }
+
+ public String toGenericString()
+ {
+ StringBuilder sb = new StringBuilder(128);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ addTypeParameters(sb, getTypeParameters());
+ sb.append(getDeclaringClass().getName()).append('(');
+ Type[] types = getGenericParameterTypes();
+ if (types.length > 0)
+ {
+ sb.append(types[0]);
+ for (int i = 1; i < types.length; ++i)
+ sb.append(',').append(types[i]);
+ }
+ sb.append(')');
+ types = getGenericExceptionTypes();
+ if (types.length > 0)
+ {
+ sb.append(" throws ").append(types[0]);
+ for (int i = 1; i < types.length; i++)
+ sb.append(',').append(types[i]);
+ }
return sb.toString();
}
@@ -294,14 +343,6 @@
return (T) VmReflection.newInstance(vmMethod, args);
}
- /**
- * Return the String in the Signature attribute for this constructor. If there
- * is no Signature attribute, return null.
- */
- private String getSignature(){
- //todo implement it
- return null;
- }
/**
* Returns an array of <code>TypeVariable</code> objects that represents
@@ -315,7 +356,7 @@
* specification, version 3.
* @since 1.5
*/
- public TypeVariable[] getTypeParameters()
+ public TypeVariable<Constructor<T>>[] getTypeParameters()
{
String sig = getSignature();
if (sig == null)
@@ -325,6 +366,15 @@
}
/**
+ * Return the String in the Signature attribute for this constructor. If there
+ * is no Signature attribute, return null.
+ */
+ private String getSignature()
+ {
+ return vmMethod.getSignature();
+ }
+
+ /**
* Returns an array of <code>Type</code> objects that represents
* the exception types declared by this constructor, in declaration order.
* An array of size zero is returned if this constructor declares no
Modified: trunk/core/src/classpath/vm/java/lang/reflect/Field.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/reflect/Field.java 2007-01-20 08:55:33 UTC (rev 3086)
+++ trunk/core/src/classpath/vm/java/lang/reflect/Field.java 2007-01-27 07:54:10 UTC (rev 3087)
@@ -1,56 +1,71 @@
-/*
- * $Id$
- *
- * JNode.org
- * Copyright (C) 2003-2006 JNode.org
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; If not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
+/* java.lang.reflect.Field - reflection of Java fields
+ Copyright (C) 1998, 2001, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
package java.lang.reflect;
-import java.lang.annotation.Annotation;
+import gnu.java.lang.ClassHelper;
+import gnu.java.lang.reflect.FieldSignatureParser;
import org.jnode.vm.VmReflection;
import org.jnode.vm.classmgr.VmField;
+import java.lang.annotation.Annotation;
/**
* 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>
+ * 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>
+ * <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.
+ * 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 <eb...@em...>
@@ -63,8 +78,9 @@
* @since 1.1
* @status updated to 1.4
*/
-public final class Field extends AccessibleObject implements Member, AnnotatedElement {
-
+public final class Field
+extends AccessibleObject implements Member
+{
private final VmField vmField;
private static final int FIELD_MODIFIERS
@@ -80,13 +96,13 @@
}
/**
- * Gets the class that declared this field, or the class where this field is
- * a non-inherited member.
- *
+ * 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 vmField.getDeclaringClass().asClass();
+ public Class<?> getDeclaringClass()
+ {
+ return vmField.getDeclaringClass().asClass();
}
/**
@@ -99,13 +115,8 @@
}
/**
- * 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
+ * Return the raw modifiers for this field.
+ * @return the field's modifiers
*/
public int getModifiersInternal() {
return vmField.getModifiers();
@@ -154,68 +165,82 @@
}
/**
- * 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.
+ * 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
+ * @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) {
- return this == o;
+ 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.
+ * 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() {
- final Class<?> declClass = getDeclaringClass();
- return declClass.getName().hashCode() ^ getName().hashCode();
+ 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:
+ * 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);
+ StringBuilder sb = new StringBuilder(64);
Modifier.toString(getModifiers(), sb).append(' ');
- final Class<?> type = getType();
- final Class<?> declClass = getDeclaringClass();
- sb.append(type.getName()).append(' ');
- sb.append(declClass.getName()).append('.');
+ sb.append(ClassHelper.getUserName(getType())).append(' ');
+ sb.append(getDeclaringClass().getName()).append('.');
sb.append(getName());
return sb.toString();
}
+ public String toGenericString()
+ {
+ StringBuilder sb = new StringBuilder(64);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ sb.append(getGenericType()).append(' ');
+ sb.append(getDeclaringClass().getName()).append('.');
+ sb.append(getName());
+ return sb.toString();
+ }
+
/**
- * Get the value of this Field. If it is primitive, it will be wrapped in
- * the appropriate wrapper type (boolean = java.lang.Boolean).
- * <p>
+ * 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>
+ * 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>
+ * 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
@@ -333,22 +358,17 @@
* 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
+ * @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
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte or short
+ * field of <code>o</code>, or if <code>o</code> is not an instance
+ * of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
* @see #get(Object)
*/
public short getShort(Object o) throws IllegalAccessException {
@@ -359,22 +379,17 @@
* 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
+ * @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
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, or
+ * int field of <code>o</code>, or if <code>o</code> is not an
+ * instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
* @see #get(Object)
*/
public int getInt(Object o) throws IllegalAccessException {
@@ -385,22 +400,17 @@
* 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
+ * @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
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * or long field of <code>o</code>, or if <code>o</code> is not an
+ * instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
* @see #get(Object)
*/
public long getLong(Object o) throws IllegalAccessException {
@@ -411,22 +421,17 @@
* 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
+ * @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
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * long, or float field of <code>o</code>, or if <code>o</code> is
+ * not an instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
* @see #get(Object)
*/
public float getFloat(Object o) throws IllegalAccessException {
@@ -437,22 +442,18 @@
* 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
+ * @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
+ * @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 ExceptionInIniti...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-27 09:39:36
|
Revision: 3088
http://jnode.svn.sourceforge.net/jnode/?rev=3088&view=rev
Author: lsantha
Date: 2007-01-27 01:39:31 -0800 (Sat, 27 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/gnu/gnu/java/awt/peer/GLightweightPeer.java
trunk/core/src/classpath/java/java/awt/CheckboxMenuItem.java
trunk/core/src/classpath/java/java/awt/MenuItem.java
trunk/core/src/classpath/java/java/awt/image/AffineTransformOp.java
trunk/core/src/classpath/java/java/awt/image/BandCombineOp.java
trunk/core/src/classpath/java/java/awt/image/ColorConvertOp.java
trunk/core/src/classpath/java/java/awt/image/ColorModel.java
trunk/core/src/classpath/java/java/awt/image/ConvolveOp.java
trunk/core/src/classpath/java/java/awt/image/ImageConsumer.java
trunk/core/src/classpath/java/java/awt/image/ImageFilter.java
trunk/core/src/classpath/java/java/awt/image/LookupOp.java
trunk/core/src/classpath/java/java/awt/image/PixelGrabber.java
trunk/core/src/classpath/java/java/awt/image/RGBImageFilter.java
trunk/core/src/classpath/java/java/awt/image/Raster.java
trunk/core/src/classpath/java/java/awt/image/RenderedImage.java
trunk/core/src/classpath/java/java/awt/image/ReplicateScaleFilter.java
trunk/core/src/classpath/java/java/awt/image/RescaleOp.java
trunk/core/src/classpath/java/java/awt/image/SampleModel.java
trunk/core/src/classpath/java/java/awt/image/SinglePixelPackedSampleModel.java
trunk/core/src/classpath/java/java/awt/image/WritableRaster.java
trunk/core/src/classpath/java/java/text/DateFormat.java
trunk/core/src/classpath/java/java/text/DateFormatSymbols.java
trunk/core/src/classpath/java/java/text/DecimalFormatSymbols.java
trunk/core/src/classpath/java/java/text/NumberFormat.java
trunk/core/src/classpath/java/java/util/Arrays.java
trunk/core/src/classpath/javax/javax/swing/ToolTipManager.java
trunk/core/src/classpath/javax/javax/swing/TransferHandler.java
trunk/core/src/classpath/tools/gnu/classpath/tools/jarsigner/JarVerifier.java
trunk/core/src/classpath/tools/gnu/classpath/tools/jarsigner/Main.java
trunk/core/src/classpath/tools/gnu/classpath/tools/jarsigner/Messages.java
trunk/core/src/classpath/tools/gnu/classpath/tools/jarsigner/SFHelper.java
trunk/core/src/classpath/tools/gnu/classpath/tools/native2ascii/Native2ASCII.java
Added Paths:
-----------
trunk/core/src/classpath/gnu/gnu/java/awt/ComponentReshapeEvent.java
trunk/core/src/classpath/gnu/gnu/java/awt/dnd/
trunk/core/src/classpath/gnu/gnu/java/awt/dnd/GtkMouseDragGestureRecognizer.java
trunk/core/src/classpath/java/java/text/spi/DateFormatProvider.java
trunk/core/src/classpath/java/java/text/spi/DecimalFormatSymbolsProvider.java
trunk/core/src/classpath/java/java/text/spi/NumberFormatProvider.java
trunk/core/src/classpath/javax/javax/management/AttributeChangeNotification.java
Added: trunk/core/src/classpath/gnu/gnu/java/awt/ComponentReshapeEvent.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/awt/ComponentReshapeEvent.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/java/awt/ComponentReshapeEvent.java 2007-01-27 09:39:31 UTC (rev 3088)
@@ -0,0 +1,85 @@
+/* WindowResizeEvent.java -- Used to synchronize the AWT and peer sizes
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+
+/**
+ * This is used to update the AWT's knowledge about a Window's size when
+ * the user changes the window bounds.
+ *
+ * This event is _not_ posted to the eventqueue, but rather dispatched directly
+ * via Window.dispatchEvent(). It is the cleanest way we could find to update
+ * the AWT's knowledge of the window size. Small testprograms showed the
+ * following:
+ * - Component.reshape() and its derivatives are _not_ called. This makes sense
+ * as it could end up in loops,because this calls back into the peers.
+ * - Intercepting event dispatching for any events in
+ * EventQueue.dispatchEvent() showed that the size is still updated. So it
+ * is not done via an event dispatched over the eventqueue.
+ *
+ * Possible other candidates for implementation would have been:
+ * - Call a (private) callback method in Window/Component from the native
+ * side.
+ * - Call a (private) callback method in Window/Component via reflection.
+ *
+ * Both is uglier than sending this event directly. Note however that this
+ * is impossible to test, as Component.dispatchEvent() is final and can't be
+ * intercepted from outside code. But this impossibility to test the issue from
+ * outside code also means that this shouldn't raise any compatibility issues.
+ */
+public class ComponentReshapeEvent
+ extends AWTEvent
+{
+
+ public int x;
+ public int y;
+ public int width;
+ public int height;
+
+ public ComponentReshapeEvent(Component c, int x, int y, int width, int height)
+ {
+ super(c, 1999);
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ }
+}
Added: trunk/core/src/classpath/gnu/gnu/java/awt/dnd/GtkMouseDragGestureRecognizer.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/awt/dnd/GtkMouseDragGestureRecognizer.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/java/awt/dnd/GtkMouseDragGestureRecognizer.java 2007-01-27 09:39:31 UTC (rev 3088)
@@ -0,0 +1,172 @@
+/* GtkMouseDragGestureRecognizer.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.dnd;
+
+import java.awt.Component;
+import java.awt.Point;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DragGestureListener;
+import java.awt.dnd.DragSource;
+import java.awt.dnd.MouseDragGestureRecognizer;
+import java.awt.event.MouseEvent;
+
+public class GtkMouseDragGestureRecognizer
+ extends MouseDragGestureRecognizer
+{
+
+ public GtkMouseDragGestureRecognizer (DragSource ds)
+ {
+ this(ds, null, 0, null);
+ }
+
+ public GtkMouseDragGestureRecognizer (DragSource ds, Component c)
+ {
+ this (ds, c, 0, null);
+ }
+
+ public GtkMouseDragGestureRecognizer (DragSource ds, Component c, int act)
+ {
+ this(ds, c, act, null);
+ }
+
+ public GtkMouseDragGestureRecognizer (DragSource ds, Component c, int act,
+ DragGestureListener dgl)
+ {
+ super(ds, c, act, dgl);
+ }
+
+ public void registerListeners ()
+ {
+ super.registerListeners();
+ }
+
+ public void unregisterListeners ()
+ {
+ super.unregisterListeners();
+ }
+
+ public void mouseClicked (MouseEvent e)
+ {
+ // Nothing to do here.
+ }
+
+ public void mousePressed (MouseEvent e)
+ {
+ events.clear();
+ if (getDropActionFromEvent(e) != DnDConstants.ACTION_NONE)
+ appendEvent(e);
+ }
+
+ public void mouseReleased (MouseEvent e)
+ {
+ events.clear();
+ }
+
+ public void mouseEntered (MouseEvent e)
+ {
+ events.clear();
+ }
+
+ public void mouseExited(MouseEvent e)
+ {
+ if (!events.isEmpty())
+ if (getDropActionFromEvent(e) == DnDConstants.ACTION_NONE)
+ events.clear();
+ }
+
+ public void mouseDragged(MouseEvent e)
+ {
+ if (!events.isEmpty())
+ {
+ int act = getDropActionFromEvent(e);
+
+ if (act == DnDConstants.ACTION_NONE)
+ return;
+
+ Point origin = ((MouseEvent) events.get(0)).getPoint();
+ Point current = e.getPoint();
+ int dx = Math.abs(origin.x - current.x);
+ int dy = Math.abs(origin.y - current.y);
+ int threshold = DragSource.getDragThreshold();
+
+ if (dx > threshold || dy > threshold)
+ fireDragGestureRecognized(act, origin);
+ else
+ appendEvent(e);
+ }
+ }
+
+ public void mouseMoved (MouseEvent e)
+ {
+ // Nothing to do here.
+ }
+
+ private int getDropActionFromEvent(MouseEvent e)
+ {
+ int modEx = e.getModifiersEx();
+ int buttons = modEx & (MouseEvent.BUTTON1_DOWN_MASK
+ | MouseEvent.BUTTON2_DOWN_MASK | MouseEvent.BUTTON3_DOWN_MASK);
+ if (!(buttons == MouseEvent.BUTTON1_DOWN_MASK ||
+ buttons == MouseEvent.BUTTON2_DOWN_MASK))
+ return DnDConstants.ACTION_NONE;
+
+ // Convert modifier to a drop action
+ int sourceActions = getSourceActions();
+ int mod = modEx
+ & (MouseEvent.SHIFT_DOWN_MASK | MouseEvent.CTRL_DOWN_MASK);
+ switch (mod)
+ {
+ case MouseEvent.SHIFT_DOWN_MASK | MouseEvent.CTRL_DOWN_MASK:
+ return DnDConstants.ACTION_LINK & sourceActions;
+ case MouseEvent.CTRL_DOWN_MASK:
+ return DnDConstants.ACTION_COPY & sourceActions;
+ case MouseEvent.SHIFT_DOWN_MASK:
+ return DnDConstants.ACTION_MOVE & sourceActions;
+ default:
+ if ((sourceActions & DnDConstants.ACTION_MOVE) != 0)
+ return DnDConstants.ACTION_MOVE & sourceActions;
+ else if ((sourceActions & DnDConstants.ACTION_COPY) != 0)
+ return DnDConstants.ACTION_COPY & sourceActions;
+ else if ((sourceActions & DnDConstants.ACTION_LINK) != 0)
+ return DnDConstants.ACTION_LINK & sourceActions;
+ }
+
+ return DnDConstants.ACTION_NONE & sourceActions;
+ }
+}
Modified: trunk/core/src/classpath/gnu/gnu/java/awt/peer/GLightweightPeer.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/awt/peer/GLightweightPeer.java 2007-01-27 07:54:10 UTC (rev 3087)
+++ trunk/core/src/classpath/gnu/gnu/java/awt/peer/GLightweightPeer.java 2007-01-27 09:39:31 UTC (rev 3088)
@@ -163,8 +163,10 @@
public FontMetrics getFontMetrics(Font f)
{
- // Nothing to do here for lightweights.
- return null;
+ // We shouldn't end up here, but if we do we can still try do something
+ // reasonable.
+ Toolkit tk = Toolkit.getDefaultToolkit();
+ return tk.getFontMetrics(f);
}
/* Returning null here tells the Component object that called us to
@@ -201,7 +203,31 @@
public void handleEvent(AWTEvent e)
{
- // Nothing to do here for lightweights.
+ // This can only happen when an application posts a PaintEvent for
+ // a lightweight component directly. We still support painting for
+ // this case.
+ if (e instanceof PaintEvent)
+ {
+ PaintEvent pe = (PaintEvent) e;
+ Component target = (Component) e.getSource();
+ if (target != null && target.isShowing())
+ {
+ Graphics g = target.getGraphics();
+ if (g != null)
+ {
+ try
+ {
+ Rectangle clip = pe.getUpdateRect();
+ g.setClip(clip);
+ target.paint(g);
+ }
+ finally
+ {
+ g.dispose();
+ }
+ }
+ }
+ }
}
public void hide()
Modified: trunk/core/src/classpath/java/java/awt/CheckboxMenuItem.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/CheckboxMenuItem.java 2007-01-27 07:54:10 UTC (rev 3087)
+++ trunk/core/src/classpath/java/java/awt/CheckboxMenuItem.java 2007-01-27 09:39:31 UTC (rev 3088)
@@ -318,7 +318,7 @@
* @exception ClassCastException If listenerType doesn't specify a class or
* interface that implements java.util.EventListener.
*/
- public EventListener[] getListeners (Class listenerType)
+ public <T extends EventListener> T[] getListeners (Class<T> listenerType)
{
if (listenerType == ItemListener.class)
return AWTEventMulticaster.getListeners (item_listeners, listenerType);
Modified: trunk/core/src/classpath/java/java/awt/MenuItem.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/MenuItem.java 2007-01-27 07:54:10 UTC (rev 3087)
+++ trunk/core/src/classpath/java/java/awt/MenuItem.java 2007-01-27 09:39:31 UTC (rev 3088)
@@ -523,11 +523,11 @@
* ClassClassException is thrown.
* @since 1.3
*/
- public EventListener[] getListeners(Class listenerType)
+ public <T extends EventListener> T[] getListeners(Class<T> listenerType)
{
if (listenerType == ActionListener.class)
- return getActionListeners();
- return (EventListener[]) Array.newInstance(listenerType, 0);
+ return (T[]) getActionListeners();
+ return (T[]) Array.newInstance(listenerType, 0);
}
/*************************************************************************/
Modified: trunk/core/src/classpath/java/java/awt/image/AffineTransformOp.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/image/AffineTransformOp.java 2007-01-27 07:54:10 UTC (rev 3087)
+++ trunk/core/src/classpath/java/java/awt/image/AffineTransformOp.java 2007-01-27 09:39:31 UTC (rev 3088)
@@ -39,6 +39,7 @@
package java.awt.image;
import java.awt.Graphics2D;
+import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
@@ -48,8 +49,11 @@
import java.util.Arrays;
/**
- * This class performs affine transformation between two images or
- * rasters in 2 dimensions.
+ * AffineTransformOp performs matrix-based transformations (translations,
+ * scales, flips, rotations, and shears).
+ *
+ * If interpolation is required, nearest neighbour, bilinear, and bicubic
+ * methods are available.
*
* @author Olga Rodimina (rod...@re...)
* @author Francis Kung (fk...@re...)
@@ -115,14 +119,14 @@
}
/**
- * Creates empty BufferedImage with the size equal to that of the
- * transformed image and correct number of bands. The newly created
+ * Creates a new BufferedImage with the size equal to that of the
+ * transformed image and the correct number of bands. The newly created
* image is created with the specified ColorModel.
- * If the ColorModel is equal to null, an appropriate ColorModel is used.
+ * If a ColorModel is not specified, an appropriate ColorModel is used.
*
- * @param src source image
- * @param destCM color model for the destination image
- * @return new compatible destination image
+ * @param src the source image.
+ * @param destCM color model for the destination image (can be null).
+ * @return a new compatible destination image.
*/
public BufferedImage createCompatibleDestImage (BufferedImage src,
ColorModel destCM)
@@ -145,21 +149,18 @@
}
/**
- * Creates empty WritableRaster with the size equal to the transformed
- * source raster and correct number of bands
+ * Creates a new WritableRaster with the size equal to the transformed
+ * source raster and correct number of bands .
*
- * @param src source raster
- * @throws RasterFormatException if resulting width or height of raster is 0
- * @return new compatible raster
+ * @param src the source raster.
+ * @throws RasterFormatException if resulting width or height of raster is 0.
+ * @return a new compatible raster.
*/
public WritableRaster createCompatibleDestRaster (Raster src)
{
Rectangle2D rect = getBounds2D(src);
- // throw RasterFormatException if resulting width or height of the
- // transformed raster is 0
-
- if (rect.getWidth () == 0 || rect.getHeight () == 0)
+ if (rect.getWidth() == 0 || rect.getHeight() == 0)
throw new RasterFormatException("width or height is 0");
return src.createCompatibleWritableRaster((int) rect.getWidth(),
@@ -175,24 +176,22 @@
* @param dst destination image
* @throws IllegalArgumentException if the source and destination image are
* the same
- * @return transformed source image
+ * @return transformed source image.
*/
public final BufferedImage filter (BufferedImage src, BufferedImage dst)
{
-
if (dst == src)
- throw new IllegalArgumentException ("src image cannot be the same as " +
- "the dst image");
+ throw new IllegalArgumentException("src image cannot be the same as "
+ + "the dst image");
// If the destination image is null, then use a compatible BufferedImage
if (dst == null)
dst = createCompatibleDestImage(src, null);
- Graphics2D gr = (Graphics2D) dst.createGraphics ();
- gr.setRenderingHints (hints);
- gr.drawImage (src, transform, null);
+ Graphics2D gr = (Graphics2D) dst.createGraphics();
+ gr.setRenderingHints(hints);
+ gr.drawImage(src, transform, null);
return dst;
-
}
/**
@@ -204,10 +203,11 @@
* @param dst destination raster
* @throws IllegalArgumentException if the source and destination are not
* compatible
- * @return transformed raster
+ * @return transformed raster.
*/
- public final WritableRaster filter (Raster src, WritableRaster dst)
+ public final WritableRaster filter(Raster src, WritableRaster dst)
{
+ // Initial checks
if (dst == src)
throw new IllegalArgumentException("src image cannot be the same as"
+ " the dst image");
@@ -219,6 +219,24 @@
throw new IllegalArgumentException("src and dst must have same number"
+ " of bands");
+ // Optimization for rasters that can be represented in the RGB colormodel:
+ // wrap the rasters in images, and let Cairo do the transformation
+ if (ColorModel.getRGBdefault().isCompatibleSampleModel(src.getSampleModel())
+ && ColorModel.getRGBdefault().isCompatibleSampleModel(dst.getSampleModel()))
+ {
+ WritableRaster src2 = Raster.createWritableRaster(src.getSampleModel(),
+ src.getDataBuffer(),
+ new Point(src.getMinX(),
+ src.getMinY()));
+ BufferedImage iSrc = new BufferedImage(ColorModel.getRGBdefault(),
+ src2, false, null);
+ BufferedImage iDst = new BufferedImage(ColorModel.getRGBdefault(), dst,
+ false, null);
+
+ return filter(iSrc, iDst).getRaster();
+ }
+
+ // Otherwise, we need to do the transformation in java code...
// Create arrays to hold all the points
double[] dstPts = new double[dst.getHeight() * dst.getWidth() * 2];
double[] srcPts = new double[dst.getHeight() * dst.getWidth() * 2];
@@ -287,7 +305,7 @@
}
/**
- * Returns interpolation type used during transformations
+ * Returns interpolation type used during transformations.
*
* @return interpolation type
*/
@@ -319,7 +337,7 @@
/**
* Returns rendering hints that are used during transformation.
*
- * @return rendering hints
+ * @return the rendering hints used in this Op.
*/
public final RenderingHints getRenderingHints ()
{
@@ -330,7 +348,7 @@
* Returns transform used in transformation between source and destination
* image.
*
- * @return transform
+ * @return the transform used in this Op.
*/
public final AffineTransform getTransform ()
{
@@ -377,6 +395,18 @@
{
Rectangle srcbounds = src.getBounds();
+ Object xyarr = null;
+ Object xp1arr = null;
+ Object yp1arr = null;
+ Object xyp1arr = null;
+
+ double xy;
+ double xp1;
+ double yp1;
+ double xyp1;
+
+ double[] result = new double[src.getNumBands()];
+
// For all points in the destination raster, use bilinear interpolation
// to find the value from the corrosponding source points
for (int i = 0; i < dpts.length; i += 2)
@@ -401,21 +431,64 @@
double xdiff = pts[i] + src.getMinX() - x;
double ydiff = pts[i + 1] + src.getMinY() - y;
- // Run the interpolation for each band
+ // Get surrounding pixels used in interpolation... optimized
+ // to use the smallest datatype possible.
+ if (src.getTransferType() == DataBuffer.TYPE_DOUBLE
+ || src.getTransferType() == DataBuffer.TYPE_FLOAT)
+ {
+ xyarr = src.getPixel(x, y, (double[])xyarr);
+ xp1arr = src.getPixel(x+1, y, (double[])xp1arr);
+ yp1arr = src.getPixel(x, y+1, (double[])yp1arr);
+ xyp1arr = src.getPixel(x+1, y+1, (double[])xyp1arr);
+ }
+ else
+ {
+ xyarr = src.getPixel(x, y, (int[])xyarr);
+ xp1arr = src.getPixel(x+1, y, (int[])xp1arr);
+ yp1arr = src.getPixel(x, y+1, (int[])yp1arr);
+ xyp1arr = src.getPixel(x+1, y+1, (int[])xyp1arr);
+ }
+ // using
+ // array[] pixels = src.getPixels(x, y, 2, 2, pixels);
+ // instead of doing four individual src.getPixel() calls
+ // should be faster, but benchmarking shows that it's not...
+
+ // Run interpolation for each band
for (int j = 0; j < src.getNumBands(); j++)
{
- double result = (src.getSampleDouble(x, y, j) * (1 - xdiff)
- + src.getSampleDouble(x + 1, y, j) * xdiff)
- * (1 - ydiff)
- + (src.getSampleDouble(x, y + 1, j)
- * (1 - xdiff)
- + src.getSampleDouble(x + 1, y + 1, j)
- * xdiff)
+ // Pull individual sample values out of array
+ if (src.getTransferType() == DataBuffer.TYPE_DOUBLE
+ || src.getTransferType() == DataBuffer.TYPE_FLOAT)
+ {
+ xy = ((double[])xyarr)[j];
+ xp1 = ((double[])xp1arr)[j];
+ yp1 = ((double[])yp1arr)[j];
+ xyp1 = ((double[])xyp1arr)[j];
+ }
+ else
+ {
+ xy = ((int[])xyarr)[j];
+ xp1 = ((int[])xp1arr)[j];
+ yp1 = ((int[])yp1arr)[j];
+ xyp1 = ((int[])xyp1arr)[j];
+ }
+
+ // If all four samples are identical, there's no need to
+ // calculate anything
+ if (xy == xp1 && xy == yp1 && xy == xyp1)
+ result[j] = xy;
+
+ // Run bilinear interpolation formula
+ else
+ result[j] = (xy * (1-xdiff) + xp1 * xdiff)
+ * (1-ydiff)
+ + (yp1 * (1-xdiff) + xyp1 * xdiff)
* ydiff;
- dst.setSample((int) dpts[i] + dst.getMinX(),
- (int) dpts[i + 1] + dst.getMinY(),
- j, result);
}
+
+ dst.setPixel((int)dpts[i] + dst.getMinX(),
+ (int)dpts[i+1] + dst.getMinY(),
+ result);
}
}
}
@@ -434,10 +507,11 @@
double[] pts)
{
Rectangle srcbounds = src.getBounds();
+ double[] result = new double[src.getNumBands()];
+ Object pixels = null;
// For all points on the destination raster, perform bicubic interpolation
// from corrosponding source points
- double[] result = new double[src.getNumBands()];
for (int i = 0; i < dpts.length; i += 2)
{
if (srcbounds.contains((int) Math.round(pts[i]) + src.getMinX(),
@@ -450,7 +524,6 @@
Arrays.fill(result, 0);
for (int m = - 1; m < 3; m++)
- {
for (int n = - 1; n < 3; n++)
{
// R(x) = ( P(x+2)^3 - 4 P(x+1)^3 + 6 P(x)^3 - 4 P(x-1)^3 ) / 6
@@ -459,7 +532,6 @@
// Calculate R(m - dx)
double rx = m - dx + 2;
- if (rx > 0)
r1 += rx * rx * rx;
rx = m - dx + 1;
@@ -509,17 +581,27 @@
else if (srcY < src.getMinY())
srcY = src.getMinY();
- // Calculate once for each band
+ // Calculate once for each band, using the smallest
+ // datatype possible
+ if (src.getTransferType() == DataBuffer.TYPE_DOUBLE
+ || src.getTransferType() == DataBuffer.TYPE_FLOAT)
+ {
+ pixels = src.getPixel(srcX, srcY, (double[])pixels);
for (int j = 0; j < result.length; j++)
- result[j] += src.getSample(srcX, srcY, j) * r1 * r2;
+ result[j] += ((double[])pixels)[j] * r1 * r2;
+ }
+ else
+ {
+ pixels = src.getPixel(srcX, srcY, (int[])pixels);
+ for (int j = 0; j < result.length; j++)
+ result[j] += ((int[])pixels)[j] * r1 * r2;
}
}
// Put it all together
- for (int j = 0; j < result.length; j++)
- dst.setSample((int) dpts[i] + dst.getMinX(),
- (int) dpts[i + 1] + dst.getMinY(),
- j, result[j]);
+ dst.setPixel((int)dpts[i] + dst.getMinX(),
+ (int)dpts[i+1] + dst.getMinY(),
+ result);
}
}
}
Modified: trunk/core/src/classpath/java/java/awt/image/BandCombineOp.java
===================================================================
--- trunk/core/src/...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-27 11:43:22
|
Revision: 3091
http://jnode.svn.sourceforge.net/jnode/?rev=3091&view=rev
Author: lsantha
Date: 2007-01-27 03:43:17 -0800 (Sat, 27 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/gnu/gnu/java/awt/java2d/AbstractGraphics2D.java
trunk/core/src/classpath/java/java/lang/InheritableThreadLocal.java
trunk/core/src/classpath/java/java/lang/StringBuffer.java
trunk/core/src/classpath/java/java/lang/ThreadLocal.java
Added Paths:
-----------
trunk/core/src/classpath/gnu/gnu/java/nio/KqueueSelectionKeyImpl.java
trunk/core/src/classpath/gnu/gnu/java/nio/KqueueSelectorImpl.java
trunk/core/src/classpath/gnu/gnu/java/nio/VMChannelOwner.java
trunk/core/src/classpath/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
Modified: trunk/core/src/classpath/gnu/gnu/java/awt/java2d/AbstractGraphics2D.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/awt/java2d/AbstractGraphics2D.java 2007-01-27 10:06:33 UTC (rev 3090)
+++ trunk/core/src/classpath/gnu/gnu/java/awt/java2d/AbstractGraphics2D.java 2007-01-27 11:43:17 UTC (rev 3091)
@@ -166,14 +166,14 @@
* Caches certain shapes to avoid massive creation of such Shapes in
* the various draw* and fill* methods.
*/
- private static final ThreadLocal shapeCache =
- new ThreadLocal();
+ private static final ThreadLocal<ShapeCache> shapeCache =
+ new ThreadLocal<ShapeCache>();
/**
* The scanline converters by thread.
*/
- private static final ThreadLocal scanlineConverters =
- new ThreadLocal();
+ private static final ThreadLocal<ScanlineConverter> scanlineConverters =
+ new ThreadLocal<ScanlineConverter>();
/**
* The transformation for this Graphics2D instance
@@ -1947,7 +1947,7 @@
*/
private ShapeCache getShapeCache()
{
- ShapeCache sc = (ShapeCache) shapeCache.get();
+ ShapeCache sc = shapeCache.get();
if (sc == null)
{
sc = new ShapeCache();
@@ -1963,7 +1963,7 @@
*/
private ScanlineConverter getScanlineConverter()
{
- ScanlineConverter sc = (ScanlineConverter) scanlineConverters.get();
+ ScanlineConverter sc = scanlineConverters.get();
if (sc == null)
{
sc = new ScanlineConverter();
Added: trunk/core/src/classpath/gnu/gnu/java/nio/KqueueSelectionKeyImpl.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/nio/KqueueSelectionKeyImpl.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/java/nio/KqueueSelectionKeyImpl.java 2007-01-27 11:43:17 UTC (rev 3091)
@@ -0,0 +1,189 @@
+/* KqueueSelectionKeyImpl.java -- selection key for kqueue/kevent.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.nio;
+
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.spi.AbstractSelectionKey;
+
+/**
+ * @author Casey Marshall (cs...@gn...)
+ */
+public class KqueueSelectionKeyImpl extends AbstractSelectionKey
+{
+ int interestOps;
+ int readyOps;
+ int activeOps = 0;
+ int key;
+ int fd;
+
+ /** The selector we were created for. */
+ private final KqueueSelectorImpl selector;
+
+ /** The channel we are attached to. */
+ private final SelectableChannel channel;
+
+ private final VMChannelOwner natChannel;
+
+ public KqueueSelectionKeyImpl(KqueueSelectorImpl selector,
+ SelectableChannel channel)
+ {
+ this.selector = selector;
+ this.channel = channel;
+ natChannel = (VMChannelOwner) channel;
+ interestOps = 0;
+ readyOps = 0;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.SelectionKey#channel()
+ */
+ //@Override
+ public SelectableChannel channel()
+ {
+ return channel;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.SelectionKey#interestOps()
+ */
+ //@Override
+ public int interestOps()
+ {
+ return interestOps;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.SelectionKey#interestOps(int)
+ */
+ //@Override
+ public SelectionKey interestOps(int ops)
+ {
+ if (!isValid())
+ throw new IllegalStateException("key is invalid");
+ if ((ops & ~channel.validOps()) != 0)
+ throw new IllegalArgumentException("channel does not support all operations");
+
+ selector.setInterestOps(this, ops);
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.SelectionKey#readyOps()
+ */
+ //@Override
+ public int readyOps()
+ {
+ return readyOps;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.SelectionKey#selector()
+ */
+ //@Override
+ public Selector selector()
+ {
+ return selector;
+ }
+
+ public String toString()
+ {
+ if (!isValid())
+ return super.toString() + " [ fd: " + fd + " <<invalid>> ]";
+ return super.toString() + " [ fd: " + fd + " interest ops: {"
+ + ((interestOps & OP_ACCEPT) != 0 ? " OP_ACCEPT" : "")
+ + ((interestOps & OP_CONNECT) != 0 ? " OP_CONNECT" : "")
+ + ((interestOps & OP_READ) != 0 ? " OP_READ" : "")
+ + ((interestOps & OP_WRITE) != 0 ? " OP_WRITE" : "")
+ + " }; ready ops: {"
+ + ((readyOps & OP_ACCEPT) != 0 ? " OP_ACCEPT" : "")
+ + ((readyOps & OP_CONNECT) != 0 ? " OP_CONNECT" : "")
+ + ((readyOps & OP_READ) != 0 ? " OP_READ" : "")
+ + ((readyOps & OP_WRITE) != 0 ? " OP_WRITE" : "")
+ + " } ]";
+ }
+
+ public int hashCode()
+ {
+ return fd;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof KqueueSelectionKeyImpl))
+ return false;
+ KqueueSelectionKeyImpl that = (KqueueSelectionKeyImpl) o;
+ return that.fd == this.fd && that.channel.equals(this.channel);
+ }
+
+
+ boolean isReadActive()
+ {
+ return (activeOps & (OP_READ | OP_ACCEPT)) != 0;
+ }
+
+ boolean isReadInterested()
+ {
+ return (interestOps & (OP_READ | OP_ACCEPT)) != 0;
+ }
+
+ boolean isWriteActive()
+ {
+ return (activeOps & (OP_WRITE | OP_CONNECT)) != 0;
+ }
+
+ boolean isWriteInterested()
+ {
+ return (interestOps & (OP_WRITE | OP_CONNECT)) != 0;
+ }
+
+ boolean needCommitRead()
+ {
+ return isReadActive() == (!isReadInterested());
+ }
+
+ boolean needCommitWrite()
+ {
+ return isWriteActive() == (!isWriteInterested());
+ }
+}
Added: trunk/core/src/classpath/gnu/gnu/java/nio/KqueueSelectorImpl.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/nio/KqueueSelectorImpl.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/java/nio/KqueueSelectorImpl.java 2007-01-27 11:43:17 UTC (rev 3091)
@@ -0,0 +1,527 @@
+/* KqueueSelectorImpl.java -- Selector for systems with kqueue event notification.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.nio;
+
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.ClosedSelectorException;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.AbstractSelector;
+import java.nio.channels.spi.SelectorProvider;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A {@link Selector} implementation that uses the <code>kqueue</code>
+ * event notification facility.
+ *
+ * @author Casey Marshall (cs...@gn...)
+ */
+public class KqueueSelectorImpl extends AbstractSelector
+{
+ // Prepended underscore to field name to make it distinct
+ // from the method with the similar name.
+ private static final int _sizeof_struct_kevent;
+
+ private static final int MAX_DOUBLING_CAPACITY = 16384;
+ private static final int CAP_INCREMENT = 1024;
+ private static final int INITIAL_CAPACITY;
+
+ static
+ {
+ try
+ {
+ System.loadLibrary("javanio");
+ }
+ catch (Exception x)
+ {
+ x.printStackTrace();
+ }
+
+ if (kqueue_supported ())
+ _sizeof_struct_kevent = sizeof_struct_kevent();
+ else
+ _sizeof_struct_kevent = -1;
+ INITIAL_CAPACITY = 16 * _sizeof_struct_kevent;
+ }
+
+ /**
+ * Tell if kqueue-based selectors are supported on this system.
+ *
+ * @return True if this system has kqueue support, and support for it was
+ * compiled in to Classpath.
+ */
+ public static native boolean kqueue_supported();
+
+ /* Our native file descriptor. */
+ private int kq;
+
+ private HashMap/*<Integer,KqueueSelectionKeyImpl>*/ keys;
+ private HashSet/*<KqueueSelectionKeyImpl>*/ selected;
+ private Thread blockedThread;
+ private ByteBuffer events;
+
+ private static final int OP_ACCEPT = SelectionKey.OP_ACCEPT;
+ private static final int OP_CONNECT = SelectionKey.OP_CONNECT;
+ private static final int OP_READ = SelectionKey.OP_READ;
+ private static final int OP_WRITE = SelectionKey.OP_WRITE;
+
+ public KqueueSelectorImpl(SelectorProvider provider) throws IOException
+ {
+ super(provider);
+ kq = implOpen();
+ keys = new HashMap/*<KqueueSelectionKeyImpl>*/();
+ events = ByteBuffer.allocateDirect(INITIAL_CAPACITY);
+ }
+
+ protected void implCloseSelector() throws IOException
+ {
+ implClose(kq);
+ kq = -1;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#keys()
+ */
+ public Set keys()
+ {
+ if (!isOpen())
+ throw new ClosedSelectorException();
+
+ return new HashSet(keys.values());
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#select()
+ */
+ public int select() throws IOException
+ {
+ return doSelect(-1);
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#select(long)
+ */
+ public int select(long timeout) throws IOException
+ {
+ if (timeout == 0)
+ timeout = -1;
+ return doSelect(timeout);
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#selectedKeys()
+ */
+ public Set selectedKeys()
+ {
+ if (!isOpen())
+ throw new ClosedSelectorException();
+
+ return selected;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#selectNow()
+ */
+ public int selectNow() throws IOException
+ {
+ return doSelect(0);
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#wakeup()
+ */
+ public Selector wakeup()
+ {
+ if (blockedThread != null)
+ blockedThread.interrupt();
+ return this;
+ }
+
+ public String toString()
+ {
+ return super.toString() + " [ fd: " + kq + " ]";
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof KqueueSelectorImpl))
+ return false;
+
+ return ((KqueueSelectorImpl) o).kq == kq;
+ }
+
+ int doSelect(long timeout) throws IOException
+ {
+ Set cancelled = cancelledKeys();
+ synchronized (cancelled)
+ {
+ synchronized (keys)
+ {
+ for (Iterator it = cancelled.iterator(); it.hasNext(); )
+ {
+ KqueueSelectionKeyImpl key = (KqueueSelectionKeyImpl) it.next();
+ key.interestOps = 0;
+ }
+
+ int events_size = (2 * _sizeof_struct_kevent) * keys.size();
+ int num_events = 0;
+
+ for (Iterator it = keys.entrySet().iterator(); it.hasNext(); )
+ {
+ Map.Entry e = (Map.Entry) it.next();
+ KqueueSelectionKeyImpl key = (KqueueSelectionKeyImpl) e.getValue();
+
+ SelectableChannel ch = key.channel();
+ if (ch instanceof VMChannelOwner)
+ {
+ if (!((VMChannelOwner) ch).getVMChannel().getState().isValid())
+ {
+ // closed channel; removed from kqueue automatically.
+ it.remove();
+ continue;
+ }
+ }
+
+ // If this key is registering a read filter, add it to the buffer.
+ if (key.needCommitRead())
+ {
+ kevent_set(events, num_events, key.fd,
+ key.interestOps & (OP_READ | OP_ACCEPT),
+ key.activeOps & (OP_READ | OP_ACCEPT), key.key);
+ num_events++;
+ }
+
+ // If this key is registering a write filter, add it to the buffer.
+ if (key.needCommitWrite())
+ {
+ kevent_set(events, num_events, key.fd,
+ key.interestOps & (OP_WRITE | OP_CONNECT),
+ key.activeOps & (OP_WRITE | OP_CONNECT), key.key);
+ num_events++;
+ }
+ }
+ events.rewind().limit(events.capacity());
+
+ //System.out.println("dump of keys to select:");
+ //dump_selection_keys(events.duplicate());
+
+ int n = 0;
+ try
+ {
+ //System.out.println("[" + kq + "] kevent enter selecting from " + keys.size());
+ begin();
+ blockedThread = Thread.currentThread();
+ if (blockedThread.isInterrupted())
+ timeout = 0;
+ n = kevent(kq, events, num_events,
+ events.capacity() / _sizeof_struct_kevent, timeout);
+ }
+ finally
+ {
+ end();
+ blockedThread = null;
+ Thread.interrupted();
+ //System.out.println("[" + kq + "kevent exit selected " + n);
+ }
+
+ //System.out.println("dump of keys selected:");
+ //dump_selection_keys((ByteBuffer) events.duplicate().limit(n * _sizeof_struct_kevent));
+
+ // Commit the operations we've just added in the call to kevent.
+ for (Iterator it = keys.values().iterator(); it.hasNext(); )
+ {
+ KqueueSelectionKeyImpl key = (KqueueSelectionKeyImpl) it.next();
+ key.activeOps = key.interestOps;
+ }
+
+ selected = new HashSet/*<KqueueSelectionKeyImpl>*/(n);
+ int x = 0;
+ for (int i = 0; i < n; i++)
+ {
+ events.position(x).limit(x + _sizeof_struct_kevent);
+ x += _sizeof_struct_kevent;
+ int y = fetch_key(events.slice());
+ KqueueSelectionKeyImpl key =
+ (KqueueSelectionKeyImpl) keys.get(new Integer(y));
+
+ if (key == null)
+ {
+ System.out.println("WARNING! no key found for selected key " + y);
+ continue;
+ }
+ // Keys that have been cancelled may be returned here; don't
+ // add them to the selected set.
+ if (!key.isValid())
+ continue;
+ key.readyOps = ready_ops(events.slice(), key.interestOps);
+ selected.add(key);
+ }
+
+ // Finally, remove the cancelled keys.
+ for (Iterator it = cancelled.iterator(); it.hasNext(); )
+ {
+ KqueueSelectionKeyImpl key = (KqueueSelectionKeyImpl) it.next();
+ keys.remove(new Integer(key.key));
+ deregister(key);
+ it.remove();
+ }
+
+ reallocateBuffer();
+
+ return selected.size();
+ }
+ }
+ }
+
+ protected SelectionKey register(AbstractSelectableChannel channel,
+ int interestOps,
+ Object attachment)
+ {
+ int native_fd = -1;
+ try
+ {
+ if (channel instanceof VMChannelOwner)
+ native_fd = ((VMChannelOwner) channel).getVMChannel()
+ .getState().getNativeFD();
+ else
+ throw new IllegalArgumentException("cannot handle channel type " +
+ channel.getClass().getName());
+ }
+ catch (IOException ioe)
+ {
+ throw new IllegalArgumentException("channel is closed or invalid");
+ }
+
+ KqueueSelectionKeyImpl result = new KqueueSelectionKeyImpl(this, channel);
+ result.interestOps = interestOps;
+ result.attach(attachment);
+ result.fd = native_fd;
+ result.key = System.identityHashCode(result);
+ synchronized (keys)
+ {
+ while (keys.containsKey(new Integer(result.key)))
+ result.key++;
+ keys.put(new Integer(result.key), result);
+ reallocateBuffer();
+ }
+ return result;
+ }
+
+ void setInterestOps(KqueueSelectionKeyImpl key, int ops)
+ {
+ synchronized (keys)
+ {
+ key.interestOps = ops;
+ }
+ }
+
+ /**
+ * Reallocate the events buffer. This is the destination buffer for
+ * events returned by kevent. This method will:
+ *
+ * * Grow the buffer if there is insufficent space for all registered
+ * events.
+ * * Shrink the buffer if it is more than twice the size needed.
+ *
+ */
+ private void reallocateBuffer()
+ {
+ synchronized (keys)
+ {
+ if (events.capacity() < (2 * _sizeof_struct_kevent) * keys.size())
+ {
+ int cap = events.capacity();
+ if (cap >= MAX_DOUBLING_CAPACITY)
+ cap += CAP_INCREMENT;
+ else
+ cap = cap << 1;
+
+ events = ByteBuffer.allocateDirect(cap);
+ }
+ else if (events.capacity() > 4 * (_sizeof_struct_kevent) * keys.size() + 1
+ && events.capacity() > INITIAL_CAPACITY)
+ {
+ int cap = events.capacity();
+ cap = cap >>> 1;
+ events = ByteBuffer.allocateDirect(cap);
+ }
+ }
+ }
+
+ //synchronized void updateOps(KqueueSelectionKeyImpl key, int interestOps)
+ //{
+ // updateOps(key, interestOps, 0, false);
+ //}
+
+ /*void updateOps(KqueueSelectionKeyImpl key, int interestOps,
+ int activeOps, int fd)
+ {
+ //System.out.println(">> updating kqueue selection key:");
+ //dump_selection_keys(key.nstate.duplicate());
+ //System.out.println("<<");
+ synchronized (keys)
+ {
+ kevent_set(key.nstate, fd, interestOps, activeOps, key.key);
+ }
+ //System.out.println(">> updated kqueue selection key:");
+ //dump_selection_keys(key.nstate.duplicate());
+ //System.out.println("<<");
+ }*/
+
+ private void dump_selection_keys(ByteBuffer keys)
+ {
+ // WARNING! This method is not guaranteed to be portable! This works
+ // on darwin/x86, but the sizeof and offsetof these fields may be
+ // different on other platforms!
+ int i = 0;
+ keys.order(ByteOrder.nativeOrder());
+ while (keys.hasRemaining())
+ {
+ System.out.println("struct kevent { ident: "
+ + Integer.toString(keys.getInt())
+ + " filter: "
+ + Integer.toHexString(keys.getShort() & 0xFFFF)
+ + " flags: "
+ + Integer.toHexString(keys.getShort() & 0xFFFF)
+ + " fflags: "
+ + Integer.toHexString(keys.getInt())
+ + " data: "
+ + Integer.toHexString(keys.getInt())
+ + " udata: "
+ + Integer.toHexString(keys.getInt())
+ + " }");
+ }
+ }
+
+ /**
+ * Return the size of a <code>struct kevent</code> on this system.
+ *
+ * @return The size of <code>struct kevent</code>.
+ */
+ private static native int sizeof_struct_kevent();
+
+ /**
+ * Opens a kqueue descriptor.
+ *
+ * @return The new kqueue descriptor.
+ * @throws IOException If opening fails.
+ */
+ private static native int implOpen() throws IOException;
+
+ /**
+ * Closes the kqueue file descriptor.
+ *
+ * @param kq The kqueue file descriptor.
+ * @throws IOException
+ */
+ private static native void implClose(int kq) throws IOException;
+
+ /**
+ * Initialize the specified native state for the given interest ops.
+ *
+ * @param nstate The native state structures; in this buffer should be
+ * the <code>struct kevent</code>s created for a key.
+ * @param fd The file descriptor. If 0, the native FD is unmodified.
+ * @param interestOps The operations to enable.
+ * @param key A unique key that will reference the associated key later.
+ * @param delete Set to true if this event should be deleted from the
+ * kqueue (if false, this event is added/updated).
+ */
+ private static native void kevent_set(ByteBuffer nstate, int i, int fd,
+ int interestOps, int activeOps, int key);
+
+ /**
+ * Poll for events. The source events are stored in <code>events</code>,
+ * which is also where polled events will be placed.
+ *
+ * @param events The events to poll. This buffer is also the destination
+ * for events read from the queue.
+ * @param nevents The number of events to poll (that is, the number of
+ * events in the <code>events</code> buffer).
+ * @param nout The maximum number of events that may be returned.
+ * @param timeout The timeout. A timeout of -1 returns immediately; a timeout
+ * of 0 waits indefinitely.
+ * @return The number of events read.
+ */
+ private static native int kevent(int kq, ByteBuffer events, int nevents,
+ int nout, long timeout);
+
+ /**
+ * Fetch a polled key from a native state buffer. For each kevent key we
+ * create, we put the native state info (one or more <code>struct
+ * kevent</code>s) in that key's {@link KqueueSelectionKeyImpl#nstate}
+ * buffer, and place the pointer of the key in the <code>udata</code> field
+ * of that structure. This method fetches that pointer from the given
+ * buffer (assumed to be a <code>struct kqueue</code>) and returns it.
+ *
+ * @param nstate The buffer containing the <code>struct kqueue</code> to read.
+ * @return The key object.
+ */
+ private static native int fetch_key(ByteBuffer nstate);
+
+ /**
+ * Fetch the ready ops of the associated native state. That is, this
+ * inspects the first argument as a <code>struct kevent</code>, looking
+ * at its operation (the input is assumed to have been returned via a
+ * previous call to <code>kevent</code>), and translating that to the
+ * appropriate Java bit set, based on the second argument.
+ *
+ * @param nstate The native state.
+ * @param interestOps The enabled operations for the key.
+ * @return The bit set representing the ready operations.
+ */
+ private static native int ready_ops(ByteBuffer nstate, int interestOps);
+
+ /**
+ * Check if kevent returned EV_EOF for a selection key.
+ *
+ * @param nstate The native state.
+ * @return True if the kevent call returned EOF.
+ */
+ private static native boolean check_eof(ByteBuffer nstate);
+}
Added: trunk/core/src/classpath/gnu/gnu/java/nio/VMChannelOwner.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/nio/VMChannelOwner.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/java/nio/VMChannelOwner.java 2007-01-27 11:43:17 UTC (rev 3091)
@@ -0,0 +1,57 @@
+/* NativeFD.java -- interface for Channels that have an underlying file descriptor.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.nio;
+
+/**
+ * This interface is meant to be implemented by any {@link Channel}
+ * implementation we support that uses a platform-specific {@link VMChannel}
+ * at their core. This is primarily used by {@link Selector} implementations,
+ * for easier access to the native state.
+ *
+ * @author Casey Marshall (cs...@gn...)
+ */
+interface VMChannelOwner
+{
+ /**
+ * Return the underlying platform-specific Channel instance.
+ *
+ * @return The platform channel object.
+ */
+ VMChannel getVMChannel();
+}
Modified: trunk/core/src/classpath/java/java/lang/InheritableThreadLocal.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/InheritableThreadLocal.java 2007-01-27 10:06:33 UTC (rev 3090)
+++ trunk/core/src/classpath/java/java/lang/InheritableThreadLocal.java 2007-01-27 11:43:17 UTC (rev 3091)
@@ -53,12 +53,15 @@
*
* @author Mark Wielaard (ma...@kl...)
* @author Eric Blake (eb...@em...)
+ * @author Tom Tromey (tr...@re...)
+ * @author Andrew John Hughes (gnu...@me...)
* @see ThreadLocal
* @since 1.2
* @status updated to 1.4
*/
public class InheritableThreadLocal extends ThreadLocal
{
+
/**
* Creates a new InheritableThreadLocal that has no values associated
* with it yet.
Modified: trunk/core/src/classpath/java/java/lang/StringBuffer.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/StringBuffer.java 2007-01-27 10:06:33 UTC (rev 3090)
+++ trunk/core/src/classpath/java/java/lang/StringBuffer.java 2007-01-27 11:43:17 UTC (rev 3091)
@@ -72,8 +72,12 @@
* @since 1.0
* @st...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-27 21:52:49
|
Revision: 3095
http://jnode.svn.sourceforge.net/jnode/?rev=3095&view=rev
Author: lsantha
Date: 2007-01-27 13:52:45 -0800 (Sat, 27 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/lang/Compiler.java
trunk/core/src/classpath/java/java/lang/Math.java
trunk/core/src/classpath/java/java/lang/SecurityManager.java
trunk/core/src/classpath/java/java/lang/StrictMath.java
trunk/core/src/classpath/java/java/lang/ThreadGroup.java
trunk/core/src/classpath/vm/java/lang/Thread.java
Added Paths:
-----------
trunk/core/src/classpath/vm/java/lang/VMMath.java
Modified: trunk/core/src/classpath/java/java/lang/Compiler.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/Compiler.java 2007-01-27 21:37:48 UTC (rev 3094)
+++ trunk/core/src/classpath/java/java/lang/Compiler.java 2007-01-27 21:52:45 UTC (rev 3095)
@@ -74,7 +74,7 @@
* compilation failed, <code>true</code> if compilation succeeded
* @throws NullPointerException if oneClass is null
*/
- public static boolean compileClass(Class oneClass)
+ public static boolean compileClass(Class<?> oneClass)
{
return VMCompiler.compileClass(oneClass);
}
Modified: trunk/core/src/classpath/java/java/lang/Math.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/Math.java 2007-01-27 21:37:48 UTC (rev 3094)
+++ trunk/core/src/classpath/java/java/lang/Math.java 2007-01-27 21:52:45 UTC (rev 3095)
@@ -1,5 +1,5 @@
-/* java.lang.Math -- common mathematical functions, native allowed
- Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+/* java.lang.Math -- common mathematical functions, native allowed (VMMath)
+ Copyright (C) 1998, 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,6 +38,8 @@
package java.lang;
+import gnu.classpath.Configuration;
+
import java.util.Random;
/**
@@ -50,10 +52,26 @@
* @author Paul Fisher
* @author John Keiser
* @author Eric Blake (eb...@em...)
+ * @author Andrew John Hughes (gnu...@me...)
* @since 1.0
*/
public final class Math
{
+
+ // FIXME - This is here because we need to load the "javalang" system
+ // library somewhere late in the bootstrap cycle. We cannot do this
+ // from VMSystem or VMRuntime since those are used to actually load
+ // the library. This is mainly here because historically Math was
+ // late enough in the bootstrap cycle to start using System after it
+ // was initialized (called from the java.util classes).
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javalang");
+ }
+ }
+
/**
* Math is non-instantiable
*/
@@ -288,11 +306,10 @@
* @param a the angle (in radians)
* @return sin(a)
*/
- // @classpath-bugfix-22918
- public static double sin(double a) {
- return StrictMath.sin(a);
+ public static double sin(double a)
+ {
+ return VMMath.sin(a);
}
- // @classpath-bugfix-end
/**
* The trigonometric function <em>cos</em>. The cosine of NaN or infinity is
@@ -301,11 +318,10 @@
* @param a the angle (in radians)
* @return cos(a)
*/
- // @classpath-bugfix-22918
- public static double cos(double a) {
- return StrictMath.cos(a);
+ public static double cos(double a)
+ {
+ return VMMath.cos(a);
}
- // @classpath-bugfix-end
/**
* The trigonometric function <em>tan</em>. The tangent of NaN or infinity
@@ -315,11 +331,10 @@
* @param a the angle (in radians)
* @return tan(a)
*/
- // @classpath-bugfix-22918
- public static double tan(double a) {
- return StrictMath.tan(a);
+ public static double tan(double a)
+ {
+ return VMMath.tan(a);
}
- // @classpath-bugfix-end
/**
* The trigonometric function <em>arcsin</em>. The range of angles returned
@@ -330,11 +345,10 @@
* @param a the sin to turn back into an angle
* @return arcsin(a)
*/
- // @classpath-bugfix-22918
- public static double asin(double a) {
- return StrictMath.asin(a);
+ public static double asin(double a)
+ {
+ return VMMath.asin(a);
}
- // @classpath-bugfix-end
/**
* The trigonometric function <em>arccos</em>. The range of angles returned
@@ -345,11 +359,10 @@
* @param a the cos to turn back into an angle
* @return arccos(a)
*/
- // @classpath-bugfix-22918
- public static double acos(double a) {
- return StrictMath.acos(a);
+ public static double acos(double a)
+ {
+ return VMMath.acos(a);
}
- // @classpath-bugfix-end
/**
* The trigonometric function <em>arcsin</em>. The range of angles returned
@@ -361,11 +374,10 @@
* @return arcsin(a)
* @see #atan2(double, double)
*/
- // @classpath-bugfix-22918
- public static double atan(double a) {
- return StrictMath.atan(a);
+ public static double atan(double a)
+ {
+ return VMMath.atan(a);
}
- // @classpath-bugfix-end
/**
* A special version of the trigonometric function <em>arctan</em>, for
@@ -414,11 +426,10 @@
* @return <em>theta</em> in the conversion of (x, y) to (r, theta)
* @see #atan(double)
*/
- // @classpath-bugfix-22918
- public static double atan2(double y, double x) {
- return StrictMath.atan2(y, x);
+ public static double atan2(double y, double x)
+ {
+ return VMMath.atan2(y,x);
}
- // @classpath-bugfix-end
/**
* Take <em>e</em><sup>a</sup>. The opposite of <code>log()</code>. If the
@@ -432,11 +443,10 @@
* @see #log(double)
* @see #pow(double, double)
*/
- // @classpath-bugfix-22918
- public static double exp(double a) {
- return StrictMath.exp(a);
+ public static double exp(double a)
+ {
+ return VMMath.exp(a);
}
- // @classpath-bugfix-end
/**
* Take ln(a) (the natural log). The opposite of <code>exp()</code>. If the
@@ -452,11 +462,10 @@
* @return the natural log of <code>a</code>
* @see #exp(double)
*/
- // @classpath-bugfix-22918
- public static double log(double a) {
- return StrictMath.log(a);
+ public static double log(double a)
+ {
+ return VMMath.log(a);
}
- // @classpath-bugfix-end
/**
* Take a square root. If the argument is NaN or negative, the result is
@@ -464,17 +473,18 @@
* infinity; and if the result is either zero, the result is the same.
* This is accurate within the limits of doubles.
*
- * <p>For other roots, use pow(a, 1 / rootNumber).
+ * <p>For a cube root, use <code>cbrt</code>. For other roots, use
+ * <code>pow(a, 1 / rootNumber)</code>.</p>
*
* @param a the numeric argument
* @return the square root of the argument
+ * @see #cbrt(double)
* @see #pow(double, double)
*/
- // @classpath-bugfix-22918
- public static double sqrt(double a) {
- return StrictMath.sqrt(a);
+ public static double sqrt(double a)
+ {
+ return VMMath.sqrt(a);
}
- // @classpath-bugfix-end
/**
* Raise a number to a power. Special cases:<ul>
@@ -544,11 +554,10 @@
* @param b the power to raise it to
* @return a<sup>b</sup>
*/
- // @classpath-bugfix-22918
- public static double pow(double a, double b) {
- return StrictMath.pow(a, b);
+ public static double pow(double a, double b)
+ {
+ return VMMath.pow(a,b);
}
- // @classpath-bugfix-end
/**
* Get the IEEE 754 floating point remainder on two numbers. This is the
@@ -564,11 +573,10 @@
* @return the IEEE 754-defined floating point remainder of x/y
* @see #rint(double)
*/
- // @classpath-bugfix-22918
- public static double IEEEremainder(double x, double y) {
- return StrictMath.IEEEremainder(x, y);
+ public static double IEEEremainder(double x, double y)
+ {
+ return VMMath.IEEEremainder(x,y);
}
- // @classpath-bugfix-end
/**
* Take the nearest integer that is that is greater than or equal to the
@@ -579,11 +587,10 @@
* @param a the value to act upon
* @return the nearest integer >= <code>a</code>
*/
- // @classpath-bugfix-22918
- public static double ceil(double a) {
- return StrictMath.ceil(a);
+ public static double ceil(double a)
+ {
+ return VMMath.ceil(a);
}
- // @classpath-bugfix-end
/**
* Take the nearest integer that is that is less than or equal to the
@@ -593,11 +600,10 @@
* @param a the value to act upon
* @return the nearest integer <= <code>a</code>
*/
- // @classpath-bugfix-22918
- public static double floor(double a) {
- return StrictMath.floor(a);
+ public static double floor(double a)
+ {
+ return VMMath.floor(a);
}
- // @classpath-bugfix-end
/**
* Take the nearest integer to the argument. If it is exactly between
@@ -607,12 +613,10 @@
* @param a the value to act upon
* @return the nearest integer to <code>a</code>
*/
- // @classpath-bugfix-22918
public static double rint(double a)
{
- return StrictMath.rint(a);
+ return VMMath.rint(a);
}
- // @classpath-bugfix-end
/**
* Take the nearest integer to the argument. This is equivalent to
@@ -701,6 +705,99 @@
/**
* <p>
+ * Take a cube root. If the argument is <code>NaN</code>, an infinity or
+ * zero, then the original value is returned. The returned result is
+ * within 1 ulp of the exact result. For a finite value, <code>x</code>,
+ * the cube root of <code>-x</code> is equal to the negation of the cube root
+ * of <code>x</code>.
+ * </p>
+ * <p>
+ * For a square root, use <code>sqrt</code>. For other roots, use
+ * <code>pow(a, 1 / rootNumber)</code>.
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return the cube root of the argument
+ * @see #sqrt(double)
+ * @see #pow(double, double)
+ * @since 1.5
+ */
+ public static double cbrt(double a)
+ {
+ return VMMath.cbrt(a);
+ }
+
+ /**
+ * <p>
+ * Returns the hyperbolic cosine of the given value. For a value,
+ * <code>x</code>, the hyperbolic cosine is <code>(e<sup>x</sup> +
+ * e<sup>-x</sup>)/2</code>
+ * with <code>e</code> being <a href="#E">Euler's number</a>. The returned
+ * result is within 2.5 ulps of the exact result.
+ * </p>
+ * <p>
+ * If the supplied value is <code>NaN</code>, then the original value is
+ * returned. For either infinity, positive infinity is returned.
+ * The hyperbolic cosine of zero is 1.0.
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return the hyperbolic cosine of <code>a</code>.
+ * @since 1.5
+ */
+ public static double cosh(double a)
+ {
+ return VMMath.cosh(a);
+ }
+
+ /**
+ * <p>
+ * Returns <code>e<sup>a</sup> - 1. For values close to 0, the
+ * result of <code>expm1(a) + 1</code> tend to be much closer to the
+ * exact result than simply <code>exp(x)</code>. The result is within
+ * 1 ulp of the exact result, and results are semi-monotonic. For finite
+ * inputs, the returned value is greater than or equal to -1.0. Once
+ * a result enters within half a ulp of this limit, the limit is returned.
+ * </p>
+ * <p>
+ * For <code>NaN</code>, positive infinity and zero, the original value
+ * is returned. Negative infinity returns a result of -1.0 (the limit).
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return <code>e<sup>a</sup> - 1</code>
+ * @since 1.5
+ */
+ public static double expm1(double a)
+ {
+ return VMMath.expm1(a);
+ }
+
+ /**
+ * <p>
+ * Returns the hypotenuse, <code>a<sup>2</sup> + b<sup>2</sup></code>,
+ * without intermediate overflow or underflow. The returned result is
+ * within 1 ulp of the exact result. If one parameter is held constant,
+ * then the result in the other parameter is semi-monotonic.
+ * </p>
+ * <p>
+ * If either of the arguments is an infinity, then the returned result
+ * is positive infinity. Otherwise, if either argument is <code>NaN</code>,
+ * then <code>NaN</code> is returned.
+ * </p>
+ *
+ * @param a the first parameter.
+ * @param b the second parameter.
+ * @return the hypotenuse matching the supplied parameters.
+ * @since 1.5
+ */
+ public static double hypot(double a, double b)
+ {
+ return VMMath.hypot(a,b);
+ }
+
+ /**
+ * <p>
* Returns the base 10 logarithm of the supplied value. The returned
* result is within 1 ulp of the exact result, and the results are
* semi-monotonic.
@@ -719,7 +816,7 @@
*/
public static double log10(double a)
{
- return log(a)/log(10);
+ return VMMath.log10(a);
}
/**
@@ -744,7 +841,7 @@
*/
public static double log1p(double a)
{
- return log(a + 1);
+ return VMMath.log1p(a);
}
/**
@@ -800,7 +897,58 @@
return -1.0f;
return a;
}
+
/**
+ * <p>
+ * Returns the hyperbolic sine of the given value. For a value,
+ * <code>x</code>, the hyperbolic sine is <code>(e<sup>x</sup> -
+ * e<sup>-x</sup>)/2</code>
+ * with <code>e</code> being <a href="#E">Euler's number</a>. The returned
+ * result is within 2.5 ulps of the exact result.
+ * </p>
+ * <p>
+ * If the supplied value is <code>NaN</code>, an infinity or a zero, then the
+ * original value is returned.
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return the hyperbolic sine of <code>a</code>.
+ * @since 1.5
+ */
+ public static double sinh(double a)
+ {
+ return VMMath.sinh(a);
+ }
+
+ /**
+ * <p>
+ * Returns the hyperbolic tangent of the given value. For a value,
+ * <code>x</code>, the hyperbolic tangent is <code>(e<sup>x</sup> -
+ * e<sup>-x</sup>)/(e<sup>x</sup> + e<sup>-x</sup>)</code>
+ * (i.e. <code>sinh(a)/cosh(a)</code>)
+ * with <code>e</code> being <a href="#E">Euler's number</a>. The returned
+ * result is within 2.5 ulps of the exact result. The absolute value
+ * of the exact result is always less than 1. Computed results are thus
+ * less than or equal to 1 for finite arguments, with results within
+ * half a ulp of either positive or negative 1 returning the appropriate
+ * limit value (i.e. as if the argument was an infinity).
+ * </p>
+ * <p>
+ * If the supplied value is <code>NaN</code> or zero, then the original
+ * value is returned. Positive infinity returns +1.0 and negative infinity
+ * returns -1.0.
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return the hyperbolic tangent of <code>a</code>.
+ * @since 1.5
+ */
+ public static double tanh(double a)
+ {
+ return VMMath.tanh(a);
+ }
+
+ /**
* Return the ulp for the given double argument. The ulp is the
* difference between the argument and the next larger double. Note
* that the sign of the double argument is ignored, that is,
Modified: trunk/core/src/classpath/java/java/lang/SecurityManager.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/SecurityManager.java 2007-01-27 21:37:48 UTC (rev 3094)
+++ trunk/core/src/classpath/java/java/lang/SecurityManager.java 2007-01-27 21:52:45 UTC (rev 3095)
@@ -1,5 +1,5 @@
/* SecurityManager.java -- security checks for privileged actions
- Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -240,7 +240,7 @@
* @return the most recent non-system Class on the execution stack
* @deprecated use {@link #checkPermission(Permission)} instead
*/
- protected Class currentLoadedClass()
+ protected Class<?> currentLoadedClass()
{
int i = classLoaderDepth();
return i >= 0 ? getClassContext()[i] : null;
@@ -421,7 +421,7 @@
public void checkAccess(Thread thread)
{
if (thread.getThreadGroup() != null
- && thread.getThreadGroup().getParent() == null)
+ && thread.getThreadGroup().parent == null)
checkPermission(new RuntimePermission("modifyThread"));
}
@@ -454,7 +454,7 @@
*/
public void checkAccess(ThreadGroup g)
{
- if (g.getParent() == null)
+ if (g.parent == null)
checkPermission(new RuntimePermission("modifyThreadGroup"));
}
@@ -983,7 +983,7 @@
* @see Member#PUBLIC
* @since 1.1
*/
- public void checkMemberAccess(Class c, int memberType)
+ public void checkMemberAccess(Class<?> c, int memberType)
{
if (c == null)
throw new NullPointerException();
Modified: trunk/core/src/classpath/java/java/lang/StrictMath.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/StrictMath.java 2007-01-27 21:37:48 UTC (rev 3094)
+++ trunk/core/src/classpath/java/java/lang/StrictMath.java 2007-01-27 21:52:45 UTC (rev 3095)
@@ -1,5 +1,5 @@
/* java.lang.StrictMath -- common mathematical functions, strict Java
- Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -633,6 +633,381 @@
}
/**
+ * Returns the hyperbolic sine of <code>x</code> which is defined as
+ * (exp(x) - exp(-x)) / 2.
+ *
+ * Special cases:
+ * <ul>
+ * <li>If the argument is NaN, the result is NaN</li>
+ * <li>If the argument is positive infinity, the result is positive
+ * infinity.</li>
+ * <li>If the argument is negative infinity, the result is negative
+ * infinity.</li>
+ * <li>If the argument is zero, the result is zero.</li>
+ * </ul>
+ *
+ * @param x the argument to <em>sinh</em>
+ * @return the hyperbolic sine of <code>x</code>
+ *
+ * @since 1.5
+ */
+ public static double sinh(double x)
+ {
+ // Method :
+ // mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
+ // 1. Replace x by |x| (sinh(-x) = -sinh(x)).
+ // 2.
+ // E + E/(E+1)
+ // 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x)
+ // 2
+ //
+ // 22 <= x <= lnovft : sinh(x) := exp(x)/2
+ // lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2)
+ // ln2ovft < x : sinh(x) := +inf (overflow)
+
+ double t, w, h;
+
+ long bits;
+ long h_bits;
+ long l_bits;
+
+ // handle special cases
+ if (x != x)
+ return x;
+ if (x == Double.POSITIVE_INFINITY)
+ return Double.POSITIVE_INFINITY;
+ if (x == Double.NEGATIVE_INFINITY)
+ return Double.NEGATIVE_INFINITY;
+
+ if (x < 0)
+ h = - 0.5;
+ else
+ h = 0.5;
+
+ bits = Double.doubleToLongBits(x);
+ h_bits = getHighDWord(bits) & 0x7fffffffL; // ignore sign
+ l_bits = getLowDWord(bits);
+
+ // |x| in [0, 22], return sign(x) * 0.5 * (E+E/(E+1))
+ if (h_bits < 0x40360000L) // |x| < 22
+ {
+ if (h_bits < 0x3e300000L) // |x| < 2^-28
+ return x; // for tiny arguments return x
+
+ t = expm1(abs(x));
+
+ if (h_bits < 0x3ff00000L)
+ return h * (2.0 * t - t * t / (t + 1.0));
+
+ return h * (t + t / (t + 1.0));
+ }
+
+ // |x| in [22, log(Double.MAX_VALUE)], return 0.5 * exp(|x|)
+ if (h_bits < 0x40862e42L)
+ return h * exp(abs(x));
+
+ // |x| in [log(Double.MAX_VALUE), overflowthreshold]
+ if ((h_bits < 0x408633ceL)
+ || ((h_bits == 0x408633ceL) && (l_bits <= 0x8fb9f87dL)))
+ {
+ w = exp(0.5 * abs(x));
+ t = h * w;
+
+ return t * w;
+ }
+
+ // |x| > overflowthershold
+ return h * Double.POSITIVE_INFINITY;
+ }
+
+ /**
+ * Returns the hyperbolic cosine of <code>x</code>, which is defined as
+ * (exp(x) + exp(-x)) / 2.
+ *
+ * Special cases:
+ * <ul>
+ * <li>If the argument is NaN, the result is NaN</li>
+ * <li>If the argument is positive infinity, the result is positive
+ * infinity.</li>
+ * <li>If the argument is negative infinity, the result is positive
+ * infinity.</li>
+ * <li>If the argument is zero, the result is one.</li>
+ * </ul>
+ *
+ * @param x the argument to <em>cosh</em>
+ * @return the hyperbolic cosine of <code>x</code>
+ *
+ * @since 1.5
+ */
+ public static double cosh(double x)
+ {
+ // Method :
+ // mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
+ // 1. Replace x by |x| (cosh(x) = cosh(-x)).
+ // 2.
+ // [ exp(x) - 1 ]^2
+ // 0 <= x <= ln2/2 : cosh(x) := 1 + -------------------
+ // 2*exp(x)
+ //
+ // exp(x) + 1/exp(x)
+ // ln2/2 <= x <= 22 : cosh(x) := ------------------
+ // 2
+ // 22 <= x <= lnovft : cosh(x) := exp(x)/2
+ // lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2)
+ // ln2ovft < x : cosh(x) := +inf (overflow)
+
+ double t, w;
+ long bits;
+ long hx;
+ long lx;
+
+ // handle special cases
+ if (x != x)
+ return x;
+ if (x == Double.POSITIVE_INFINITY)
+ return Double.POSITIVE_INFINITY;
+ if (x == Double.NEGATIVE_INFINITY)
+ return Double.POSITIVE_INFINITY;
+
+ bits = Double.doubleToLongBits(x);
+ hx = getHighDWord(bits) & 0x7fffffffL; // ignore sign
+ lx = getLowDWord(bits);
+
+ // |x| in [0, 0.5 * ln(2)], return 1 + expm1(|x|)^2 / (2 * exp(|x|))
+ if (hx < 0x3fd62e43L)
+ {
+ t = expm1(abs(x));
+ w = 1.0 + t;
+
+ // for tiny arguments return 1.
+ if (hx < 0x3c800000L)
+ return w;
+
+ return 1.0 + (t * t) / (w + w);
+ }
+
+ // |x| in [0.5 * ln(2), 22], return exp(|x|)/2 + 1 / (2 * exp(|x|))
+ if (hx < 0x40360000L)
+ {
+ t = exp(abs(x));
+
+ return 0.5 * t + 0.5 / t;
+ }
+
+ // |x| in [22, log(Double.MAX_VALUE)], return 0.5 * exp(|x|)
+ if (hx < 0x40862e42L)
+ return 0.5 * exp(abs(x));
+
+ // |x| in [log(Double.MAX_VALUE), overflowthreshold],
+ // return exp(x/2)/2 * exp(x/2)
+ if ((hx < 0x408633ceL)
+ || ((hx == 0x408633ceL) && (lx <= 0x8fb9f87dL)))
+ {
+ w = exp(0.5 * abs(x));
+ t = 0.5 * w;
+
+ return t * w;
+ }
+
+ // |x| > overflowthreshold
+ return Double.POSITIVE_INFINITY;
+ }
+
+ /**
+ * Returns the hyperbolic tangent of <code>x</code>, which is defined as
+ * (exp(x) - exp(-x)) / (exp(x) + exp(-x)), i.e. sinh(x) / cosh(x).
+ *
+ Special cases:
+ * <ul>
+ * <li>If the argument is NaN, the result is NaN</li>
+ * <li>If the argument is positive infinity, the result is 1.</li>
+ * <li>If the argument is negative infinity, the result is -1.</li>
+ * <li>If the argument is zero, the result is zero.</li>
+ * </ul>
+ *
+ * @param x the argument to <em>tanh</em>
+ * @return the hyperbolic tagent of <code>x</code>
+ *
+ * @since 1.5
+ */
+ public static double tanh(double x)
+ {
+ // Method :
+ // 0. tanh(x) is defined to be (exp(x) - exp(-x)) / (exp(x) + exp(-x))
+ // 1. reduce x to non-negative by tanh(-x) = -tanh(x).
+ // 2. 0 <= x <= 2^-55 : tanh(x) := x * (1.0 + x)
+ // -t
+ // 2^-55 < x <= 1 : tanh(x) := -----; t = expm1(-2x)
+ // t + 2
+ // 2
+ // 1 <= x <= 22.0 : tanh(x) := 1 - ----- ; t=expm1(2x)
+ // t + 2
+ // 22.0 < x <= INF : tanh(x) := 1.
+
+ double t, z;
+
+ long bits;
+ long h_bits;
+
+ // handle special cases
+ if (x != x)
+ return x;
+ if (x == Double.POSITIVE_INFINITY)
+ return 1.0;
+ if (x == Double.NEGATIVE_INFINITY)
+ return -1.0;
+
+ bits = Double.doubleToLongBits(x);
+ h_bits = getHighDWord(bits) & 0x7fffffffL; // ingnore sign
+
+ if (h_bits < 0x40360000L) // |x| < 22
+ {
+ if (h_bits < 0x3c800000L) // |x| < 2^-55
+ return x * (1.0 + x);
+
+ if (h_bits >= 0x3ff00000L) // |x| >= 1
+ {
+ t = expm1(2.0 * abs(x));
+ z = 1.0 - 2.0 / (t + 2.0);
+ }
+ else // |x| < 1
+ {
+ t = expm1(-2.0 * abs(x));
+ z = -t / (t + 2.0);
+ }
+ }
+ else // |x| >= 22
+ z = 1.0;
+
+ return (x >= 0) ? z : -z;
+ }
+
+ /**
+ * Returns the lower two words of a long. This is intended to be
+ * used like this:
+ * <code>getLowDWord(Double.doubleToLongBits(x))</code>.
+ */
+ private static long getLowDWord(long x)
+ {
+ return x & 0x00000000ffffffffL;
+ }
+
+ /**
+ * Returns the higher two words of a long. This is intended to be
+ * used like this:
+ * <code>getHighDWord(Double.doubleToLongBits(x))</code>.
+ */
+ private static long getHighDWord(long x)
+ {
+ return (x & 0xffffffff00000000L) >> 32;
+ }
+
+ /**
+ * Returns a double with the IEEE754 bit pattern given in the lower
+ * and higher two words <code>lowDWord</code> and <code>highDWord</code>.
+ */
+ private static double buildDouble(long lowDWord, long highDWord)
+ {
+ return Double.longBitsToDouble(((highDWord & 0xffffffffL) << 32)
+ | (lowDWord & 0xffffffffL));
+ }
+
+ /**
+ * Returns the cube root of <code>x</code>. The sign of the cube root
+ * is equal to the sign of <code>x</code>.
+ *
+ * Special cases:
+ * <ul>
+ * <li>If the argument is NaN, the result is NaN</li>
+ * <li>If the argument is positive infinity, the result is positive
+ * infinity.</li>
+ * <li>If the argument is negative infinity, the result is negative
+ * infinity.</li>
+ * <li>If the argument is zero, the result is zero with the same
+ * sign as the argument.</li>
+ * </ul>
+ *
+ * @param x the number to take the cube root of
+ * @return the cube root of <code>x</code>
+ * @see #sqrt(double)
+ *
+ * @since 1.5
+ */
+ public static double cbrt(double x)
+ {
+ boolean negative = (x < 0);
+ double r;
+ double s;
+ double t;
+ double w;
+
+ long bits;
+ long l;
+ long h;
+
+ // handle the special cases
+ if (x != x)
+ return x;
+ if (x == Double.POSITIVE_INFINITY)
+ return Double.POSITIVE_INFINITY;
+ if (x == Double.NEGATIVE_INFINITY)
+ return Double.NEGATIVE_INFINITY;
+ if (x == 0)
+ return x;
+
+ x = abs(x);
+ bits = Double.doubleToLongBits(x);
+
+ if (bits < 0x0010000000000000L) // subnormal number
+ {
+ t = TWO_54;
+ t *= x;
+
+ // __HI(t)=__HI(t)/3+B2;
+ bits = Double.doubleToLongBits(t);
+ h = getHighDWord(bits);
+ l = getLowDWord(bits);
+
+ h = h / 3 + CBRT_B2;
+
+ t = buildDouble(l, h);
+ }
+ else
+ {
+ // __HI(t)=__HI(x)/3+B1;
+ h = getHighDWord(bits);
+ l = 0;
+
+ h = h / 3 + CBRT_B1;
+ t = buildDouble(l, h);
+ }
+
+ // new cbrt to 23 bits
+ r = t * t / x;
+ s = CBRT_C + r * t;
+ t *= CBRT_G + CBRT_F / (s + CBRT_E + CBRT_D / s);
+
+ // chopped to 20 bits and make it larger than cbrt(x)
+ bits = Double.doubleToLongBits(t);
+ h = getHighDWord(bits);
+
+ // __LO(t)=0;
+ // __HI(t)+=0x00000001;
+ l = 0;
+ h += 1;
+ t = buildDouble(l, h);
+
+ // one step newton iteration to 53 bits with error less than 0.667 ulps
+ s = t * t; // t * t is exact
+ r = x / s;
+ w = t + t;
+ r = (r - t) / (w + r); // r - t is exact
+ t = t + t * r;
+
+ return negative ? -t : t;
+ }
+
+ /**
* Take <em>e</em><sup>a</sup>. The opposite of <code>log()</code>. If the
* argument is NaN, the result is NaN; if the argument is positive infinity,
* the result is positive infinity; and if the argument is negative
@@ -694,6 +1069,254 @@
}
/**
+ * Returns <em>e</em><sup>x</sup> - 1.
+ * Special cases:
+ * <ul>
+ * <li>If the argument is NaN, the result is NaN.</li>
+ * <li>If the argument is positive infinity, the result is positive
+ * infinity</li>
+ * <li>If the argument is negative infinity, the result is -1.</li>
+ * <li>If the argument is zero, the result is zero.</li>
+ * </ul>
+ *
+ * @param x the argument to <em>e</em><sup>x</sup> - 1.
+ * @return <em>e</em> raised to the power <code>x</code> minus one.
+ * @see #exp(double)
+ */
+ public static double expm1(double x)
+ {
+ // Method
+ // 1. Argument reduction:
+ // Given x, find r and integer k such that
+ //
+ // x = k * ln(2) + r, |r| <= 0.5 * ln(2)
+ //
+ // Here a correction term c will be computed to compensate
+ // the error in r when rounded to a floating-point number.
+ //
+ // 2. Approximating expm1(r) by a special rational function on
+ // the interval [0, 0.5 * ln(2)]:
+ // Since
+ // r*(exp(r)+1)/(exp(r)-1) = 2 + r^2/6 - r^4/360 + ...
+ // we define R1(r*r) by
+ // r*(exp(r)+1)/(exp(r)-1) = 2 + r^2/6 * R1(r*r)
+ // That is,
+ // R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
+ // = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
+ // = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
+ // We use a special Remes algorithm on [0, 0.347] to generate
+ // a polynomial of degree 5 in r*r to approximate R1. The
+ // maximum error of this polynomial approximation is bounded
+ // by 2**-61. In other words,
+ // R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
+ // where Q1 = -1.6666666666666567384E-2,
+ // Q2 = 3.9682539681370365873E-4,
+ // Q3 = -9.9206344733435987357E-6,
+ // Q4 = 2.5051361420808517002E-7,
+ // Q5 = -6.2843505682382617102E-9;
+ // (where z=r*r, and Q1 to Q5 are called EXPM1_Qx in the source)
+ // with error bounded by
+ // | 5 | -61
+ // | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2
+ // | |
+ //
+ // expm1(r) = exp(r)-1 is then computed by the following
+ // specific way which minimize the accumulation rounding error:
+ // 2 3
+ // r r [ 3 - (R1 + R1*r/2) ]
+ // expm1(r) = r + --- + --- * [--------------------]
+ // 2 2 [ 6 - r*(3 - R1*r/2) ]
+ //
+ // To compensate the error in the argument reduction, we use
+ // expm1(r+c) = expm1(r) + c + expm1(r)*c
+ // ~ expm1(r) + c ...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-28 20:52:04
|
Revision: 3096
http://jnode.svn.sourceforge.net/jnode/?rev=3096&view=rev
Author: lsantha
Date: 2007-01-28 12:52:02 -0800 (Sun, 28 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/lang/reflect/Array.java
Added Paths:
-----------
trunk/core/src/classpath/vm/java/lang/reflect/VMArray.java
Modified: trunk/core/src/classpath/java/java/lang/reflect/Array.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/reflect/Array.java 2007-01-27 21:52:45 UTC (rev 3095)
+++ trunk/core/src/classpath/java/java/lang/reflect/Array.java 2007-01-28 20:52:02 UTC (rev 3096)
@@ -35,19 +35,9 @@
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
+
package java.lang.reflect;
-import org.jnode.vm.Vm;
-import org.jnode.vm.memmgr.VmHeapManager;
-import org.jnode.vm.classmgr.VmType;
-import org.jnode.vm.classmgr.VmClassLoader;
-import org.jnode.vm.classmgr.VmArrayClass;
-
-import gnu.java.security.action.InvokeAction;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
/**
* Array holds static helper functions that allow you to create and
* manipulate arrays by reflection. Operations know how to perform widening
@@ -105,10 +95,10 @@
* @throws NegativeArraySizeException when length is less than 0
* @throws OutOfMemoryError if memory allocation fails
*/
- public static Object newInstance(Class componentType, int length)
+ public static Object newInstance(Class<?> componentType, int length)
{
- if (!componentType.isPrimitive())
- return createObjectArray(componentType, length);
+ if (! componentType.isPrimitive())
+ return VMArray.createObjectArray(componentType, length);
if (componentType == boolean.class)
return new boolean[length];
if (componentType == byte.class)
@@ -153,10 +143,10 @@
* than 0
* @throws OutOfMemoryError if memory allocation fails
*/
- public static Object newInstance(Class componentType, int[] dimensions)
+ public static Object newInstance(Class<?> componentType, int[] dimensions)
{
if (dimensions.length <= 0)
- throw new IllegalArgumentException("Empty dimensions array.");
+ throw new IllegalArgumentException ("Empty dimensions array.");
return createMultiArray(componentType, dimensions,
dimensions.length - 1);
}
@@ -175,7 +165,7 @@
if (array instanceof boolean[])
return ((boolean[]) array).length;
if (array instanceof byte[])
- return ((byte[]) array).length;
+ return ((byte[]) array). length;
if (array instanceof char[])
return ((char[]) array).length;
if (array instanceof short[])
@@ -654,7 +644,7 @@
Object toAdd = createMultiArray(type, dimensions, index - 1);
Class thisType = toAdd.getClass();
Object[] retval
- = (Object[]) createObjectArray(thisType, dimensions[index]);
+ = (Object[]) VMArray.createObjectArray(thisType, dimensions[index]);
if (dimensions[index] > 0)
retval[0] = toAdd;
int i = dimensions[index];
@@ -663,49 +653,4 @@
return retval;
}
-
- // LS
- // @classpath-bugfix-22923 should be placed in VMArray
- /**
- * Dynamically create an array of objects.
- *
- * @param type guaranteed to be a valid object type
- * @param dim the length of the array
- * @return the new array
- * @throws NegativeArraySizeException if dim is negative
- * @throws OutOfMemoryError if memory allocation fails
- */
- private static Object createObjectArray(final Class type, int dim) {
- final VmType vmClass = (VmType) AccessController.doPrivileged(
- new PrivilegedAction() {
- public Object run() {
- return type.getVmClass();
- }
- });
-
- final String arrClsName = vmClass.getArrayClassName();
- final VmType arrCls;
- try {
- final VmClassLoader curLoader = vmClass.getLoader();
- arrCls = curLoader.loadClass(arrClsName, true);
- //Screen.debug("an cls{");
- //Screen.debug(vmClass.getName());
- if (arrCls == null) {
- throw new NoClassDefFoundError(arrClsName);
- }
- } catch (ClassNotFoundException ex) {
- throw new NoClassDefFoundError(arrClsName);
- }
-
- VmHeapManager hm = heapManager;
- if (hm == null) {
- heapManager = hm = Vm.getVm().getHeapManager();
- }
- final Object result = hm.newArray((VmArrayClass) arrCls, dim);
-
- //Screen.debug("}");
- return result;
- }
- private static VmHeapManager heapManager;
- // @classpath-bugfix-end
}
Added: trunk/core/src/classpath/vm/java/lang/reflect/VMArray.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/reflect/VMArray.java (rev 0)
+++ trunk/core/src/classpath/vm/java/lang/reflect/VMArray.java 2007-01-28 20:52:02 UTC (rev 3096)
@@ -0,0 +1,91 @@
+/* java.lang.reflect.VMArray - VM class for array manipulation by reflection.
+ Copyright (C) 1998, 1999, 2001, 2003, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.classpath.Configuration;
+import org.jnode.vm.classmgr.VmType;
+import org.jnode.vm.classmgr.VmClassLoader;
+import org.jnode.vm.classmgr.VmArrayClass;
+import org.jnode.vm.Vm;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+class VMArray
+{
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javalangreflect");
+ }
+ }
+
+ /**
+ * Dynamically create an array of objects.
+ *
+ * @param type guaranteed to be a valid object type
+ * @param dim the length of the array
+ * @return the new array
+ * @throws NegativeArraySizeException if dim is negative
+ * @throws OutOfMemoryError if memory allocation fails
+ */
+ static Object createObjectArray(final Class type, int dim) {
+ final VmType vmClass = AccessController.doPrivileged(
+ new PrivilegedAction<VmType>() {
+ public VmType run() {
+ return type.getVmClass();
+ }
+ });
+
+ final String arrClsName = vmClass.getArrayClassName();
+ final VmType arrCls;
+ try {
+ final VmClassLoader curLoader = vmClass.getLoader();
+ arrCls = curLoader.loadClass(arrClsName, true);
+ if (arrCls == null) {
+ throw new NoClassDefFoundError(arrClsName);
+ }
+ } catch (ClassNotFoundException ex) {
+ throw new NoClassDefFoundError(arrClsName);
+ }
+
+ return Vm.getHeapManager().newArray((VmArrayClass) arrCls, dim);
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|