summaryrefslogtreecommitdiff
path: root/libjava/java/lang
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/lang')
-rw-r--r--libjava/java/lang/AbstractMethodError.h23
-rw-r--r--libjava/java/lang/AbstractStringBuffer.h85
-rw-r--r--libjava/java/lang/AbstractStringBuffer.java1027
-rw-r--r--libjava/java/lang/Appendable.h21
-rw-r--r--libjava/java/lang/ArithmeticException.h23
-rw-r--r--libjava/java/lang/ArrayIndexOutOfBoundsException.h24
-rw-r--r--libjava/java/lang/ArrayStoreException.h23
-rw-r--r--libjava/java/lang/AssertionError.h29
-rw-r--r--libjava/java/lang/Boolean.h40
-rw-r--r--libjava/java/lang/Byte.h51
-rw-r--r--libjava/java/lang/CharSequence.h22
-rw-r--r--libjava/java/lang/Character$Subset.h26
-rw-r--r--libjava/java/lang/Character$UnicodeBlock$NameType.h29
-rw-r--r--libjava/java/lang/Character$UnicodeBlock.h161
-rw-r--r--libjava/java/lang/Character.h179
-rw-r--r--libjava/java/lang/Character.java4051
-rw-r--r--libjava/java/lang/Class$1.h24
-rw-r--r--libjava/java/lang/Class.h758
-rw-r--r--libjava/java/lang/Class.java1430
-rw-r--r--libjava/java/lang/ClassCastException.h23
-rw-r--r--libjava/java/lang/ClassCircularityError.h23
-rw-r--r--libjava/java/lang/ClassFormatError.h23
-rw-r--r--libjava/java/lang/ClassLoader$AnnotationsKey.h31
-rw-r--r--libjava/java/lang/ClassLoader.h112
-rw-r--r--libjava/java/lang/ClassLoader.java1144
-rw-r--r--libjava/java/lang/ClassNotFoundException.h27
-rw-r--r--libjava/java/lang/CloneNotSupportedException.h23
-rw-r--r--libjava/java/lang/Cloneable.h18
-rw-r--r--libjava/java/lang/Comparable.h19
-rw-r--r--libjava/java/lang/Compiler.h24
-rw-r--r--libjava/java/lang/Deprecated.h19
-rw-r--r--libjava/java/lang/Double.h59
-rw-r--r--libjava/java/lang/EcosProcess.h27
-rw-r--r--libjava/java/lang/EcosProcess.java60
-rw-r--r--libjava/java/lang/Enum.h41
-rw-r--r--libjava/java/lang/EnumConstantNotPresentException.h26
-rw-r--r--libjava/java/lang/Error.h25
-rw-r--r--libjava/java/lang/Exception.h25
-rw-r--r--libjava/java/lang/ExceptionInInitializerError.h28
-rw-r--r--libjava/java/lang/Float.h60
-rw-r--r--libjava/java/lang/IllegalAccessError.h23
-rw-r--r--libjava/java/lang/IllegalAccessException.h23
-rw-r--r--libjava/java/lang/IllegalArgumentException.h25
-rw-r--r--libjava/java/lang/IllegalMonitorStateException.h23
-rw-r--r--libjava/java/lang/IllegalStateException.h25
-rw-r--r--libjava/java/lang/IllegalThreadStateException.h23
-rw-r--r--libjava/java/lang/IncompatibleClassChangeError.h23
-rw-r--r--libjava/java/lang/IndexOutOfBoundsException.h23
-rw-r--r--libjava/java/lang/InheritableThreadLocal.h24
-rw-r--r--libjava/java/lang/InstantiationError.h23
-rw-r--r--libjava/java/lang/InstantiationException.h23
-rw-r--r--libjava/java/lang/Integer.h77
-rw-r--r--libjava/java/lang/InternalError.h23
-rw-r--r--libjava/java/lang/InterruptedException.h23
-rw-r--r--libjava/java/lang/Iterable.h19
-rw-r--r--libjava/java/lang/LinkageError.h23
-rw-r--r--libjava/java/lang/Long.h77
-rw-r--r--libjava/java/lang/Math.h68
-rw-r--r--libjava/java/lang/Math.java973
-rw-r--r--libjava/java/lang/NegativeArraySizeException.h23
-rw-r--r--libjava/java/lang/NoClassDefFoundError.h23
-rw-r--r--libjava/java/lang/NoSuchFieldError.h23
-rw-r--r--libjava/java/lang/NoSuchFieldException.h23
-rw-r--r--libjava/java/lang/NoSuchMethodError.h23
-rw-r--r--libjava/java/lang/NoSuchMethodException.h23
-rw-r--r--libjava/java/lang/NullPointerException.h23
-rw-r--r--libjava/java/lang/Number.h32
-rw-r--r--libjava/java/lang/NumberFormatException.h23
-rw-r--r--libjava/java/lang/Object.h91
-rw-r--r--libjava/java/lang/Object.java519
-rw-r--r--libjava/java/lang/OutOfMemoryError.h23
-rw-r--r--libjava/java/lang/Override.h19
-rw-r--r--libjava/java/lang/Package.h62
-rw-r--r--libjava/java/lang/PosixProcess$EOFInputStream.h24
-rw-r--r--libjava/java/lang/PosixProcess$ProcessManager.h45
-rw-r--r--libjava/java/lang/PosixProcess.h62
-rw-r--r--libjava/java/lang/PosixProcess.java470
-rw-r--r--libjava/java/lang/Process.h25
-rw-r--r--libjava/java/lang/ProcessBuilder.h37
-rw-r--r--libjava/java/lang/Readable.h29
-rw-r--r--libjava/java/lang/Runnable.h19
-rw-r--r--libjava/java/lang/Runtime.h69
-rw-r--r--libjava/java/lang/Runtime.java747
-rw-r--r--libjava/java/lang/RuntimeException.h25
-rw-r--r--libjava/java/lang/RuntimePermission.h23
-rw-r--r--libjava/java/lang/SecurityException.h25
-rw-r--r--libjava/java/lang/SecurityManager$1.h26
-rw-r--r--libjava/java/lang/SecurityManager.h84
-rw-r--r--libjava/java/lang/Short.h54
-rw-r--r--libjava/java/lang/StackOverflowError.h23
-rw-r--r--libjava/java/lang/StackTraceElement.h39
-rw-r--r--libjava/java/lang/StrictMath.h203
-rw-r--r--libjava/java/lang/String$CaseInsensitiveComparator.h25
-rw-r--r--libjava/java/lang/String.h148
-rw-r--r--libjava/java/lang/String.java1457
-rw-r--r--libjava/java/lang/StringBuffer.h115
-rw-r--r--libjava/java/lang/StringBuffer.java976
-rw-r--r--libjava/java/lang/StringBuilder.h96
-rw-r--r--libjava/java/lang/StringBuilder.java706
-rw-r--r--libjava/java/lang/StringIndexOutOfBoundsException.h24
-rw-r--r--libjava/java/lang/SuppressWarnings.h22
-rw-r--r--libjava/java/lang/System$EnvironmentCollection.h29
-rw-r--r--libjava/java/lang/System$EnvironmentMap.h37
-rw-r--r--libjava/java/lang/System$EnvironmentSet.h21
-rw-r--r--libjava/java/lang/System.h70
-rw-r--r--libjava/java/lang/System.java1089
-rw-r--r--libjava/java/lang/Thread$State.h32
-rw-r--r--libjava/java/lang/Thread$UncaughtExceptionHandler.h19
-rw-r--r--libjava/java/lang/Thread.h157
-rw-r--r--libjava/java/lang/Thread.java1358
-rw-r--r--libjava/java/lang/ThreadDeath.h22
-rw-r--r--libjava/java/lang/ThreadGroup.h69
-rw-r--r--libjava/java/lang/ThreadLocal.h57
-rw-r--r--libjava/java/lang/ThreadLocal.java198
-rw-r--r--libjava/java/lang/ThreadLocalMap$Entry.h21
-rw-r--r--libjava/java/lang/ThreadLocalMap.h41
-rw-r--r--libjava/java/lang/Throwable$StaticData.h21
-rw-r--r--libjava/java/lang/Throwable.h59
-rw-r--r--libjava/java/lang/TypeNotPresentException.h24
-rw-r--r--libjava/java/lang/UnknownError.h23
-rw-r--r--libjava/java/lang/UnsatisfiedLinkError.h23
-rw-r--r--libjava/java/lang/UnsupportedClassVersionError.h23
-rw-r--r--libjava/java/lang/UnsupportedOperationException.h25
-rw-r--r--libjava/java/lang/VMClassLoader.h74
-rw-r--r--libjava/java/lang/VMClassLoader.java348
-rw-r--r--libjava/java/lang/VMCompiler.h64
-rw-r--r--libjava/java/lang/VMCompiler.java369
-rw-r--r--libjava/java/lang/VMDouble.h25
-rw-r--r--libjava/java/lang/VMDouble.java111
-rw-r--r--libjava/java/lang/VMFloat.h25
-rw-r--r--libjava/java/lang/VMFloat.java121
-rw-r--r--libjava/java/lang/VMProcess.h24
-rw-r--r--libjava/java/lang/VMProcess.java68
-rw-r--r--libjava/java/lang/VMThrowable.h36
-rw-r--r--libjava/java/lang/VMThrowable.java82
-rw-r--r--libjava/java/lang/VerifyError.h23
-rw-r--r--libjava/java/lang/VirtualMachineError.h23
-rw-r--r--libjava/java/lang/Void.h20
-rw-r--r--libjava/java/lang/Win32Process$EOFInputStream.h23
-rw-r--r--libjava/java/lang/Win32Process.h37
-rw-r--r--libjava/java/lang/Win32Process.java97
-rw-r--r--libjava/java/lang/annotation/Annotation.h22
-rw-r--r--libjava/java/lang/annotation/AnnotationFormatError.h24
-rw-r--r--libjava/java/lang/annotation/AnnotationTypeMismatchException.h26
-rw-r--r--libjava/java/lang/annotation/Documented.h19
-rw-r--r--libjava/java/lang/annotation/ElementType.h35
-rw-r--r--libjava/java/lang/annotation/IncompleteAnnotationException.h25
-rw-r--r--libjava/java/lang/annotation/Inherited.h19
-rw-r--r--libjava/java/lang/annotation/Retention.h20
-rw-r--r--libjava/java/lang/annotation/RetentionPolicy.h30
-rw-r--r--libjava/java/lang/annotation/Target.h22
-rw-r--r--libjava/java/lang/instrument/ClassDefinition.h27
-rw-r--r--libjava/java/lang/instrument/ClassFileTransformer.h31
-rw-r--r--libjava/java/lang/instrument/IllegalClassFormatException.h23
-rw-r--r--libjava/java/lang/instrument/Instrumentation.h27
-rw-r--r--libjava/java/lang/instrument/UnmodifiableClassException.h23
-rw-r--r--libjava/java/lang/management/ClassLoadingMXBean.h23
-rw-r--r--libjava/java/lang/management/CompilationMXBean.h21
-rw-r--r--libjava/java/lang/management/GarbageCollectorMXBean.h25
-rw-r--r--libjava/java/lang/management/LockInfo.h26
-rw-r--r--libjava/java/lang/management/ManagementFactory$ManagementInvocationHandler.h38
-rw-r--r--libjava/java/lang/management/ManagementFactory.h59
-rw-r--r--libjava/java/lang/management/ManagementPermission.h23
-rw-r--r--libjava/java/lang/management/MemoryMXBean.h24
-rw-r--r--libjava/java/lang/management/MemoryManagerMXBean.h23
-rw-r--r--libjava/java/lang/management/MemoryNotificationInfo.h43
-rw-r--r--libjava/java/lang/management/MemoryPoolMXBean.h38
-rw-r--r--libjava/java/lang/management/MemoryType.h28
-rw-r--r--libjava/java/lang/management/MemoryUsage.h44
-rw-r--r--libjava/java/lang/management/MonitorInfo.h39
-rw-r--r--libjava/java/lang/management/OperatingSystemMXBean.h23
-rw-r--r--libjava/java/lang/management/RuntimeMXBean.h34
-rw-r--r--libjava/java/lang/management/ThreadInfo.h77
-rw-r--r--libjava/java/lang/management/ThreadMXBean.h47
-rw-r--r--libjava/java/lang/management/VMManagementFactory.h25
-rw-r--r--libjava/java/lang/management/VMManagementFactory.java87
-rw-r--r--libjava/java/lang/natAbstractStringBuffer.cc41
-rw-r--r--libjava/java/lang/natCharacter.cc235
-rw-r--r--libjava/java/lang/natClass.cc2089
-rw-r--r--libjava/java/lang/natClassLoader.cc734
-rw-r--r--libjava/java/lang/natEcosProcess.cc25
-rw-r--r--libjava/java/lang/natMath.cc184
-rw-r--r--libjava/java/lang/natObject.cc1457
-rw-r--r--libjava/java/lang/natPosixProcess.cc515
-rw-r--r--libjava/java/lang/natRuntime.cc323
-rw-r--r--libjava/java/lang/natString.cc1068
-rw-r--r--libjava/java/lang/natSystem.cc150
-rw-r--r--libjava/java/lang/natThread.cc534
-rw-r--r--libjava/java/lang/natThreadLocal.cc169
-rw-r--r--libjava/java/lang/natVMClassLoader.cc245
-rw-r--r--libjava/java/lang/natVMDouble.cc215
-rw-r--r--libjava/java/lang/natVMFloat.cc52
-rw-r--r--libjava/java/lang/natVMProcess.cc33
-rw-r--r--libjava/java/lang/natVMThrowable.cc45
-rw-r--r--libjava/java/lang/natWin32Process.cc360
-rw-r--r--libjava/java/lang/ref/PhantomReference.h20
-rw-r--r--libjava/java/lang/ref/Reference.h45
-rw-r--r--libjava/java/lang/ref/Reference.java204
-rw-r--r--libjava/java/lang/ref/ReferenceQueue.h31
-rw-r--r--libjava/java/lang/ref/SoftReference.h21
-rw-r--r--libjava/java/lang/ref/WeakReference.h20
-rw-r--r--libjava/java/lang/ref/natReference.cc377
-rw-r--r--libjava/java/lang/reflect/AccessibleObject.h36
-rw-r--r--libjava/java/lang/reflect/AnnotatedElement.h24
-rw-r--r--libjava/java/lang/reflect/Array.h46
-rw-r--r--libjava/java/lang/reflect/Array.java458
-rw-r--r--libjava/java/lang/reflect/Constructor.h65
-rw-r--r--libjava/java/lang/reflect/Constructor.java424
-rw-r--r--libjava/java/lang/reflect/Field.h98
-rw-r--r--libjava/java/lang/reflect/Field.java817
-rw-r--r--libjava/java/lang/reflect/GenericArrayType.h19
-rw-r--r--libjava/java/lang/reflect/GenericDeclaration.h21
-rw-r--r--libjava/java/lang/reflect/GenericSignatureFormatError.h22
-rw-r--r--libjava/java/lang/reflect/InvocationHandler.h21
-rw-r--r--libjava/java/lang/reflect/InvocationTargetException.h28
-rw-r--r--libjava/java/lang/reflect/MalformedParameterizedTypeException.h22
-rw-r--r--libjava/java/lang/reflect/Member.h24
-rw-r--r--libjava/java/lang/reflect/Method.h84
-rw-r--r--libjava/java/lang/reflect/Method.java501
-rw-r--r--libjava/java/lang/reflect/Modifier.h58
-rw-r--r--libjava/java/lang/reflect/Modifier.java375
-rw-r--r--libjava/java/lang/reflect/ParameterizedType.h23
-rw-r--r--libjava/java/lang/reflect/Proxy$ClassFactory.h78
-rw-r--r--libjava/java/lang/reflect/Proxy$ProxyData.h37
-rw-r--r--libjava/java/lang/reflect/Proxy$ProxySignature.h28
-rw-r--r--libjava/java/lang/reflect/Proxy$ProxyType.h28
-rw-r--r--libjava/java/lang/reflect/Proxy.h32
-rw-r--r--libjava/java/lang/reflect/ReflectPermission.h23
-rw-r--r--libjava/java/lang/reflect/Type.h18
-rw-r--r--libjava/java/lang/reflect/TypeVariable.h23
-rw-r--r--libjava/java/lang/reflect/UndeclaredThrowableException.h26
-rw-r--r--libjava/java/lang/reflect/VMProxy.h28
-rw-r--r--libjava/java/lang/reflect/VMProxy.java140
-rw-r--r--libjava/java/lang/reflect/WildcardType.h22
-rw-r--r--libjava/java/lang/reflect/natArray.cc360
-rw-r--r--libjava/java/lang/reflect/natConstructor.cc93
-rw-r--r--libjava/java/lang/reflect/natField.cc449
-rw-r--r--libjava/java/lang/reflect/natMethod.cc701
-rw-r--r--libjava/java/lang/reflect/natVMProxy.cc459
239 files changed, 38943 insertions, 0 deletions
diff --git a/libjava/java/lang/AbstractMethodError.h b/libjava/java/lang/AbstractMethodError.h
new file mode 100644
index 000000000..92a757da2
--- /dev/null
+++ b/libjava/java/lang/AbstractMethodError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_AbstractMethodError__
+#define __java_lang_AbstractMethodError__
+
+#pragma interface
+
+#include <java/lang/IncompatibleClassChangeError.h>
+
+class java::lang::AbstractMethodError : public ::java::lang::IncompatibleClassChangeError
+{
+
+public:
+ AbstractMethodError();
+ AbstractMethodError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -1654391082989018462LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_AbstractMethodError__
diff --git a/libjava/java/lang/AbstractStringBuffer.h b/libjava/java/lang/AbstractStringBuffer.h
new file mode 100644
index 000000000..256004c24
--- /dev/null
+++ b/libjava/java/lang/AbstractStringBuffer.h
@@ -0,0 +1,85 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_AbstractStringBuffer__
+#define __java_lang_AbstractStringBuffer__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::AbstractStringBuffer : public ::java::lang::Object
+{
+
+public: // actually package-private
+ AbstractStringBuffer();
+ AbstractStringBuffer(jint);
+ AbstractStringBuffer(::java::lang::String *);
+ AbstractStringBuffer(::java::lang::CharSequence *);
+public:
+ virtual void ensureCapacity(jint);
+ virtual void setLength(jint);
+ virtual jchar charAt(jint);
+ virtual jint codePointAt(jint);
+ virtual jint codePointBefore(jint);
+ virtual void getChars(jint, jint, JArray< jchar > *, jint);
+ virtual void setCharAt(jint, jchar);
+ virtual ::java::lang::AbstractStringBuffer * append(::java::lang::Object *);
+ virtual ::java::lang::AbstractStringBuffer * append(::java::lang::String *);
+ virtual ::java::lang::AbstractStringBuffer * append(::java::lang::StringBuffer *);
+ virtual ::java::lang::AbstractStringBuffer * append(JArray< jchar > *);
+ virtual ::java::lang::AbstractStringBuffer * append(JArray< jchar > *, jint, jint);
+ virtual ::java::lang::AbstractStringBuffer * append(jboolean);
+ virtual ::java::lang::AbstractStringBuffer * AbstractStringBuffer$append(jchar);
+ virtual ::java::lang::AbstractStringBuffer * AbstractStringBuffer$append(::java::lang::CharSequence *);
+ virtual ::java::lang::AbstractStringBuffer * AbstractStringBuffer$append(::java::lang::CharSequence *, jint, jint);
+ virtual ::java::lang::AbstractStringBuffer * append(jint);
+ virtual ::java::lang::AbstractStringBuffer * append(jlong);
+ virtual ::java::lang::AbstractStringBuffer * append(jfloat);
+ virtual ::java::lang::AbstractStringBuffer * append(jdouble);
+ virtual ::java::lang::AbstractStringBuffer * appendCodePoint(jint);
+ virtual ::java::lang::AbstractStringBuffer * delete$(jint, jint);
+ virtual ::java::lang::AbstractStringBuffer * deleteCharAt(jint);
+ virtual ::java::lang::AbstractStringBuffer * replace(jint, jint, ::java::lang::String *);
+ virtual ::java::lang::AbstractStringBuffer * insert(jint, JArray< jchar > *, jint, jint);
+ virtual ::java::lang::AbstractStringBuffer * insert(jint, ::java::lang::Object *);
+ virtual ::java::lang::AbstractStringBuffer * insert(jint, ::java::lang::String *);
+ virtual ::java::lang::AbstractStringBuffer * insert(jint, ::java::lang::CharSequence *);
+ virtual ::java::lang::AbstractStringBuffer * insert(jint, ::java::lang::CharSequence *, jint, jint);
+ virtual ::java::lang::AbstractStringBuffer * insert(jint, JArray< jchar > *);
+ virtual ::java::lang::AbstractStringBuffer * insert(jint, jboolean);
+ virtual ::java::lang::AbstractStringBuffer * insert(jint, jchar);
+ virtual ::java::lang::AbstractStringBuffer * insert(jint, jint);
+ virtual ::java::lang::AbstractStringBuffer * insert(jint, jlong);
+ virtual ::java::lang::AbstractStringBuffer * insert(jint, jfloat);
+ virtual ::java::lang::AbstractStringBuffer * insert(jint, jdouble);
+ virtual jint indexOf(::java::lang::String *);
+ virtual jint indexOf(::java::lang::String *, jint);
+ virtual jint lastIndexOf(::java::lang::String *);
+ virtual jint lastIndexOf(::java::lang::String *, jint);
+ virtual ::java::lang::AbstractStringBuffer * reverse();
+ virtual void trimToSize();
+ virtual jint codePointCount(jint, jint);
+ virtual jint offsetByCodePoints(jint, jint);
+public: // actually package-private
+ virtual void ensureCapacity_unsynchronized(jint);
+private:
+ jboolean regionMatches(jint, ::java::lang::String *);
+public:
+ virtual ::java::lang::Appendable * append(::java::lang::CharSequence *, jint, jint);
+ virtual ::java::lang::Appendable * append(::java::lang::CharSequence *);
+ virtual ::java::lang::Appendable * append(jchar);
+ virtual jint length() = 0;
+ virtual ::java::lang::CharSequence * subSequence(jint, jint) = 0;
+public: // actually package-private
+ jint __attribute__((aligned(__alignof__( ::java::lang::Object)))) count;
+ JArray< jchar > * value;
+private:
+ static const jint DEFAULT_CAPACITY = 16;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_AbstractStringBuffer__
diff --git a/libjava/java/lang/AbstractStringBuffer.java b/libjava/java/lang/AbstractStringBuffer.java
new file mode 100644
index 000000000..fe128b8af
--- /dev/null
+++ b/libjava/java/lang/AbstractStringBuffer.java
@@ -0,0 +1,1027 @@
+/* AbstractStringBuffer.java -- Growable strings
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.io.Serializable;
+
+/**
+ * This class is based on gnu.classpath.ClasspathStringBuffer but
+ * is package-private to java.lang so it can be used as the basis
+ * for StringBuffer and StringBuilder.
+ * If you modify this, please consider also modifying that code.
+ */
+abstract class AbstractStringBuffer
+ implements Serializable, CharSequence, Appendable
+{
+
+ /**
+ * Index of next available character (and thus the size of the current
+ * string contents). Note that this has permissions set this way so that
+ * String can get the value.
+ *
+ * @serial the number of characters in the buffer
+ */
+ int count;
+
+ /**
+ * The buffer. Note that this has permissions set this way so that String
+ * can get the value.
+ *
+ * @serial the buffer
+ */
+ char[] value;
+
+ /**
+ * The default capacity of a buffer.
+ */
+ private static final int DEFAULT_CAPACITY = 16;
+
+ /**
+ * Create a new AbstractStringBuffer with default capacity 16.
+ */
+ AbstractStringBuffer()
+ {
+ this(DEFAULT_CAPACITY);
+ }
+
+ /**
+ * Create an empty <code>StringBuffer</code> with the specified initial
+ * capacity.
+ *
+ * @param capacity the initial capacity
+ * @throws NegativeArraySizeException if capacity is negative
+ */
+ AbstractStringBuffer(int capacity)
+ {
+ value = new char[capacity];
+ }
+
+ /**
+ * Create a new <code>StringBuffer</code> with the characters in the
+ * specified <code>String</code>. Initial capacity will be the size of the
+ * String plus 16.
+ *
+ * @param str the <code>String</code> to convert
+ * @throws NullPointerException if str is null
+ */
+ AbstractStringBuffer(String str)
+ {
+ count = str.count;
+ value = new char[count + DEFAULT_CAPACITY];
+ str.getChars(0, count, value, 0);
+ }
+
+ /**
+ * Create a new <code>StringBuffer</code> with the characters in the
+ * specified <code>CharSequence</code>. Initial capacity will be the
+ * length of the sequence plus 16; if the sequence reports a length
+ * less than or equal to 0, then the initial capacity will be 16.
+ *
+ * @param seq the initializing <code>CharSequence</code>
+ * @throws NullPointerException if str is null
+ * @since 1.5
+ */
+ AbstractStringBuffer(CharSequence seq)
+ {
+ int len = seq.length();
+ count = len <= 0 ? 0 : len;
+ value = new char[count + DEFAULT_CAPACITY];
+ for (int i = 0; i < len; ++i)
+ value[i] = seq.charAt(i);
+ }
+
+ /**
+ * Increase the capacity of this <code>StringBuffer</code>. This will
+ * ensure that an expensive growing operation will not occur until
+ * <code>minimumCapacity</code> is reached. The buffer is grown to the
+ * larger of <code>minimumCapacity</code> and
+ * <code>capacity() * 2 + 2</code>, if it is not already large enough.
+ *
+ * @param minimumCapacity the new capacity
+ * @see #capacity()
+ */
+ public void ensureCapacity(int minimumCapacity)
+ {
+ ensureCapacity_unsynchronized(minimumCapacity);
+ }
+
+ /**
+ * Set the length of this StringBuffer. If the new length is greater than
+ * the current length, all the new characters are set to '\0'. If the new
+ * length is less than the current length, the first <code>newLength</code>
+ * characters of the old array will be preserved, and the remaining
+ * characters are truncated.
+ *
+ * @param newLength the new length
+ * @throws IndexOutOfBoundsException if the new length is negative
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ * @see #length()
+ */
+ public void setLength(int newLength)
+ {
+ if (newLength < 0)
+ throw new StringIndexOutOfBoundsException(newLength);
+
+ int valueLength = value.length;
+
+ /* Always call ensureCapacity_unsynchronized in order to preserve
+ copy-on-write semantics. */
+ ensureCapacity_unsynchronized(newLength);
+
+ if (newLength < valueLength)
+ {
+ /* If the StringBuffer's value just grew, then we know that
+ value is newly allocated and the region between count and
+ newLength is filled with '\0'. */
+ count = newLength;
+ }
+ else
+ {
+ /* The StringBuffer's value doesn't need to grow. However,
+ we should clear out any cruft that may exist. */
+ while (count < newLength)
+ value[count++] = '\0';
+ }
+ }
+
+ /**
+ * Get the character at the specified index.
+ *
+ * @param index the index of the character to get, starting at 0
+ * @return the character at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public char charAt(int index)
+ {
+ if (index < 0 || index >= count)
+ throw new StringIndexOutOfBoundsException(index);
+ return value[index];
+ }
+
+ /**
+ * Get the code point at the specified index. This is like #charAt(int),
+ * but if the character is the start of a surrogate pair, and the
+ * following character completes the pair, then the corresponding
+ * supplementary code point is returned.
+ * @param index the index of the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public int codePointAt(int index)
+ {
+ return Character.codePointAt(value, index, count);
+ }
+
+ /**
+ * Get the code point before the specified index. This is like
+ * #codePointAt(int), but checks the characters at <code>index-1</code> and
+ * <code>index-2</code> to see if they form a supplementary code point.
+ * @param index the index just past the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public int codePointBefore(int index)
+ {
+ // Character.codePointBefore() doesn't perform this check. We
+ // could use the CharSequence overload, but this is just as easy.
+ if (index >= count)
+ throw new IndexOutOfBoundsException();
+ return Character.codePointBefore(value, index, 1);
+ }
+
+ /**
+ * Get the specified array of characters. <code>srcOffset - srcEnd</code>
+ * characters will be copied into the array you pass in.
+ *
+ * @param srcOffset the index to start copying from (inclusive)
+ * @param srcEnd the index to stop copying from (exclusive)
+ * @param dst the array to copy into
+ * @param dstOffset the index to start copying into
+ * @throws NullPointerException if dst is null
+ * @throws IndexOutOfBoundsException if any source or target indices are
+ * out of range (while unspecified, source problems cause a
+ * StringIndexOutOfBoundsException, and dest problems cause an
+ * ArrayIndexOutOfBoundsException)
+ * @see System#arraycopy(Object, int, Object, int, int)
+ */
+ public void getChars(int srcOffset, int srcEnd,
+ char[] dst, int dstOffset)
+ {
+ if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset)
+ throw new StringIndexOutOfBoundsException();
+ System.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset);
+ }
+
+ /**
+ * Set the character at the specified index.
+ *
+ * @param index the index of the character to set starting at 0
+ * @param ch the value to set that character to
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public void setCharAt(int index, char ch)
+ {
+ if (index < 0 || index >= count)
+ throw new StringIndexOutOfBoundsException(index);
+ // Call ensureCapacity to enforce copy-on-write.
+ ensureCapacity_unsynchronized(count);
+ value[index] = ch;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param obj the <code>Object</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(Object)
+ * @see #append(String)
+ */
+ public AbstractStringBuffer append(Object obj)
+ {
+ return append(String.valueOf(obj));
+ }
+
+ /**
+ * Append the <code>String</code> to this <code>StringBuffer</code>. If
+ * str is null, the String "null" is appended.
+ *
+ * @param str the <code>String</code> to append
+ * @return this <code>StringBuffer</code>
+ */
+ public AbstractStringBuffer append(String str)
+ {
+ if (str == null)
+ str = "null";
+ int len = str.count;
+ ensureCapacity_unsynchronized(count + len);
+ str.getChars(0, len, value, count);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Append the <code>StringBuilder</code> value of the argument to this
+ * <code>StringBuilder</code>. This behaves the same as
+ * <code>append((Object) stringBuffer)</code>, except it is more efficient.
+ *
+ * @param stringBuffer the <code>StringBuilder</code> to convert and append
+ * @return this <code>StringBuilder</code>
+ * @see #append(Object)
+ */
+ public AbstractStringBuffer append(StringBuffer stringBuffer)
+ {
+ if (stringBuffer == null)
+ return append("null");
+ synchronized (stringBuffer)
+ {
+ int len = stringBuffer.count;
+ ensureCapacity(count + len);
+ System.arraycopy(stringBuffer.value, 0, value, count, len);
+ count += len;
+ }
+ return this;
+ }
+
+ /**
+ * Append the <code>char</code> array to this <code>StringBuffer</code>.
+ * This is similar (but more efficient) than
+ * <code>append(new String(data))</code>, except in the case of null.
+ *
+ * @param data the <code>char[]</code> to append
+ * @return this <code>StringBuffer</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @see #append(char[], int, int)
+ */
+ public AbstractStringBuffer append(char[] data)
+ {
+ return append(data, 0, data.length);
+ }
+
+ /**
+ * Append part of the <code>char</code> array to this
+ * <code>StringBuffer</code>. This is similar (but more efficient) than
+ * <code>append(new String(data, offset, count))</code>, except in the case
+ * of null.
+ *
+ * @param data the <code>char[]</code> to append
+ * @param offset the start location in <code>str</code>
+ * @param count the number of characters to get from <code>str</code>
+ * @return this <code>StringBuffer</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @throws IndexOutOfBoundsException if offset or count is out of range
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public AbstractStringBuffer append(char[] data, int offset, int count)
+ {
+ if (offset < 0 || count < 0 || offset > data.length - count)
+ throw new StringIndexOutOfBoundsException();
+ ensureCapacity_unsynchronized(this.count + count);
+ System.arraycopy(data, offset, value, this.count, count);
+ this.count += count;
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param bool the <code>boolean</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(boolean)
+ */
+ public AbstractStringBuffer append(boolean bool)
+ {
+ return append(bool ? "true" : "false");
+ }
+
+ /**
+ * Append the <code>char</code> to this <code>StringBuffer</code>.
+ *
+ * @param ch the <code>char</code> to append
+ * @return this <code>StringBuffer</code>
+ */
+ public AbstractStringBuffer append(char ch)
+ {
+ ensureCapacity_unsynchronized(count + 1);
+ value[count++] = ch;
+ return this;
+ }
+
+ /**
+ * Append the characters in the <code>CharSequence</code> to this
+ * buffer.
+ *
+ * @param seq the <code>CharSequence</code> providing the characters
+ * @return this <code>StringBuffer</code>
+ * @since 1.5
+ */
+ public AbstractStringBuffer append(CharSequence seq)
+ {
+ return append(seq, 0, seq.length());
+ }
+
+ /**
+ * Append some characters from the <code>CharSequence</code> to this
+ * buffer. If the argument is null, the <code>seq</code> is assumed
+ * to be equal to the string <code>"null"</code>.
+ *
+ * @param seq the <code>CharSequence</code> providing the characters
+ * @param start the starting index
+ * @param end one past the final index
+ * @return this <code>StringBuffer</code>
+ * @since 1.5
+ */
+ public AbstractStringBuffer append(CharSequence seq, int start, int end)
+ {
+ if (seq == null)
+ seq = "null";
+ if (end - start > 0)
+ {
+ ensureCapacity_unsynchronized(count + end - start);
+ for (; start < end; ++start)
+ value[count++] = seq.charAt(start);
+ }
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param inum the <code>int</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(int)
+ */
+ // GCJ LOCAL: this is native for efficiency.
+ public native AbstractStringBuffer append (int inum);
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param lnum the <code>long</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(long)
+ */
+ public AbstractStringBuffer append(long lnum)
+ {
+ return append(Long.toString(lnum, 10));
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param fnum the <code>float</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(float)
+ */
+ public AbstractStringBuffer append(float fnum)
+ {
+ return append(Float.toString(fnum));
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param dnum the <code>double</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(double)
+ */
+ public AbstractStringBuffer append(double dnum)
+ {
+ return append(Double.toString(dnum));
+ }
+
+ /**
+ * Append the code point to this <code>StringBuffer</code>.
+ * This is like #append(char), but will append two characters
+ * if a supplementary code point is given.
+ *
+ * @param code the code point to append
+ * @return this <code>StringBuffer</code>
+ * @see Character#toChars(int, char[], int)
+ * @since 1.5
+ */
+ public AbstractStringBuffer appendCodePoint(int code)
+ {
+ int len = Character.charCount(code);
+ ensureCapacity_unsynchronized(count + len);
+ Character.toChars(code, value, count);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Delete characters from this <code>StringBuffer</code>.
+ * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
+ * harmless for end to be larger than length().
+ *
+ * @param start the first character to delete
+ * @param end the index after the last character to delete
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+ * @since 1.2
+ */
+ public AbstractStringBuffer delete(int start, int end)
+ {
+ if (start < 0 || start > count || start > end)
+ throw new StringIndexOutOfBoundsException(start);
+ if (end > count)
+ end = count;
+ ensureCapacity_unsynchronized(count);
+ if (count - end != 0)
+ System.arraycopy(value, end, value, start, count - end);
+ count -= end - start;
+ return this;
+ }
+
+ /**
+ * Delete a character from this <code>StringBuffer</code>.
+ *
+ * @param index the index of the character to delete
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if index is out of bounds
+ * @since 1.2
+ */
+ public AbstractStringBuffer deleteCharAt(int index)
+ {
+ return delete(index, index + 1);
+ }
+
+ /**
+ * Replace characters between index <code>start</code> (inclusive) and
+ * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
+ * is larger than the size of this StringBuffer, all characters after
+ * <code>start</code> are replaced.
+ *
+ * @param start the beginning index of characters to delete (inclusive)
+ * @param end the ending index of characters to delete (exclusive)
+ * @param str the new <code>String</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+ * @throws NullPointerException if str is null
+ * @since 1.2
+ */
+ public AbstractStringBuffer replace(int start, int end, String str)
+ {
+ if (start < 0 || start > count || start > end)
+ throw new StringIndexOutOfBoundsException(start);
+
+ int len = str.count;
+ // Calculate the difference in 'count' after the replace.
+ int delta = len - (end > count ? count : end) + start;
+ ensureCapacity_unsynchronized(count + delta);
+
+ if (delta != 0 && end < count)
+ System.arraycopy(value, end, value, end + delta, count - end);
+
+ str.getChars(0, len, value, start);
+ count += delta;
+ return this;
+ }
+
+ /**
+ * Insert a subarray of the <code>char[]</code> argument into this
+ * <code>StringBuffer</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param str the <code>char[]</code> to insert
+ * @param str_offset the index in <code>str</code> to start inserting from
+ * @param len the number of characters to insert
+ * @return this <code>StringBuffer</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @throws StringIndexOutOfBoundsException if any index is out of bounds
+ * @since 1.2
+ */
+ public AbstractStringBuffer insert(int offset, char[] str, int str_offset, int len)
+ {
+ if (offset < 0 || offset > count || len < 0
+ || str_offset < 0 || str_offset > str.length - len)
+ throw new StringIndexOutOfBoundsException();
+ ensureCapacity_unsynchronized(count + len);
+ System.arraycopy(value, offset, value, offset + len, count - offset);
+ System.arraycopy(str, str_offset, value, offset, len);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param obj the <code>Object</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @exception StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(Object)
+ */
+ public AbstractStringBuffer insert(int offset, Object obj)
+ {
+ return insert(offset, obj == null ? "null" : obj.toString());
+ }
+
+ /**
+ * Insert the <code>String</code> argument into this
+ * <code>StringBuffer</code>. If str is null, the String "null" is used
+ * instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param str the <code>String</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ */
+ public AbstractStringBuffer insert(int offset, String str)
+ {
+ if (offset < 0 || offset > count)
+ throw new StringIndexOutOfBoundsException(offset);
+ if (str == null)
+ str = "null";
+ int len = str.count;
+ ensureCapacity_unsynchronized(count + len);
+ System.arraycopy(value, offset, value, offset + len, count - offset);
+ str.getChars(0, len, value, offset);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Insert the <code>CharSequence</code> argument into this
+ * <code>StringBuffer</code>. If the sequence is null, the String
+ * "null" is used instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param sequence the <code>CharSequence</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws IndexOutOfBoundsException if offset is out of bounds
+ * @since 1.5
+ */
+ public AbstractStringBuffer insert(int offset, CharSequence sequence)
+ {
+ if (sequence == null)
+ sequence = "null";
+ return insert(offset, sequence, 0, sequence.length());
+ }
+
+ /**
+ * Insert a subsequence of the <code>CharSequence</code> argument into this
+ * <code>StringBuffer</code>. If the sequence is null, the String
+ * "null" is used instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param sequence the <code>CharSequence</code> to insert
+ * @param start the starting index of the subsequence
+ * @param end one past the ending index of the subsequence
+ * @return this <code>StringBuffer</code>
+ * @throws IndexOutOfBoundsException if offset, start,
+ * or end are out of bounds
+ * @since 1.5
+ */
+ public AbstractStringBuffer insert(int offset, CharSequence sequence, int start, int end)
+ {
+ if (sequence == null)
+ sequence = "null";
+ if (start < 0 || end < 0 || start > end || end > sequence.length())
+ throw new IndexOutOfBoundsException();
+ int len = end - start;
+ ensureCapacity_unsynchronized(count + len);
+ System.arraycopy(value, offset, value, offset + len, count - offset);
+ for (int i = start; i < end; ++i)
+ value[offset++] = sequence.charAt(i);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Insert the <code>char[]</code> argument into this
+ * <code>StringBuffer</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param data the <code>char[]</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws NullPointerException if <code>data</code> is <code>null</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see #insert(int, char[], int, int)
+ */
+ public AbstractStringBuffer insert(int offset, char[] data)
+ {
+ return insert(offset, data, 0, data.length);
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param bool the <code>boolean</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(boolean)
+ */
+ public AbstractStringBuffer insert(int offset, boolean bool)
+ {
+ return insert(offset, bool ? "true" : "false");
+ }
+
+ /**
+ * Insert the <code>char</code> argument into this <code>StringBuffer</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param ch the <code>char</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ */
+ public AbstractStringBuffer insert(int offset, char ch)
+ {
+ if (offset < 0 || offset > count)
+ throw new StringIndexOutOfBoundsException(offset);
+ ensureCapacity_unsynchronized(count + 1);
+ System.arraycopy(value, offset, value, offset + 1, count - offset);
+ value[offset] = ch;
+ count++;
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param inum the <code>int</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(int)
+ */
+ public AbstractStringBuffer insert(int offset, int inum)
+ {
+ return insert(offset, String.valueOf(inum));
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param lnum the <code>long</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(long)
+ */
+ public AbstractStringBuffer insert(int offset, long lnum)
+ {
+ return insert(offset, Long.toString(lnum, 10));
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param fnum the <code>float</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(float)
+ */
+ public AbstractStringBuffer insert(int offset, float fnum)
+ {
+ return insert(offset, Float.toString(fnum));
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param dnum the <code>double</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(double)
+ */
+ public AbstractStringBuffer insert(int offset, double dnum)
+ {
+ return insert(offset, Double.toString(dnum));
+ }
+
+ /**
+ * Finds the first instance of a substring in this StringBuilder.
+ *
+ * @param str String to find
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @see #indexOf(String, int)
+ */
+ public int indexOf(String str)
+ {
+ return indexOf(str, 0);
+ }
+
+ /**
+ * Finds the first instance of a String in this StringBuffer, starting at
+ * a given index. If starting index is less than 0, the search starts at
+ * the beginning of this String. If the starting index is greater than the
+ * length of this String, or the substring is not found, -1 is returned.
+ *
+ * @param str String to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @since 1.4
+ */
+ public int indexOf(String str, int fromIndex)
+ {
+ if (fromIndex < 0)
+ fromIndex = 0;
+ int limit = count - str.count;
+ for ( ; fromIndex <= limit; fromIndex++)
+ if (regionMatches(fromIndex, str))
+ return fromIndex;
+ return -1;
+ }
+
+ /**
+ * Finds the last instance of a substring in this StringBuffer.
+ *
+ * @param str String to find
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @see #lastIndexOf(String, int)
+ * @since 1.4
+ */
+ public int lastIndexOf(String str)
+ {
+ return lastIndexOf(str, count - str.count);
+ }
+
+ /**
+ * Finds the last instance of a String in this StringBuffer, starting at a
+ * given index. If starting index is greater than the maximum valid index,
+ * then the search begins at the end of this String. If the starting index
+ * is less than zero, or the substring is not found, -1 is returned.
+ *
+ * @param str String to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @since 1.4
+ */
+ public int lastIndexOf(String str, int fromIndex)
+ {
+ fromIndex = Math.min(fromIndex, count - str.count);
+ for ( ; fromIndex >= 0; fromIndex--)
+ if (regionMatches(fromIndex, str))
+ return fromIndex;
+ return -1;
+ }
+
+ /**
+ * Reverse the characters in this StringBuffer. The same sequence of
+ * characters exists, but in the reverse index ordering.
+ *
+ * @return this <code>StringBuffer</code>
+ */
+ public AbstractStringBuffer reverse()
+ {
+ // Call ensureCapacity to enforce copy-on-write.
+ ensureCapacity_unsynchronized(count);
+ for (int i = count >> 1, j = count - i; --i >= 0; ++j)
+ {
+ char c = value[i];
+ value[i] = value[j];
+ value[j] = c;
+ }
+ return this;
+ }
+
+ /**
+ * This may reduce the amount of memory used by the StringBuffer,
+ * by resizing the internal array to remove unused space. However,
+ * this method is not required to resize, so this behavior cannot
+ * be relied upon.
+ * @since 1.5
+ */
+ public void trimToSize()
+ {
+ int wouldSave = value.length - count;
+ // Some random heuristics: if we save less than 20 characters, who
+ // cares.
+ if (wouldSave < 20)
+ return;
+ // If we save more than 200 characters, shrink.
+ // If we save more than 1/4 of the buffer, shrink.
+ if (wouldSave > 200 || wouldSave * 4 > value.length)
+ {
+ char[] newValue = new char[count];
+ System.arraycopy(value, 0, newValue, 0, count);
+ value = newValue;
+ }
+ }
+
+ /**
+ * Return the number of code points between two indices in the
+ * <code>StringBuffer</code>. An unpaired surrogate counts as a
+ * code point for this purpose. Characters outside the indicated
+ * range are not examined, even if the range ends in the middle of a
+ * surrogate pair.
+ *
+ * @param start the starting index
+ * @param end one past the ending index
+ * @return the number of code points
+ * @since 1.5
+ */
+ public int codePointCount(int start, int end)
+ {
+ if (start < 0 || end >= count || start > end)
+ throw new StringIndexOutOfBoundsException();
+
+ int count = 0;
+ while (start < end)
+ {
+ char base = value[start];
+ if (base < Character.MIN_HIGH_SURROGATE
+ || base > Character.MAX_HIGH_SURROGATE
+ || start == end
+ || start == count
+ || value[start + 1] < Character.MIN_LOW_SURROGATE
+ || value[start + 1] > Character.MAX_LOW_SURROGATE)
+ {
+ // Nothing.
+ }
+ else
+ {
+ // Surrogate pair.
+ ++start;
+ }
+ ++start;
+ ++count;
+ }
+ return count;
+ }
+
+ /**
+ * Starting at the given index, this counts forward by the indicated
+ * number of code points, and then returns the resulting index. An
+ * unpaired surrogate counts as a single code point for this
+ * purpose.
+ *
+ * @param start the starting index
+ * @param codePoints the number of code points
+ * @return the resulting index
+ * @since 1.5
+ */
+ public int offsetByCodePoints(int start, int codePoints)
+ {
+ while (codePoints > 0)
+ {
+ char base = value[start];
+ if (base < Character.MIN_HIGH_SURROGATE
+ || base > Character.MAX_HIGH_SURROGATE
+ || start == count
+ || value[start + 1] < Character.MIN_LOW_SURROGATE
+ || value[start + 1] > Character.MAX_LOW_SURROGATE)
+ {
+ // Nothing.
+ }
+ else
+ {
+ // Surrogate pair.
+ ++start;
+ }
+ ++start;
+ --codePoints;
+ }
+ return start;
+ }
+
+ /**
+ * Increase the capacity of this <code>StringBuilder</code>. This will
+ * ensure that an expensive growing operation will not occur until
+ * <code>minimumCapacity</code> is reached. The buffer is grown to the
+ * larger of <code>minimumCapacity</code> and
+ * <code>capacity() * 2 + 2</code>, if it is not already large enough.
+ *
+ * @param minimumCapacity the new capacity
+ * @see #capacity()
+ */
+ void ensureCapacity_unsynchronized(int minimumCapacity)
+ {
+ if (minimumCapacity > value.length)
+ {
+ int max = value.length * 2 + 2;
+ minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
+ char[] nb = new char[minimumCapacity];
+ System.arraycopy(value, 0, nb, 0, count);
+ value = nb;
+ }
+ }
+
+ /**
+ * Predicate which determines if a substring of this matches another String
+ * starting at a specified offset for each String and continuing for a
+ * specified length. This is more efficient than creating a String to call
+ * indexOf on.
+ *
+ * @param toffset index to start comparison at for this String
+ * @param other non-null String to compare to region of this
+ * @return true if regions match, false otherwise
+ * @see #indexOf(String, int)
+ * @see #lastIndexOf(String, int)
+ * @see String#regionMatches(boolean, int, String, int, int)
+ */
+ // GCJ LOCAL: native for gcj.
+ private native boolean regionMatches(int toffset, String other);
+
+}
diff --git a/libjava/java/lang/Appendable.h b/libjava/java/lang/Appendable.h
new file mode 100644
index 000000000..d304ff9cf
--- /dev/null
+++ b/libjava/java/lang/Appendable.h
@@ -0,0 +1,21 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Appendable__
+#define __java_lang_Appendable__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Appendable : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::Appendable * append(jchar) = 0;
+ virtual ::java::lang::Appendable * append(::java::lang::CharSequence *) = 0;
+ virtual ::java::lang::Appendable * append(::java::lang::CharSequence *, jint, jint) = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_Appendable__
diff --git a/libjava/java/lang/ArithmeticException.h b/libjava/java/lang/ArithmeticException.h
new file mode 100644
index 000000000..8d784adb7
--- /dev/null
+++ b/libjava/java/lang/ArithmeticException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ArithmeticException__
+#define __java_lang_ArithmeticException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::ArithmeticException : public ::java::lang::RuntimeException
+{
+
+public:
+ ArithmeticException();
+ ArithmeticException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 2256477558314496007LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ArithmeticException__
diff --git a/libjava/java/lang/ArrayIndexOutOfBoundsException.h b/libjava/java/lang/ArrayIndexOutOfBoundsException.h
new file mode 100644
index 000000000..8e65f70f7
--- /dev/null
+++ b/libjava/java/lang/ArrayIndexOutOfBoundsException.h
@@ -0,0 +1,24 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ArrayIndexOutOfBoundsException__
+#define __java_lang_ArrayIndexOutOfBoundsException__
+
+#pragma interface
+
+#include <java/lang/IndexOutOfBoundsException.h>
+
+class java::lang::ArrayIndexOutOfBoundsException : public ::java::lang::IndexOutOfBoundsException
+{
+
+public:
+ ArrayIndexOutOfBoundsException();
+ ArrayIndexOutOfBoundsException(::java::lang::String *);
+ ArrayIndexOutOfBoundsException(jint);
+private:
+ static const jlong serialVersionUID = -5116101128118950844LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ArrayIndexOutOfBoundsException__
diff --git a/libjava/java/lang/ArrayStoreException.h b/libjava/java/lang/ArrayStoreException.h
new file mode 100644
index 000000000..8e120d11c
--- /dev/null
+++ b/libjava/java/lang/ArrayStoreException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ArrayStoreException__
+#define __java_lang_ArrayStoreException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::ArrayStoreException : public ::java::lang::RuntimeException
+{
+
+public:
+ ArrayStoreException();
+ ArrayStoreException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -4522193890499838241LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ArrayStoreException__
diff --git a/libjava/java/lang/AssertionError.h b/libjava/java/lang/AssertionError.h
new file mode 100644
index 000000000..0154c04b3
--- /dev/null
+++ b/libjava/java/lang/AssertionError.h
@@ -0,0 +1,29 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_AssertionError__
+#define __java_lang_AssertionError__
+
+#pragma interface
+
+#include <java/lang/Error.h>
+
+class java::lang::AssertionError : public ::java::lang::Error
+{
+
+public:
+ AssertionError();
+ AssertionError(::java::lang::Object *);
+ AssertionError(jboolean);
+ AssertionError(jchar);
+ AssertionError(jint);
+ AssertionError(jlong);
+ AssertionError(jfloat);
+ AssertionError(jdouble);
+private:
+ static const jlong serialVersionUID = -5013299493970297370LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_AssertionError__
diff --git a/libjava/java/lang/Boolean.h b/libjava/java/lang/Boolean.h
new file mode 100644
index 000000000..0ead5b527
--- /dev/null
+++ b/libjava/java/lang/Boolean.h
@@ -0,0 +1,40 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Boolean__
+#define __java_lang_Boolean__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Boolean : public ::java::lang::Object
+{
+
+public:
+ Boolean(jboolean);
+ Boolean(::java::lang::String *);
+ jboolean booleanValue();
+ static ::java::lang::Boolean * valueOf(jboolean);
+ static ::java::lang::Boolean * valueOf(::java::lang::String *);
+ static ::java::lang::String * toString(jboolean);
+ ::java::lang::String * toString();
+ jint hashCode();
+ jboolean equals(::java::lang::Object *);
+ static jboolean getBoolean(::java::lang::String *);
+ jint Boolean$compareTo(::java::lang::Boolean *);
+ static jboolean parseBoolean(::java::lang::String *);
+ jint compareTo(::java::lang::Object *);
+private:
+ static const jlong serialVersionUID = -3665804199014368530LL;
+public:
+ static ::java::lang::Boolean * TRUE;
+ static ::java::lang::Boolean * FALSE;
+ static ::java::lang::Class * TYPE;
+private:
+ jboolean __attribute__((aligned(__alignof__( ::java::lang::Object)))) value;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Boolean__
diff --git a/libjava/java/lang/Byte.h b/libjava/java/lang/Byte.h
new file mode 100644
index 000000000..fc9e3b33f
--- /dev/null
+++ b/libjava/java/lang/Byte.h
@@ -0,0 +1,51 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Byte__
+#define __java_lang_Byte__
+
+#pragma interface
+
+#include <java/lang/Number.h>
+#include <gcj/array.h>
+
+
+class java::lang::Byte : public ::java::lang::Number
+{
+
+public:
+ Byte(jbyte);
+ Byte(::java::lang::String *);
+ static ::java::lang::String * toString(jbyte);
+ static jbyte parseByte(::java::lang::String *);
+ static jbyte parseByte(::java::lang::String *, jint);
+ static ::java::lang::Byte * valueOf(::java::lang::String *, jint);
+ static ::java::lang::Byte * valueOf(::java::lang::String *);
+ static ::java::lang::Byte * valueOf(jbyte);
+ static ::java::lang::Byte * decode(::java::lang::String *);
+ jbyte byteValue();
+ jshort shortValue();
+ jint intValue();
+ jlong longValue();
+ jfloat floatValue();
+ jdouble doubleValue();
+ ::java::lang::String * toString();
+ jint hashCode();
+ jboolean equals(::java::lang::Object *);
+ jint Byte$compareTo(::java::lang::Byte *);
+ jint compareTo(::java::lang::Object *);
+private:
+ static const jlong serialVersionUID = -7183698231559129828LL;
+public:
+ static const jbyte MIN_VALUE = -128;
+ static const jbyte MAX_VALUE = 127;
+ static ::java::lang::Class * TYPE;
+ static const jint SIZE = 8;
+private:
+ static JArray< ::java::lang::Byte * > * byteCache;
+ jbyte __attribute__((aligned(__alignof__( ::java::lang::Number)))) value;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Byte__
diff --git a/libjava/java/lang/CharSequence.h b/libjava/java/lang/CharSequence.h
new file mode 100644
index 000000000..1348b564d
--- /dev/null
+++ b/libjava/java/lang/CharSequence.h
@@ -0,0 +1,22 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_CharSequence__
+#define __java_lang_CharSequence__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::CharSequence : public ::java::lang::Object
+{
+
+public:
+ virtual jchar charAt(jint) = 0;
+ virtual jint length() = 0;
+ virtual ::java::lang::CharSequence * subSequence(jint, jint) = 0;
+ virtual ::java::lang::String * toString() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_CharSequence__
diff --git a/libjava/java/lang/Character$Subset.h b/libjava/java/lang/Character$Subset.h
new file mode 100644
index 000000000..93f2ba1cb
--- /dev/null
+++ b/libjava/java/lang/Character$Subset.h
@@ -0,0 +1,26 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Character$Subset__
+#define __java_lang_Character$Subset__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Character$Subset : public ::java::lang::Object
+{
+
+public: // actually protected
+ Character$Subset(::java::lang::String *);
+public:
+ virtual jboolean equals(::java::lang::Object *);
+ virtual jint hashCode();
+ virtual ::java::lang::String * toString();
+private:
+ ::java::lang::String * __attribute__((aligned(__alignof__( ::java::lang::Object)))) name;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Character$Subset__
diff --git a/libjava/java/lang/Character$UnicodeBlock$NameType.h b/libjava/java/lang/Character$UnicodeBlock$NameType.h
new file mode 100644
index 000000000..2b83115b0
--- /dev/null
+++ b/libjava/java/lang/Character$UnicodeBlock$NameType.h
@@ -0,0 +1,29 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Character$UnicodeBlock$NameType__
+#define __java_lang_Character$UnicodeBlock$NameType__
+
+#pragma interface
+
+#include <java/lang/Enum.h>
+#include <gcj/array.h>
+
+
+class java::lang::Character$UnicodeBlock$NameType : public ::java::lang::Enum
+{
+
+ Character$UnicodeBlock$NameType(::java::lang::String *, jint);
+public:
+ static JArray< ::java::lang::Character$UnicodeBlock$NameType * > * values();
+ static ::java::lang::Character$UnicodeBlock$NameType * valueOf(::java::lang::String *);
+ static ::java::lang::Character$UnicodeBlock$NameType * CANONICAL;
+ static ::java::lang::Character$UnicodeBlock$NameType * NO_SPACES;
+ static ::java::lang::Character$UnicodeBlock$NameType * CONSTANT;
+private:
+ static JArray< ::java::lang::Character$UnicodeBlock$NameType * > * ENUM$VALUES;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Character$UnicodeBlock$NameType__
diff --git a/libjava/java/lang/Character$UnicodeBlock.h b/libjava/java/lang/Character$UnicodeBlock.h
new file mode 100644
index 000000000..b32f2121e
--- /dev/null
+++ b/libjava/java/lang/Character$UnicodeBlock.h
@@ -0,0 +1,161 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Character$UnicodeBlock__
+#define __java_lang_Character$UnicodeBlock__
+
+#pragma interface
+
+#include <java/lang/Character$Subset.h>
+#include <gcj/array.h>
+
+
+class java::lang::Character$UnicodeBlock : public ::java::lang::Character$Subset
+{
+
+ Character$UnicodeBlock(jint, jint, ::java::lang::String *, ::java::lang::String *);
+public:
+ static ::java::lang::Character$UnicodeBlock * of(jchar);
+ static ::java::lang::Character$UnicodeBlock * of(jint);
+ static ::java::lang::Character$UnicodeBlock * forName(::java::lang::String *);
+public: // actually package-private
+ static JArray< jint > * $SWITCH_TABLE$java$lang$Character$UnicodeBlock$NameType();
+private:
+ jint __attribute__((aligned(__alignof__( ::java::lang::Character$Subset)))) start;
+ jint end;
+ ::java::lang::String * canonicalName;
+public:
+ static ::java::lang::Character$UnicodeBlock * BASIC_LATIN;
+ static ::java::lang::Character$UnicodeBlock * LATIN_1_SUPPLEMENT;
+ static ::java::lang::Character$UnicodeBlock * LATIN_EXTENDED_A;
+ static ::java::lang::Character$UnicodeBlock * LATIN_EXTENDED_B;
+ static ::java::lang::Character$UnicodeBlock * IPA_EXTENSIONS;
+ static ::java::lang::Character$UnicodeBlock * SPACING_MODIFIER_LETTERS;
+ static ::java::lang::Character$UnicodeBlock * COMBINING_DIACRITICAL_MARKS;
+ static ::java::lang::Character$UnicodeBlock * GREEK;
+ static ::java::lang::Character$UnicodeBlock * CYRILLIC;
+ static ::java::lang::Character$UnicodeBlock * CYRILLIC_SUPPLEMENTARY;
+ static ::java::lang::Character$UnicodeBlock * ARMENIAN;
+ static ::java::lang::Character$UnicodeBlock * HEBREW;
+ static ::java::lang::Character$UnicodeBlock * ARABIC;
+ static ::java::lang::Character$UnicodeBlock * SYRIAC;
+ static ::java::lang::Character$UnicodeBlock * THAANA;
+ static ::java::lang::Character$UnicodeBlock * DEVANAGARI;
+ static ::java::lang::Character$UnicodeBlock * BENGALI;
+ static ::java::lang::Character$UnicodeBlock * GURMUKHI;
+ static ::java::lang::Character$UnicodeBlock * GUJARATI;
+ static ::java::lang::Character$UnicodeBlock * ORIYA;
+ static ::java::lang::Character$UnicodeBlock * TAMIL;
+ static ::java::lang::Character$UnicodeBlock * TELUGU;
+ static ::java::lang::Character$UnicodeBlock * KANNADA;
+ static ::java::lang::Character$UnicodeBlock * MALAYALAM;
+ static ::java::lang::Character$UnicodeBlock * SINHALA;
+ static ::java::lang::Character$UnicodeBlock * THAI;
+ static ::java::lang::Character$UnicodeBlock * LAO;
+ static ::java::lang::Character$UnicodeBlock * TIBETAN;
+ static ::java::lang::Character$UnicodeBlock * MYANMAR;
+ static ::java::lang::Character$UnicodeBlock * GEORGIAN;
+ static ::java::lang::Character$UnicodeBlock * HANGUL_JAMO;
+ static ::java::lang::Character$UnicodeBlock * ETHIOPIC;
+ static ::java::lang::Character$UnicodeBlock * CHEROKEE;
+ static ::java::lang::Character$UnicodeBlock * UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS;
+ static ::java::lang::Character$UnicodeBlock * OGHAM;
+ static ::java::lang::Character$UnicodeBlock * RUNIC;
+ static ::java::lang::Character$UnicodeBlock * TAGALOG;
+ static ::java::lang::Character$UnicodeBlock * HANUNOO;
+ static ::java::lang::Character$UnicodeBlock * BUHID;
+ static ::java::lang::Character$UnicodeBlock * TAGBANWA;
+ static ::java::lang::Character$UnicodeBlock * KHMER;
+ static ::java::lang::Character$UnicodeBlock * MONGOLIAN;
+ static ::java::lang::Character$UnicodeBlock * LIMBU;
+ static ::java::lang::Character$UnicodeBlock * TAI_LE;
+ static ::java::lang::Character$UnicodeBlock * KHMER_SYMBOLS;
+ static ::java::lang::Character$UnicodeBlock * PHONETIC_EXTENSIONS;
+ static ::java::lang::Character$UnicodeBlock * LATIN_EXTENDED_ADDITIONAL;
+ static ::java::lang::Character$UnicodeBlock * GREEK_EXTENDED;
+ static ::java::lang::Character$UnicodeBlock * GENERAL_PUNCTUATION;
+ static ::java::lang::Character$UnicodeBlock * SUPERSCRIPTS_AND_SUBSCRIPTS;
+ static ::java::lang::Character$UnicodeBlock * CURRENCY_SYMBOLS;
+ static ::java::lang::Character$UnicodeBlock * COMBINING_MARKS_FOR_SYMBOLS;
+ static ::java::lang::Character$UnicodeBlock * LETTERLIKE_SYMBOLS;
+ static ::java::lang::Character$UnicodeBlock * NUMBER_FORMS;
+ static ::java::lang::Character$UnicodeBlock * ARROWS;
+ static ::java::lang::Character$UnicodeBlock * MATHEMATICAL_OPERATORS;
+ static ::java::lang::Character$UnicodeBlock * MISCELLANEOUS_TECHNICAL;
+ static ::java::lang::Character$UnicodeBlock * CONTROL_PICTURES;
+ static ::java::lang::Character$UnicodeBlock * OPTICAL_CHARACTER_RECOGNITION;
+ static ::java::lang::Character$UnicodeBlock * ENCLOSED_ALPHANUMERICS;
+ static ::java::lang::Character$UnicodeBlock * BOX_DRAWING;
+ static ::java::lang::Character$UnicodeBlock * BLOCK_ELEMENTS;
+ static ::java::lang::Character$UnicodeBlock * GEOMETRIC_SHAPES;
+ static ::java::lang::Character$UnicodeBlock * MISCELLANEOUS_SYMBOLS;
+ static ::java::lang::Character$UnicodeBlock * DINGBATS;
+ static ::java::lang::Character$UnicodeBlock * MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A;
+ static ::java::lang::Character$UnicodeBlock * SUPPLEMENTAL_ARROWS_A;
+ static ::java::lang::Character$UnicodeBlock * BRAILLE_PATTERNS;
+ static ::java::lang::Character$UnicodeBlock * SUPPLEMENTAL_ARROWS_B;
+ static ::java::lang::Character$UnicodeBlock * MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B;
+ static ::java::lang::Character$UnicodeBlock * SUPPLEMENTAL_MATHEMATICAL_OPERATORS;
+ static ::java::lang::Character$UnicodeBlock * MISCELLANEOUS_SYMBOLS_AND_ARROWS;
+ static ::java::lang::Character$UnicodeBlock * CJK_RADICALS_SUPPLEMENT;
+ static ::java::lang::Character$UnicodeBlock * KANGXI_RADICALS;
+ static ::java::lang::Character$UnicodeBlock * IDEOGRAPHIC_DESCRIPTION_CHARACTERS;
+ static ::java::lang::Character$UnicodeBlock * CJK_SYMBOLS_AND_PUNCTUATION;
+ static ::java::lang::Character$UnicodeBlock * HIRAGANA;
+ static ::java::lang::Character$UnicodeBlock * KATAKANA;
+ static ::java::lang::Character$UnicodeBlock * BOPOMOFO;
+ static ::java::lang::Character$UnicodeBlock * HANGUL_COMPATIBILITY_JAMO;
+ static ::java::lang::Character$UnicodeBlock * KANBUN;
+ static ::java::lang::Character$UnicodeBlock * BOPOMOFO_EXTENDED;
+ static ::java::lang::Character$UnicodeBlock * KATAKANA_PHONETIC_EXTENSIONS;
+ static ::java::lang::Character$UnicodeBlock * ENCLOSED_CJK_LETTERS_AND_MONTHS;
+ static ::java::lang::Character$UnicodeBlock * CJK_COMPATIBILITY;
+ static ::java::lang::Character$UnicodeBlock * CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A;
+ static ::java::lang::Character$UnicodeBlock * YIJING_HEXAGRAM_SYMBOLS;
+ static ::java::lang::Character$UnicodeBlock * CJK_UNIFIED_IDEOGRAPHS;
+ static ::java::lang::Character$UnicodeBlock * YI_SYLLABLES;
+ static ::java::lang::Character$UnicodeBlock * YI_RADICALS;
+ static ::java::lang::Character$UnicodeBlock * HANGUL_SYLLABLES;
+ static ::java::lang::Character$UnicodeBlock * HIGH_SURROGATES;
+ static ::java::lang::Character$UnicodeBlock * HIGH_PRIVATE_USE_SURROGATES;
+ static ::java::lang::Character$UnicodeBlock * LOW_SURROGATES;
+ static ::java::lang::Character$UnicodeBlock * PRIVATE_USE_AREA;
+ static ::java::lang::Character$UnicodeBlock * CJK_COMPATIBILITY_IDEOGRAPHS;
+ static ::java::lang::Character$UnicodeBlock * ALPHABETIC_PRESENTATION_FORMS;
+ static ::java::lang::Character$UnicodeBlock * ARABIC_PRESENTATION_FORMS_A;
+ static ::java::lang::Character$UnicodeBlock * VARIATION_SELECTORS;
+ static ::java::lang::Character$UnicodeBlock * COMBINING_HALF_MARKS;
+ static ::java::lang::Character$UnicodeBlock * CJK_COMPATIBILITY_FORMS;
+ static ::java::lang::Character$UnicodeBlock * SMALL_FORM_VARIANTS;
+ static ::java::lang::Character$UnicodeBlock * ARABIC_PRESENTATION_FORMS_B;
+ static ::java::lang::Character$UnicodeBlock * HALFWIDTH_AND_FULLWIDTH_FORMS;
+ static ::java::lang::Character$UnicodeBlock * SPECIALS;
+ static ::java::lang::Character$UnicodeBlock * LINEAR_B_SYLLABARY;
+ static ::java::lang::Character$UnicodeBlock * LINEAR_B_IDEOGRAMS;
+ static ::java::lang::Character$UnicodeBlock * AEGEAN_NUMBERS;
+ static ::java::lang::Character$UnicodeBlock * OLD_ITALIC;
+ static ::java::lang::Character$UnicodeBlock * GOTHIC;
+ static ::java::lang::Character$UnicodeBlock * UGARITIC;
+ static ::java::lang::Character$UnicodeBlock * DESERET;
+ static ::java::lang::Character$UnicodeBlock * SHAVIAN;
+ static ::java::lang::Character$UnicodeBlock * OSMANYA;
+ static ::java::lang::Character$UnicodeBlock * CYPRIOT_SYLLABARY;
+ static ::java::lang::Character$UnicodeBlock * BYZANTINE_MUSICAL_SYMBOLS;
+ static ::java::lang::Character$UnicodeBlock * MUSICAL_SYMBOLS;
+ static ::java::lang::Character$UnicodeBlock * TAI_XUAN_JING_SYMBOLS;
+ static ::java::lang::Character$UnicodeBlock * MATHEMATICAL_ALPHANUMERIC_SYMBOLS;
+ static ::java::lang::Character$UnicodeBlock * CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B;
+ static ::java::lang::Character$UnicodeBlock * CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT;
+ static ::java::lang::Character$UnicodeBlock * TAGS;
+ static ::java::lang::Character$UnicodeBlock * VARIATION_SELECTORS_SUPPLEMENT;
+ static ::java::lang::Character$UnicodeBlock * SUPPLEMENTARY_PRIVATE_USE_AREA_A;
+ static ::java::lang::Character$UnicodeBlock * SUPPLEMENTARY_PRIVATE_USE_AREA_B;
+ static ::java::lang::Character$UnicodeBlock * SURROGATES_AREA;
+private:
+ static JArray< ::java::lang::Character$UnicodeBlock * > * sets;
+ static JArray< jint > * $SWITCH_TABLE$java$lang$Character$UnicodeBlock$NameType__;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Character$UnicodeBlock__
diff --git a/libjava/java/lang/Character.h b/libjava/java/lang/Character.h
new file mode 100644
index 000000000..a21447098
--- /dev/null
+++ b/libjava/java/lang/Character.h
@@ -0,0 +1,179 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Character__
+#define __java_lang_Character__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::Character : public ::java::lang::Object
+{
+
+ static jchar readChar(jchar);
+ static jchar readCodePoint(jint);
+public:
+ Character(jchar);
+ jchar charValue();
+ jint hashCode();
+ jboolean equals(::java::lang::Object *);
+ ::java::lang::String * toString();
+ static ::java::lang::String * toString(jchar);
+ static jboolean isLowerCase(jchar);
+ static jboolean isLowerCase(jint);
+ static jboolean isUpperCase(jchar);
+ static jboolean isUpperCase(jint);
+ static jboolean isTitleCase(jchar);
+ static jboolean isTitleCase(jint);
+ static jboolean isDigit(jchar);
+ static jboolean isDigit(jint);
+ static jboolean isDefined(jchar);
+ static jboolean isDefined(jint);
+ static jboolean isLetter(jchar);
+ static jboolean isLetter(jint);
+ static jint offsetByCodePoints(::java::lang::CharSequence *, jint, jint);
+ static jint offsetByCodePoints(JArray< jchar > *, jint, jint, jint, jint);
+ static jint codePointCount(::java::lang::CharSequence *, jint, jint);
+ static jint codePointCount(JArray< jchar > *, jint, jint);
+ static jboolean isLetterOrDigit(jchar);
+ static jboolean isLetterOrDigit(jint);
+ static jboolean isJavaLetter(jchar);
+ static jboolean isJavaIdentifierStart(jint);
+ static jboolean isJavaLetterOrDigit(jchar);
+ static jboolean isJavaIdentifierStart(jchar);
+ static jboolean isJavaIdentifierPart(jchar);
+ static jboolean isJavaIdentifierPart(jint);
+ static jboolean isUnicodeIdentifierStart(jchar);
+ static jboolean isUnicodeIdentifierStart(jint);
+ static jboolean isUnicodeIdentifierPart(jchar);
+ static jboolean isUnicodeIdentifierPart(jint);
+ static jboolean isIdentifierIgnorable(jchar);
+ static jboolean isIdentifierIgnorable(jint);
+ static jchar toLowerCase(jchar);
+ static jint toLowerCase(jint);
+ static jchar toUpperCase(jchar);
+ static jint toUpperCase(jint);
+ static jchar toTitleCase(jchar);
+ static jint toTitleCase(jint);
+ static jint digit(jchar, jint);
+ static jint digit(jint, jint);
+ static jint getNumericValue(jchar);
+ static jint getNumericValue(jint);
+ static jboolean isSpace(jchar);
+ static jboolean isSpaceChar(jchar);
+ static jboolean isSpaceChar(jint);
+ static jboolean isWhitespace(jchar);
+ static jboolean isWhitespace(jint);
+ static jboolean isISOControl(jchar);
+ static jboolean isISOControl(jint);
+ static jint getType(jchar);
+ static jint getType(jint);
+ static jchar forDigit(jint, jint);
+ static jbyte getDirectionality(jchar);
+ static jbyte getDirectionality(jint);
+ static jboolean isMirrored(jchar);
+ static jboolean isMirrored(jint);
+ jint Character$compareTo(::java::lang::Character *);
+ static ::java::lang::Character * valueOf(jchar);
+ static jchar reverseBytes(jchar);
+ static JArray< jchar > * toChars(jint);
+ static jint toChars(jint, JArray< jchar > *, jint);
+ static jint charCount(jint);
+ static jboolean isSupplementaryCodePoint(jint);
+ static jboolean isValidCodePoint(jint);
+ static jboolean isHighSurrogate(jchar);
+ static jboolean isLowSurrogate(jchar);
+ static jboolean isSurrogatePair(jchar, jchar);
+ static jint toCodePoint(jchar, jchar);
+ static jint codePointAt(::java::lang::CharSequence *, jint);
+ static jint codePointAt(JArray< jchar > *, jint);
+ static jint codePointAt(JArray< jchar > *, jint, jint);
+ static jint codePointBefore(JArray< jchar > *, jint);
+ static jint codePointBefore(JArray< jchar > *, jint, jint);
+ static jint codePointBefore(::java::lang::CharSequence *, jint);
+ jint compareTo(::java::lang::Object *);
+private:
+ jchar __attribute__((aligned(__alignof__( ::java::lang::Object)))) value;
+ static const jlong serialVersionUID = 3786198910865385080LL;
+public:
+ static const jint MIN_RADIX = 2;
+ static const jint MAX_RADIX = 36;
+ static const jchar MIN_VALUE = 0;
+ static const jchar MAX_VALUE = 65535;
+ static const jint MIN_CODE_POINT = 0;
+ static const jint MAX_CODE_POINT = 1114111;
+ static const jchar MIN_HIGH_SURROGATE = 55296;
+ static const jchar MAX_HIGH_SURROGATE = 56319;
+ static const jchar MIN_LOW_SURROGATE = 56320;
+ static const jchar MAX_LOW_SURROGATE = 57343;
+ static const jchar MIN_SURROGATE = 55296;
+ static const jchar MAX_SURROGATE = 57343;
+ static const jint MIN_SUPPLEMENTARY_CODE_POINT = 65536;
+ static ::java::lang::Class * TYPE;
+ static const jint SIZE = 16;
+private:
+ static const jint MAX_CACHE = 127;
+ static JArray< ::java::lang::Character * > * charCache;
+public:
+ static const jbyte UPPERCASE_LETTER = 1;
+ static const jbyte LOWERCASE_LETTER = 2;
+ static const jbyte TITLECASE_LETTER = 3;
+ static const jbyte NON_SPACING_MARK = 6;
+ static const jbyte COMBINING_SPACING_MARK = 8;
+ static const jbyte ENCLOSING_MARK = 7;
+ static const jbyte DECIMAL_DIGIT_NUMBER = 9;
+ static const jbyte LETTER_NUMBER = 10;
+ static const jbyte OTHER_NUMBER = 11;
+ static const jbyte SPACE_SEPARATOR = 12;
+ static const jbyte LINE_SEPARATOR = 13;
+ static const jbyte PARAGRAPH_SEPARATOR = 14;
+ static const jbyte CONTROL = 15;
+ static const jbyte FORMAT = 16;
+ static const jbyte SURROGATE = 19;
+ static const jbyte PRIVATE_USE = 18;
+ static const jbyte UNASSIGNED = 0;
+ static const jbyte MODIFIER_LETTER = 4;
+ static const jbyte OTHER_LETTER = 5;
+ static const jbyte CONNECTOR_PUNCTUATION = 23;
+ static const jbyte DASH_PUNCTUATION = 20;
+ static const jbyte START_PUNCTUATION = 21;
+ static const jbyte END_PUNCTUATION = 22;
+ static const jbyte INITIAL_QUOTE_PUNCTUATION = 29;
+ static const jbyte FINAL_QUOTE_PUNCTUATION = 30;
+ static const jbyte OTHER_PUNCTUATION = 24;
+ static const jbyte MATH_SYMBOL = 25;
+ static const jbyte CURRENCY_SYMBOL = 26;
+ static const jbyte MODIFIER_SYMBOL = 27;
+ static const jbyte OTHER_SYMBOL = 28;
+ static const jbyte DIRECTIONALITY_UNDEFINED = -1;
+ static const jbyte DIRECTIONALITY_LEFT_TO_RIGHT = 0;
+ static const jbyte DIRECTIONALITY_RIGHT_TO_LEFT = 1;
+ static const jbyte DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC = 2;
+ static const jbyte DIRECTIONALITY_EUROPEAN_NUMBER = 3;
+ static const jbyte DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR = 4;
+ static const jbyte DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR = 5;
+ static const jbyte DIRECTIONALITY_ARABIC_NUMBER = 6;
+ static const jbyte DIRECTIONALITY_COMMON_NUMBER_SEPARATOR = 7;
+ static const jbyte DIRECTIONALITY_NONSPACING_MARK = 8;
+ static const jbyte DIRECTIONALITY_BOUNDARY_NEUTRAL = 9;
+ static const jbyte DIRECTIONALITY_PARAGRAPH_SEPARATOR = 10;
+ static const jbyte DIRECTIONALITY_SEGMENT_SEPARATOR = 11;
+ static const jbyte DIRECTIONALITY_WHITESPACE = 12;
+ static const jbyte DIRECTIONALITY_OTHER_NEUTRALS = 13;
+ static const jbyte DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING = 14;
+ static const jbyte DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE = 15;
+ static const jbyte DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING = 16;
+ static const jbyte DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE = 17;
+ static const jbyte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18;
+private:
+ static const jint TYPE_MASK = 31;
+ static const jint NO_BREAK_MASK = 32;
+ static const jint MIRROR_MASK = 64;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Character__
diff --git a/libjava/java/lang/Character.java b/libjava/java/lang/Character.java
new file mode 100644
index 000000000..2edf72e67
--- /dev/null
+++ b/libjava/java/lang/Character.java
@@ -0,0 +1,4051 @@
+/* java.lang.Character -- Wrapper class for char, and Unicode subsets
+ Copyright (C) 1998, 1999, 2001, 2002, 2005, 2006, 2007
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+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. */
+
+/*
+ * Note: This class must not be merged with Classpath. Gcj uses C-style
+ * arrays (see include/java-chartables.h) to store the Unicode character
+ * database, whereas Classpath uses Java objects (char[] extracted from
+ * String constants) in gnu.java.lang.CharData. Gcj's approach is more
+ * efficient, because there is no vtable or data relocation to worry about.
+ * However, despite the difference in the database interface, the two
+ * versions share identical algorithms.
+ */
+
+package java.lang;
+
+import java.io.Serializable;
+import java.text.Collator;
+import java.util.Locale;
+
+/**
+ * Wrapper class for the primitive char data type. In addition, this class
+ * allows one to retrieve property information and perform transformations
+ * on the defined characters in the Unicode Standard, Version 4.0.0.
+ * java.lang.Character is designed to be very dynamic, and as such, it
+ * retrieves information on the Unicode character set from a separate
+ * database, gnu.java.lang.CharData, which can be easily upgraded.
+ *
+ * <p>For predicates, boundaries are used to describe
+ * the set of characters for which the method will return true.
+ * This syntax uses fairly normal regular expression notation.
+ * See 5.13 of the Unicode Standard, Version 4.0, for the
+ * boundary specification.
+ *
+ * <p>See <a href="http://www.unicode.org">http://www.unicode.org</a>
+ * for more information on the Unicode Standard.
+ *
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Paul N. Fisher
+ * @author Jochen Hoenicke
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.0
+ * @status partly updated to 1.5; some things still missing
+ */
+public final class Character implements Serializable, Comparable<Character>
+{
+ /**
+ * A subset of Unicode blocks.
+ *
+ * @author Paul N. Fisher
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ */
+ public static class Subset
+ {
+ /** The name of the subset. */
+ private final String name;
+
+ /**
+ * Construct a new subset of characters.
+ *
+ * @param name the name of the subset
+ * @throws NullPointerException if name is null
+ */
+ protected Subset(String name)
+ {
+ // Note that name.toString() is name, unless name was null.
+ this.name = name.toString();
+ }
+
+ /**
+ * Compares two Subsets for equality. This is <code>final</code>, and
+ * restricts the comparison on the <code>==</code> operator, so it returns
+ * true only for the same object.
+ *
+ * @param o the object to compare
+ * @return true if o is this
+ */
+ public final boolean equals(Object o)
+ {
+ return o == this;
+ }
+
+ /**
+ * Makes the original hashCode of Object final, to be consistent with
+ * equals.
+ *
+ * @return the hash code for this object
+ */
+ public final int hashCode()
+ {
+ return super.hashCode();
+ }
+
+ /**
+ * Returns the name of the subset.
+ *
+ * @return the name
+ */
+ public final String toString()
+ {
+ return name;
+ }
+ } // class Subset
+
+ /**
+ * A family of character subsets in the Unicode specification. A character
+ * is in at most one of these blocks.
+ *
+ * This inner class was generated automatically from
+ * <code>libjava/gnu/gcj/convert/Blocks-3.txt</code>, by some perl scripts.
+ * This Unicode definition file can be found on the
+ * <a href="http://www.unicode.org">http://www.unicode.org</a> website.
+ * JDK 1.4 uses Unicode version 3.0.0.
+ *
+ * @author scripts/unicode-blocks.pl (written by Eric Blake)
+ * @since 1.2
+ */
+ public static final class UnicodeBlock extends Subset
+ {
+ /** The start of the subset. */
+ private final int start;
+
+ /** The end of the subset. */
+ private final int end;
+
+ /** The canonical name of the block according to the Unicode standard. */
+ private final String canonicalName;
+
+ /** Enumeration for the <code>forName()</code> method */
+ private enum NameType { CANONICAL, NO_SPACES, CONSTANT; }
+
+ /**
+ * Constructor for strictly defined blocks.
+ *
+ * @param start the start character of the range
+ * @param end the end character of the range
+ * @param name the block name
+ */
+ private UnicodeBlock(int start, int end, String name,
+ String canonicalName)
+ {
+ super(name);
+ this.start = start;
+ this.end = end;
+ this.canonicalName = canonicalName;
+ }
+
+ /**
+ * Returns the Unicode character block which a character belongs to.
+ * <strong>Note</strong>: This method does not support the use of
+ * supplementary characters. For such support, <code>of(int)</code>
+ * should be used instead.
+ *
+ * @param ch the character to look up
+ * @return the set it belongs to, or null if it is not in one
+ */
+ public static UnicodeBlock of(char ch)
+ {
+ return of((int) ch);
+ }
+
+ /**
+ * Returns the Unicode character block which a code point belongs to.
+ *
+ * @param codePoint the character to look up
+ * @return the set it belongs to, or null if it is not in one.
+ * @throws IllegalArgumentException if the specified code point is
+ * invalid.
+ * @since 1.5
+ */
+ public static UnicodeBlock of(int codePoint)
+ {
+ if (codePoint > MAX_CODE_POINT)
+ throw new IllegalArgumentException("The supplied integer value is " +
+ "too large to be a codepoint.");
+ // Simple binary search for the correct block.
+ int low = 0;
+ int hi = sets.length - 1;
+ while (low <= hi)
+ {
+ int mid = (low + hi) >> 1;
+ UnicodeBlock b = sets[mid];
+ if (codePoint < b.start)
+ hi = mid - 1;
+ else if (codePoint > b.end)
+ low = mid + 1;
+ else
+ return b;
+ }
+ return null;
+ }
+
+ /**
+ * <p>
+ * Returns the <code>UnicodeBlock</code> with the given name, as defined
+ * by the Unicode standard. The version of Unicode in use is defined by
+ * the <code>Character</code> class, and the names are given in the
+ * <code>Blocks-<version>.txt</code> file corresponding to that version.
+ * The name may be specified in one of three ways:
+ * </p>
+ * <ol>
+ * <li>The canonical, human-readable name used by the Unicode standard.
+ * This is the name with all spaces and hyphens retained. For example,
+ * `Basic Latin' retrieves the block, UnicodeBlock.BASIC_LATIN.</li>
+ * <li>The canonical name with all spaces removed e.g. `BasicLatin'.</li>
+ * <li>The name used for the constants specified by this class, which
+ * is the canonical name with all spaces and hyphens replaced with
+ * underscores e.g. `BASIC_LATIN'</li>
+ * </ol>
+ * <p>
+ * The names are compared case-insensitively using the case comparison
+ * associated with the U.S. English locale. The method recognises the
+ * previous names used for blocks as well as the current ones. At
+ * present, this simply means that the deprecated `SURROGATES_AREA'
+ * will be recognised by this method (the <code>of()</code> methods
+ * only return one of the three new surrogate blocks).
+ * </p>
+ *
+ * @param blockName the name of the block to look up.
+ * @return the specified block.
+ * @throws NullPointerException if the <code>blockName</code> is
+ * <code>null</code>.
+ * @throws IllegalArgumentException if the name does not match any Unicode
+ * block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock forName(String blockName)
+ {
+ NameType type;
+ if (blockName.indexOf(' ') != -1)
+ type = NameType.CANONICAL;
+ else if (blockName.indexOf('_') != -1)
+ type = NameType.CONSTANT;
+ else
+ type = NameType.NO_SPACES;
+ Collator usCollator = Collator.getInstance(Locale.US);
+ usCollator.setStrength(Collator.PRIMARY);
+ /* Special case for deprecated blocks not in sets */
+ switch (type)
+ {
+ case CANONICAL:
+ if (usCollator.compare(blockName, "Surrogates Area") == 0)
+ return SURROGATES_AREA;
+ break;
+ case NO_SPACES:
+ if (usCollator.compare(blockName, "SurrogatesArea") == 0)
+ return SURROGATES_AREA;
+ break;
+ case CONSTANT:
+ if (usCollator.compare(blockName, "SURROGATES_AREA") == 0)
+ return SURROGATES_AREA;
+ break;
+ }
+ /* Other cases */
+ switch (type)
+ {
+ case CANONICAL:
+ for (UnicodeBlock block : sets)
+ if (usCollator.compare(blockName, block.canonicalName) == 0)
+ return block;
+ break;
+ case NO_SPACES:
+ for (UnicodeBlock block : sets)
+ {
+ String nsName = block.canonicalName.replaceAll(" ","");
+ if (usCollator.compare(blockName, nsName) == 0)
+ return block;
+ }
+ break;
+ case CONSTANT:
+ for (UnicodeBlock block : sets)
+ if (usCollator.compare(blockName, block.toString()) == 0)
+ return block;
+ break;
+ }
+ throw new IllegalArgumentException("No Unicode block found for " +
+ blockName + ".");
+ }
+
+ /**
+ * Basic Latin.
+ * 0x0000 - 0x007F.
+ */
+ public static final UnicodeBlock BASIC_LATIN
+ = new UnicodeBlock(0x0000, 0x007F,
+ "BASIC_LATIN",
+ "Basic Latin");
+
+ /**
+ * Latin-1 Supplement.
+ * 0x0080 - 0x00FF.
+ */
+ public static final UnicodeBlock LATIN_1_SUPPLEMENT
+ = new UnicodeBlock(0x0080, 0x00FF,
+ "LATIN_1_SUPPLEMENT",
+ "Latin-1 Supplement");
+
+ /**
+ * Latin Extended-A.
+ * 0x0100 - 0x017F.
+ */
+ public static final UnicodeBlock LATIN_EXTENDED_A
+ = new UnicodeBlock(0x0100, 0x017F,
+ "LATIN_EXTENDED_A",
+ "Latin Extended-A");
+
+ /**
+ * Latin Extended-B.
+ * 0x0180 - 0x024F.
+ */
+ public static final UnicodeBlock LATIN_EXTENDED_B
+ = new UnicodeBlock(0x0180, 0x024F,
+ "LATIN_EXTENDED_B",
+ "Latin Extended-B");
+
+ /**
+ * IPA Extensions.
+ * 0x0250 - 0x02AF.
+ */
+ public static final UnicodeBlock IPA_EXTENSIONS
+ = new UnicodeBlock(0x0250, 0x02AF,
+ "IPA_EXTENSIONS",
+ "IPA Extensions");
+
+ /**
+ * Spacing Modifier Letters.
+ * 0x02B0 - 0x02FF.
+ */
+ public static final UnicodeBlock SPACING_MODIFIER_LETTERS
+ = new UnicodeBlock(0x02B0, 0x02FF,
+ "SPACING_MODIFIER_LETTERS",
+ "Spacing Modifier Letters");
+
+ /**
+ * Combining Diacritical Marks.
+ * 0x0300 - 0x036F.
+ */
+ public static final UnicodeBlock COMBINING_DIACRITICAL_MARKS
+ = new UnicodeBlock(0x0300, 0x036F,
+ "COMBINING_DIACRITICAL_MARKS",
+ "Combining Diacritical Marks");
+
+ /**
+ * Greek.
+ * 0x0370 - 0x03FF.
+ */
+ public static final UnicodeBlock GREEK
+ = new UnicodeBlock(0x0370, 0x03FF,
+ "GREEK",
+ "Greek");
+
+ /**
+ * Cyrillic.
+ * 0x0400 - 0x04FF.
+ */
+ public static final UnicodeBlock CYRILLIC
+ = new UnicodeBlock(0x0400, 0x04FF,
+ "CYRILLIC",
+ "Cyrillic");
+
+ /**
+ * Cyrillic Supplementary.
+ * 0x0500 - 0x052F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock CYRILLIC_SUPPLEMENTARY
+ = new UnicodeBlock(0x0500, 0x052F,
+ "CYRILLIC_SUPPLEMENTARY",
+ "Cyrillic Supplementary");
+
+ /**
+ * Armenian.
+ * 0x0530 - 0x058F.
+ */
+ public static final UnicodeBlock ARMENIAN
+ = new UnicodeBlock(0x0530, 0x058F,
+ "ARMENIAN",
+ "Armenian");
+
+ /**
+ * Hebrew.
+ * 0x0590 - 0x05FF.
+ */
+ public static final UnicodeBlock HEBREW
+ = new UnicodeBlock(0x0590, 0x05FF,
+ "HEBREW",
+ "Hebrew");
+
+ /**
+ * Arabic.
+ * 0x0600 - 0x06FF.
+ */
+ public static final UnicodeBlock ARABIC
+ = new UnicodeBlock(0x0600, 0x06FF,
+ "ARABIC",
+ "Arabic");
+
+ /**
+ * Syriac.
+ * 0x0700 - 0x074F.
+ * @since 1.4
+ */
+ public static final UnicodeBlock SYRIAC
+ = new UnicodeBlock(0x0700, 0x074F,
+ "SYRIAC",
+ "Syriac");
+
+ /**
+ * Thaana.
+ * 0x0780 - 0x07BF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock THAANA
+ = new UnicodeBlock(0x0780, 0x07BF,
+ "THAANA",
+ "Thaana");
+
+ /**
+ * Devanagari.
+ * 0x0900 - 0x097F.
+ */
+ public static final UnicodeBlock DEVANAGARI
+ = new UnicodeBlock(0x0900, 0x097F,
+ "DEVANAGARI",
+ "Devanagari");
+
+ /**
+ * Bengali.
+ * 0x0980 - 0x09FF.
+ */
+ public static final UnicodeBlock BENGALI
+ = new UnicodeBlock(0x0980, 0x09FF,
+ "BENGALI",
+ "Bengali");
+
+ /**
+ * Gurmukhi.
+ * 0x0A00 - 0x0A7F.
+ */
+ public static final UnicodeBlock GURMUKHI
+ = new UnicodeBlock(0x0A00, 0x0A7F,
+ "GURMUKHI",
+ "Gurmukhi");
+
+ /**
+ * Gujarati.
+ * 0x0A80 - 0x0AFF.
+ */
+ public static final UnicodeBlock GUJARATI
+ = new UnicodeBlock(0x0A80, 0x0AFF,
+ "GUJARATI",
+ "Gujarati");
+
+ /**
+ * Oriya.
+ * 0x0B00 - 0x0B7F.
+ */
+ public static final UnicodeBlock ORIYA
+ = new UnicodeBlock(0x0B00, 0x0B7F,
+ "ORIYA",
+ "Oriya");
+
+ /**
+ * Tamil.
+ * 0x0B80 - 0x0BFF.
+ */
+ public static final UnicodeBlock TAMIL
+ = new UnicodeBlock(0x0B80, 0x0BFF,
+ "TAMIL",
+ "Tamil");
+
+ /**
+ * Telugu.
+ * 0x0C00 - 0x0C7F.
+ */
+ public static final UnicodeBlock TELUGU
+ = new UnicodeBlock(0x0C00, 0x0C7F,
+ "TELUGU",
+ "Telugu");
+
+ /**
+ * Kannada.
+ * 0x0C80 - 0x0CFF.
+ */
+ public static final UnicodeBlock KANNADA
+ = new UnicodeBlock(0x0C80, 0x0CFF,
+ "KANNADA",
+ "Kannada");
+
+ /**
+ * Malayalam.
+ * 0x0D00 - 0x0D7F.
+ */
+ public static final UnicodeBlock MALAYALAM
+ = new UnicodeBlock(0x0D00, 0x0D7F,
+ "MALAYALAM",
+ "Malayalam");
+
+ /**
+ * Sinhala.
+ * 0x0D80 - 0x0DFF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock SINHALA
+ = new UnicodeBlock(0x0D80, 0x0DFF,
+ "SINHALA",
+ "Sinhala");
+
+ /**
+ * Thai.
+ * 0x0E00 - 0x0E7F.
+ */
+ public static final UnicodeBlock THAI
+ = new UnicodeBlock(0x0E00, 0x0E7F,
+ "THAI",
+ "Thai");
+
+ /**
+ * Lao.
+ * 0x0E80 - 0x0EFF.
+ */
+ public static final UnicodeBlock LAO
+ = new UnicodeBlock(0x0E80, 0x0EFF,
+ "LAO",
+ "Lao");
+
+ /**
+ * Tibetan.
+ * 0x0F00 - 0x0FFF.
+ */
+ public static final UnicodeBlock TIBETAN
+ = new UnicodeBlock(0x0F00, 0x0FFF,
+ "TIBETAN",
+ "Tibetan");
+
+ /**
+ * Myanmar.
+ * 0x1000 - 0x109F.
+ * @since 1.4
+ */
+ public static final UnicodeBlock MYANMAR
+ = new UnicodeBlock(0x1000, 0x109F,
+ "MYANMAR",
+ "Myanmar");
+
+ /**
+ * Georgian.
+ * 0x10A0 - 0x10FF.
+ */
+ public static final UnicodeBlock GEORGIAN
+ = new UnicodeBlock(0x10A0, 0x10FF,
+ "GEORGIAN",
+ "Georgian");
+
+ /**
+ * Hangul Jamo.
+ * 0x1100 - 0x11FF.
+ */
+ public static final UnicodeBlock HANGUL_JAMO
+ = new UnicodeBlock(0x1100, 0x11FF,
+ "HANGUL_JAMO",
+ "Hangul Jamo");
+
+ /**
+ * Ethiopic.
+ * 0x1200 - 0x137F.
+ * @since 1.4
+ */
+ public static final UnicodeBlock ETHIOPIC
+ = new UnicodeBlock(0x1200, 0x137F,
+ "ETHIOPIC",
+ "Ethiopic");
+
+ /**
+ * Cherokee.
+ * 0x13A0 - 0x13FF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock CHEROKEE
+ = new UnicodeBlock(0x13A0, 0x13FF,
+ "CHEROKEE",
+ "Cherokee");
+
+ /**
+ * Unified Canadian Aboriginal Syllabics.
+ * 0x1400 - 0x167F.
+ * @since 1.4
+ */
+ public static final UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS
+ = new UnicodeBlock(0x1400, 0x167F,
+ "UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS",
+ "Unified Canadian Aboriginal Syllabics");
+
+ /**
+ * Ogham.
+ * 0x1680 - 0x169F.
+ * @since 1.4
+ */
+ public static final UnicodeBlock OGHAM
+ = new UnicodeBlock(0x1680, 0x169F,
+ "OGHAM",
+ "Ogham");
+
+ /**
+ * Runic.
+ * 0x16A0 - 0x16FF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock RUNIC
+ = new UnicodeBlock(0x16A0, 0x16FF,
+ "RUNIC",
+ "Runic");
+
+ /**
+ * Tagalog.
+ * 0x1700 - 0x171F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock TAGALOG
+ = new UnicodeBlock(0x1700, 0x171F,
+ "TAGALOG",
+ "Tagalog");
+
+ /**
+ * Hanunoo.
+ * 0x1720 - 0x173F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock HANUNOO
+ = new UnicodeBlock(0x1720, 0x173F,
+ "HANUNOO",
+ "Hanunoo");
+
+ /**
+ * Buhid.
+ * 0x1740 - 0x175F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock BUHID
+ = new UnicodeBlock(0x1740, 0x175F,
+ "BUHID",
+ "Buhid");
+
+ /**
+ * Tagbanwa.
+ * 0x1760 - 0x177F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock TAGBANWA
+ = new UnicodeBlock(0x1760, 0x177F,
+ "TAGBANWA",
+ "Tagbanwa");
+
+ /**
+ * Khmer.
+ * 0x1780 - 0x17FF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock KHMER
+ = new UnicodeBlock(0x1780, 0x17FF,
+ "KHMER",
+ "Khmer");
+
+ /**
+ * Mongolian.
+ * 0x1800 - 0x18AF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock MONGOLIAN
+ = new UnicodeBlock(0x1800, 0x18AF,
+ "MONGOLIAN",
+ "Mongolian");
+
+ /**
+ * Limbu.
+ * 0x1900 - 0x194F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock LIMBU
+ = new UnicodeBlock(0x1900, 0x194F,
+ "LIMBU",
+ "Limbu");
+
+ /**
+ * Tai Le.
+ * 0x1950 - 0x197F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock TAI_LE
+ = new UnicodeBlock(0x1950, 0x197F,
+ "TAI_LE",
+ "Tai Le");
+
+ /**
+ * Khmer Symbols.
+ * 0x19E0 - 0x19FF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock KHMER_SYMBOLS
+ = new UnicodeBlock(0x19E0, 0x19FF,
+ "KHMER_SYMBOLS",
+ "Khmer Symbols");
+
+ /**
+ * Phonetic Extensions.
+ * 0x1D00 - 0x1D7F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock PHONETIC_EXTENSIONS
+ = new UnicodeBlock(0x1D00, 0x1D7F,
+ "PHONETIC_EXTENSIONS",
+ "Phonetic Extensions");
+
+ /**
+ * Latin Extended Additional.
+ * 0x1E00 - 0x1EFF.
+ */
+ public static final UnicodeBlock LATIN_EXTENDED_ADDITIONAL
+ = new UnicodeBlock(0x1E00, 0x1EFF,
+ "LATIN_EXTENDED_ADDITIONAL",
+ "Latin Extended Additional");
+
+ /**
+ * Greek Extended.
+ * 0x1F00 - 0x1FFF.
+ */
+ public static final UnicodeBlock GREEK_EXTENDED
+ = new UnicodeBlock(0x1F00, 0x1FFF,
+ "GREEK_EXTENDED",
+ "Greek Extended");
+
+ /**
+ * General Punctuation.
+ * 0x2000 - 0x206F.
+ */
+ public static final UnicodeBlock GENERAL_PUNCTUATION
+ = new UnicodeBlock(0x2000, 0x206F,
+ "GENERAL_PUNCTUATION",
+ "General Punctuation");
+
+ /**
+ * Superscripts and Subscripts.
+ * 0x2070 - 0x209F.
+ */
+ public static final UnicodeBlock SUPERSCRIPTS_AND_SUBSCRIPTS
+ = new UnicodeBlock(0x2070, 0x209F,
+ "SUPERSCRIPTS_AND_SUBSCRIPTS",
+ "Superscripts and Subscripts");
+
+ /**
+ * Currency Symbols.
+ * 0x20A0 - 0x20CF.
+ */
+ public static final UnicodeBlock CURRENCY_SYMBOLS
+ = new UnicodeBlock(0x20A0, 0x20CF,
+ "CURRENCY_SYMBOLS",
+ "Currency Symbols");
+
+ /**
+ * Combining Marks for Symbols.
+ * 0x20D0 - 0x20FF.
+ */
+ public static final UnicodeBlock COMBINING_MARKS_FOR_SYMBOLS
+ = new UnicodeBlock(0x20D0, 0x20FF,
+ "COMBINING_MARKS_FOR_SYMBOLS",
+ "Combining Marks for Symbols");
+
+ /**
+ * Letterlike Symbols.
+ * 0x2100 - 0x214F.
+ */
+ public static final UnicodeBlock LETTERLIKE_SYMBOLS
+ = new UnicodeBlock(0x2100, 0x214F,
+ "LETTERLIKE_SYMBOLS",
+ "Letterlike Symbols");
+
+ /**
+ * Number Forms.
+ * 0x2150 - 0x218F.
+ */
+ public static final UnicodeBlock NUMBER_FORMS
+ = new UnicodeBlock(0x2150, 0x218F,
+ "NUMBER_FORMS",
+ "Number Forms");
+
+ /**
+ * Arrows.
+ * 0x2190 - 0x21FF.
+ */
+ public static final UnicodeBlock ARROWS
+ = new UnicodeBlock(0x2190, 0x21FF,
+ "ARROWS",
+ "Arrows");
+
+ /**
+ * Mathematical Operators.
+ * 0x2200 - 0x22FF.
+ */
+ public static final UnicodeBlock MATHEMATICAL_OPERATORS
+ = new UnicodeBlock(0x2200, 0x22FF,
+ "MATHEMATICAL_OPERATORS",
+ "Mathematical Operators");
+
+ /**
+ * Miscellaneous Technical.
+ * 0x2300 - 0x23FF.
+ */
+ public static final UnicodeBlock MISCELLANEOUS_TECHNICAL
+ = new UnicodeBlock(0x2300, 0x23FF,
+ "MISCELLANEOUS_TECHNICAL",
+ "Miscellaneous Technical");
+
+ /**
+ * Control Pictures.
+ * 0x2400 - 0x243F.
+ */
+ public static final UnicodeBlock CONTROL_PICTURES
+ = new UnicodeBlock(0x2400, 0x243F,
+ "CONTROL_PICTURES",
+ "Control Pictures");
+
+ /**
+ * Optical Character Recognition.
+ * 0x2440 - 0x245F.
+ */
+ public static final UnicodeBlock OPTICAL_CHARACTER_RECOGNITION
+ = new UnicodeBlock(0x2440, 0x245F,
+ "OPTICAL_CHARACTER_RECOGNITION",
+ "Optical Character Recognition");
+
+ /**
+ * Enclosed Alphanumerics.
+ * 0x2460 - 0x24FF.
+ */
+ public static final UnicodeBlock ENCLOSED_ALPHANUMERICS
+ = new UnicodeBlock(0x2460, 0x24FF,
+ "ENCLOSED_ALPHANUMERICS",
+ "Enclosed Alphanumerics");
+
+ /**
+ * Box Drawing.
+ * 0x2500 - 0x257F.
+ */
+ public static final UnicodeBlock BOX_DRAWING
+ = new UnicodeBlock(0x2500, 0x257F,
+ "BOX_DRAWING",
+ "Box Drawing");
+
+ /**
+ * Block Elements.
+ * 0x2580 - 0x259F.
+ */
+ public static final UnicodeBlock BLOCK_ELEMENTS
+ = new UnicodeBlock(0x2580, 0x259F,
+ "BLOCK_ELEMENTS",
+ "Block Elements");
+
+ /**
+ * Geometric Shapes.
+ * 0x25A0 - 0x25FF.
+ */
+ public static final UnicodeBlock GEOMETRIC_SHAPES
+ = new UnicodeBlock(0x25A0, 0x25FF,
+ "GEOMETRIC_SHAPES",
+ "Geometric Shapes");
+
+ /**
+ * Miscellaneous Symbols.
+ * 0x2600 - 0x26FF.
+ */
+ public static final UnicodeBlock MISCELLANEOUS_SYMBOLS
+ = new UnicodeBlock(0x2600, 0x26FF,
+ "MISCELLANEOUS_SYMBOLS",
+ "Miscellaneous Symbols");
+
+ /**
+ * Dingbats.
+ * 0x2700 - 0x27BF.
+ */
+ public static final UnicodeBlock DINGBATS
+ = new UnicodeBlock(0x2700, 0x27BF,
+ "DINGBATS",
+ "Dingbats");
+
+ /**
+ * Miscellaneous Mathematical Symbols-A.
+ * 0x27C0 - 0x27EF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A
+ = new UnicodeBlock(0x27C0, 0x27EF,
+ "MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A",
+ "Miscellaneous Mathematical Symbols-A");
+
+ /**
+ * Supplemental Arrows-A.
+ * 0x27F0 - 0x27FF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SUPPLEMENTAL_ARROWS_A
+ = new UnicodeBlock(0x27F0, 0x27FF,
+ "SUPPLEMENTAL_ARROWS_A",
+ "Supplemental Arrows-A");
+
+ /**
+ * Braille Patterns.
+ * 0x2800 - 0x28FF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock BRAILLE_PATTERNS
+ = new UnicodeBlock(0x2800, 0x28FF,
+ "BRAILLE_PATTERNS",
+ "Braille Patterns");
+
+ /**
+ * Supplemental Arrows-B.
+ * 0x2900 - 0x297F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SUPPLEMENTAL_ARROWS_B
+ = new UnicodeBlock(0x2900, 0x297F,
+ "SUPPLEMENTAL_ARROWS_B",
+ "Supplemental Arrows-B");
+
+ /**
+ * Miscellaneous Mathematical Symbols-B.
+ * 0x2980 - 0x29FF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B
+ = new UnicodeBlock(0x2980, 0x29FF,
+ "MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B",
+ "Miscellaneous Mathematical Symbols-B");
+
+ /**
+ * Supplemental Mathematical Operators.
+ * 0x2A00 - 0x2AFF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SUPPLEMENTAL_MATHEMATICAL_OPERATORS
+ = new UnicodeBlock(0x2A00, 0x2AFF,
+ "SUPPLEMENTAL_MATHEMATICAL_OPERATORS",
+ "Supplemental Mathematical Operators");
+
+ /**
+ * Miscellaneous Symbols and Arrows.
+ * 0x2B00 - 0x2BFF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_ARROWS
+ = new UnicodeBlock(0x2B00, 0x2BFF,
+ "MISCELLANEOUS_SYMBOLS_AND_ARROWS",
+ "Miscellaneous Symbols and Arrows");
+
+ /**
+ * CJK Radicals Supplement.
+ * 0x2E80 - 0x2EFF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock CJK_RADICALS_SUPPLEMENT
+ = new UnicodeBlock(0x2E80, 0x2EFF,
+ "CJK_RADICALS_SUPPLEMENT",
+ "CJK Radicals Supplement");
+
+ /**
+ * Kangxi Radicals.
+ * 0x2F00 - 0x2FDF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock KANGXI_RADICALS
+ = new UnicodeBlock(0x2F00, 0x2FDF,
+ "KANGXI_RADICALS",
+ "Kangxi Radicals");
+
+ /**
+ * Ideographic Description Characters.
+ * 0x2FF0 - 0x2FFF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock IDEOGRAPHIC_DESCRIPTION_CHARACTERS
+ = new UnicodeBlock(0x2FF0, 0x2FFF,
+ "IDEOGRAPHIC_DESCRIPTION_CHARACTERS",
+ "Ideographic Description Characters");
+
+ /**
+ * CJK Symbols and Punctuation.
+ * 0x3000 - 0x303F.
+ */
+ public static final UnicodeBlock CJK_SYMBOLS_AND_PUNCTUATION
+ = new UnicodeBlock(0x3000, 0x303F,
+ "CJK_SYMBOLS_AND_PUNCTUATION",
+ "CJK Symbols and Punctuation");
+
+ /**
+ * Hiragana.
+ * 0x3040 - 0x309F.
+ */
+ public static final UnicodeBlock HIRAGANA
+ = new UnicodeBlock(0x3040, 0x309F,
+ "HIRAGANA",
+ "Hiragana");
+
+ /**
+ * Katakana.
+ * 0x30A0 - 0x30FF.
+ */
+ public static final UnicodeBlock KATAKANA
+ = new UnicodeBlock(0x30A0, 0x30FF,
+ "KATAKANA",
+ "Katakana");
+
+ /**
+ * Bopomofo.
+ * 0x3100 - 0x312F.
+ */
+ public static final UnicodeBlock BOPOMOFO
+ = new UnicodeBlock(0x3100, 0x312F,
+ "BOPOMOFO",
+ "Bopomofo");
+
+ /**
+ * Hangul Compatibility Jamo.
+ * 0x3130 - 0x318F.
+ */
+ public static final UnicodeBlock HANGUL_COMPATIBILITY_JAMO
+ = new UnicodeBlock(0x3130, 0x318F,
+ "HANGUL_COMPATIBILITY_JAMO",
+ "Hangul Compatibility Jamo");
+
+ /**
+ * Kanbun.
+ * 0x3190 - 0x319F.
+ */
+ public static final UnicodeBlock KANBUN
+ = new UnicodeBlock(0x3190, 0x319F,
+ "KANBUN",
+ "Kanbun");
+
+ /**
+ * Bopomofo Extended.
+ * 0x31A0 - 0x31BF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock BOPOMOFO_EXTENDED
+ = new UnicodeBlock(0x31A0, 0x31BF,
+ "BOPOMOFO_EXTENDED",
+ "Bopomofo Extended");
+
+ /**
+ * Katakana Phonetic Extensions.
+ * 0x31F0 - 0x31FF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock KATAKANA_PHONETIC_EXTENSIONS
+ = new UnicodeBlock(0x31F0, 0x31FF,
+ "KATAKANA_PHONETIC_EXTENSIONS",
+ "Katakana Phonetic Extensions");
+
+ /**
+ * Enclosed CJK Letters and Months.
+ * 0x3200 - 0x32FF.
+ */
+ public static final UnicodeBlock ENCLOSED_CJK_LETTERS_AND_MONTHS
+ = new UnicodeBlock(0x3200, 0x32FF,
+ "ENCLOSED_CJK_LETTERS_AND_MONTHS",
+ "Enclosed CJK Letters and Months");
+
+ /**
+ * CJK Compatibility.
+ * 0x3300 - 0x33FF.
+ */
+ public static final UnicodeBlock CJK_COMPATIBILITY
+ = new UnicodeBlock(0x3300, 0x33FF,
+ "CJK_COMPATIBILITY",
+ "CJK Compatibility");
+
+ /**
+ * CJK Unified Ideographs Extension A.
+ * 0x3400 - 0x4DBF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
+ = new UnicodeBlock(0x3400, 0x4DBF,
+ "CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A",
+ "CJK Unified Ideographs Extension A");
+
+ /**
+ * Yijing Hexagram Symbols.
+ * 0x4DC0 - 0x4DFF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock YIJING_HEXAGRAM_SYMBOLS
+ = new UnicodeBlock(0x4DC0, 0x4DFF,
+ "YIJING_HEXAGRAM_SYMBOLS",
+ "Yijing Hexagram Symbols");
+
+ /**
+ * CJK Unified Ideographs.
+ * 0x4E00 - 0x9FFF.
+ */
+ public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS
+ = new UnicodeBlock(0x4E00, 0x9FFF,
+ "CJK_UNIFIED_IDEOGRAPHS",
+ "CJK Unified Ideographs");
+
+ /**
+ * Yi Syllables.
+ * 0xA000 - 0xA48F.
+ * @since 1.4
+ */
+ public static final UnicodeBlock YI_SYLLABLES
+ = new UnicodeBlock(0xA000, 0xA48F,
+ "YI_SYLLABLES",
+ "Yi Syllables");
+
+ /**
+ * Yi Radicals.
+ * 0xA490 - 0xA4CF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock YI_RADICALS
+ = new UnicodeBlock(0xA490, 0xA4CF,
+ "YI_RADICALS",
+ "Yi Radicals");
+
+ /**
+ * Hangul Syllables.
+ * 0xAC00 - 0xD7AF.
+ */
+ public static final UnicodeBlock HANGUL_SYLLABLES
+ = new UnicodeBlock(0xAC00, 0xD7AF,
+ "HANGUL_SYLLABLES",
+ "Hangul Syllables");
+
+ /**
+ * High Surrogates.
+ * 0xD800 - 0xDB7F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock HIGH_SURROGATES
+ = new UnicodeBlock(0xD800, 0xDB7F,
+ "HIGH_SURROGATES",
+ "High Surrogates");
+
+ /**
+ * High Private Use Surrogates.
+ * 0xDB80 - 0xDBFF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock HIGH_PRIVATE_USE_SURROGATES
+ = new UnicodeBlock(0xDB80, 0xDBFF,
+ "HIGH_PRIVATE_USE_SURROGATES",
+ "High Private Use Surrogates");
+
+ /**
+ * Low Surrogates.
+ * 0xDC00 - 0xDFFF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock LOW_SURROGATES
+ = new UnicodeBlock(0xDC00, 0xDFFF,
+ "LOW_SURROGATES",
+ "Low Surrogates");
+
+ /**
+ * Private Use Area.
+ * 0xE000 - 0xF8FF.
+ */
+ public static final UnicodeBlock PRIVATE_USE_AREA
+ = new UnicodeBlock(0xE000, 0xF8FF,
+ "PRIVATE_USE_AREA",
+ "Private Use Area");
+
+ /**
+ * CJK Compatibility Ideographs.
+ * 0xF900 - 0xFAFF.
+ */
+ public static final UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS
+ = new UnicodeBlock(0xF900, 0xFAFF,
+ "CJK_COMPATIBILITY_IDEOGRAPHS",
+ "CJK Compatibility Ideographs");
+
+ /**
+ * Alphabetic Presentation Forms.
+ * 0xFB00 - 0xFB4F.
+ */
+ public static final UnicodeBlock ALPHABETIC_PRESENTATION_FORMS
+ = new UnicodeBlock(0xFB00, 0xFB4F,
+ "ALPHABETIC_PRESENTATION_FORMS",
+ "Alphabetic Presentation Forms");
+
+ /**
+ * Arabic Presentation Forms-A.
+ * 0xFB50 - 0xFDFF.
+ */
+ public static final UnicodeBlock ARABIC_PRESENTATION_FORMS_A
+ = new UnicodeBlock(0xFB50, 0xFDFF,
+ "ARABIC_PRESENTATION_FORMS_A",
+ "Arabic Presentation Forms-A");
+
+ /**
+ * Variation Selectors.
+ * 0xFE00 - 0xFE0F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock VARIATION_SELECTORS
+ = new UnicodeBlock(0xFE00, 0xFE0F,
+ "VARIATION_SELECTORS",
+ "Variation Selectors");
+
+ /**
+ * Combining Half Marks.
+ * 0xFE20 - 0xFE2F.
+ */
+ public static final UnicodeBlock COMBINING_HALF_MARKS
+ = new UnicodeBlock(0xFE20, 0xFE2F,
+ "COMBINING_HALF_MARKS",
+ "Combining Half Marks");
+
+ /**
+ * CJK Compatibility Forms.
+ * 0xFE30 - 0xFE4F.
+ */
+ public static final UnicodeBlock CJK_COMPATIBILITY_FORMS
+ = new UnicodeBlock(0xFE30, 0xFE4F,
+ "CJK_COMPATIBILITY_FORMS",
+ "CJK Compatibility Forms");
+
+ /**
+ * Small Form Variants.
+ * 0xFE50 - 0xFE6F.
+ */
+ public static final UnicodeBlock SMALL_FORM_VARIANTS
+ = new UnicodeBlock(0xFE50, 0xFE6F,
+ "SMALL_FORM_VARIANTS",
+ "Small Form Variants");
+
+ /**
+ * Arabic Presentation Forms-B.
+ * 0xFE70 - 0xFEFF.
+ */
+ public static final UnicodeBlock ARABIC_PRESENTATION_FORMS_B
+ = new UnicodeBlock(0xFE70, 0xFEFF,
+ "ARABIC_PRESENTATION_FORMS_B",
+ "Arabic Presentation Forms-B");
+
+ /**
+ * Halfwidth and Fullwidth Forms.
+ * 0xFF00 - 0xFFEF.
+ */
+ public static final UnicodeBlock HALFWIDTH_AND_FULLWIDTH_FORMS
+ = new UnicodeBlock(0xFF00, 0xFFEF,
+ "HALFWIDTH_AND_FULLWIDTH_FORMS",
+ "Halfwidth and Fullwidth Forms");
+
+ /**
+ * Specials.
+ * 0xFFF0 - 0xFFFF.
+ */
+ public static final UnicodeBlock SPECIALS
+ = new UnicodeBlock(0xFFF0, 0xFFFF,
+ "SPECIALS",
+ "Specials");
+
+ /**
+ * Linear B Syllabary.
+ * 0x10000 - 0x1007F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock LINEAR_B_SYLLABARY
+ = new UnicodeBlock(0x10000, 0x1007F,
+ "LINEAR_B_SYLLABARY",
+ "Linear B Syllabary");
+
+ /**
+ * Linear B Ideograms.
+ * 0x10080 - 0x100FF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock LINEAR_B_IDEOGRAMS
+ = new UnicodeBlock(0x10080, 0x100FF,
+ "LINEAR_B_IDEOGRAMS",
+ "Linear B Ideograms");
+
+ /**
+ * Aegean Numbers.
+ * 0x10100 - 0x1013F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock AEGEAN_NUMBERS
+ = new UnicodeBlock(0x10100, 0x1013F,
+ "AEGEAN_NUMBERS",
+ "Aegean Numbers");
+
+ /**
+ * Old Italic.
+ * 0x10300 - 0x1032F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock OLD_ITALIC
+ = new UnicodeBlock(0x10300, 0x1032F,
+ "OLD_ITALIC",
+ "Old Italic");
+
+ /**
+ * Gothic.
+ * 0x10330 - 0x1034F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock GOTHIC
+ = new UnicodeBlock(0x10330, 0x1034F,
+ "GOTHIC",
+ "Gothic");
+
+ /**
+ * Ugaritic.
+ * 0x10380 - 0x1039F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock UGARITIC
+ = new UnicodeBlock(0x10380, 0x1039F,
+ "UGARITIC",
+ "Ugaritic");
+
+ /**
+ * Deseret.
+ * 0x10400 - 0x1044F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock DESERET
+ = new UnicodeBlock(0x10400, 0x1044F,
+ "DESERET",
+ "Deseret");
+
+ /**
+ * Shavian.
+ * 0x10450 - 0x1047F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SHAVIAN
+ = new UnicodeBlock(0x10450, 0x1047F,
+ "SHAVIAN",
+ "Shavian");
+
+ /**
+ * Osmanya.
+ * 0x10480 - 0x104AF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock OSMANYA
+ = new UnicodeBlock(0x10480, 0x104AF,
+ "OSMANYA",
+ "Osmanya");
+
+ /**
+ * Cypriot Syllabary.
+ * 0x10800 - 0x1083F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock CYPRIOT_SYLLABARY
+ = new UnicodeBlock(0x10800, 0x1083F,
+ "CYPRIOT_SYLLABARY",
+ "Cypriot Syllabary");
+
+ /**
+ * Byzantine Musical Symbols.
+ * 0x1D000 - 0x1D0FF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock BYZANTINE_MUSICAL_SYMBOLS
+ = new UnicodeBlock(0x1D000, 0x1D0FF,
+ "BYZANTINE_MUSICAL_SYMBOLS",
+ "Byzantine Musical Symbols");
+
+ /**
+ * Musical Symbols.
+ * 0x1D100 - 0x1D1FF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock MUSICAL_SYMBOLS
+ = new UnicodeBlock(0x1D100, 0x1D1FF,
+ "MUSICAL_SYMBOLS",
+ "Musical Symbols");
+
+ /**
+ * Tai Xuan Jing Symbols.
+ * 0x1D300 - 0x1D35F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock TAI_XUAN_JING_SYMBOLS
+ = new UnicodeBlock(0x1D300, 0x1D35F,
+ "TAI_XUAN_JING_SYMBOLS",
+ "Tai Xuan Jing Symbols");
+
+ /**
+ * Mathematical Alphanumeric Symbols.
+ * 0x1D400 - 0x1D7FF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock MATHEMATICAL_ALPHANUMERIC_SYMBOLS
+ = new UnicodeBlock(0x1D400, 0x1D7FF,
+ "MATHEMATICAL_ALPHANUMERIC_SYMBOLS",
+ "Mathematical Alphanumeric Symbols");
+
+ /**
+ * CJK Unified Ideographs Extension B.
+ * 0x20000 - 0x2A6DF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
+ = new UnicodeBlock(0x20000, 0x2A6DF,
+ "CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B",
+ "CJK Unified Ideographs Extension B");
+
+ /**
+ * CJK Compatibility Ideographs Supplement.
+ * 0x2F800 - 0x2FA1F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT
+ = new UnicodeBlock(0x2F800, 0x2FA1F,
+ "CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT",
+ "CJK Compatibility Ideographs Supplement");
+
+ /**
+ * Tags.
+ * 0xE0000 - 0xE007F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock TAGS
+ = new UnicodeBlock(0xE0000, 0xE007F,
+ "TAGS",
+ "Tags");
+
+ /**
+ * Variation Selectors Supplement.
+ * 0xE0100 - 0xE01EF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock VARIATION_SELECTORS_SUPPLEMENT
+ = new UnicodeBlock(0xE0100, 0xE01EF,
+ "VARIATION_SELECTORS_SUPPLEMENT",
+ "Variation Selectors Supplement");
+
+ /**
+ * Supplementary Private Use Area-A.
+ * 0xF0000 - 0xFFFFF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_A
+ = new UnicodeBlock(0xF0000, 0xFFFFF,
+ "SUPPLEMENTARY_PRIVATE_USE_AREA_A",
+ "Supplementary Private Use Area-A");
+
+ /**
+ * Supplementary Private Use Area-B.
+ * 0x100000 - 0x10FFFF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_B
+ = new UnicodeBlock(0x100000, 0x10FFFF,
+ "SUPPLEMENTARY_PRIVATE_USE_AREA_B",
+ "Supplementary Private Use Area-B");
+
+ /**
+ * Surrogates Area.
+ * 'D800' - 'DFFF'.
+ * @deprecated As of 1.5, the three areas,
+ * <a href="#HIGH_SURROGATES">HIGH_SURROGATES</a>,
+ * <a href="#HIGH_PRIVATE_USE_SURROGATES">HIGH_PRIVATE_USE_SURROGATES</a>
+ * and <a href="#LOW_SURROGATES">LOW_SURROGATES</a>, as defined
+ * by the Unicode standard, should be used in preference to
+ * this. These are also returned from calls to <code>of(int)</code>
+ * and <code>of(char)</code>.
+ */
+ @Deprecated
+ public static final UnicodeBlock SURROGATES_AREA
+ = new UnicodeBlock(0xD800, 0xDFFF,
+ "SURROGATES_AREA",
+ "Surrogates Area");
+
+ /**
+ * The defined subsets.
+ */
+ private static final UnicodeBlock sets[] = {
+ BASIC_LATIN,
+ LATIN_1_SUPPLEMENT,
+ LATIN_EXTENDED_A,
+ LATIN_EXTENDED_B,
+ IPA_EXTENSIONS,
+ SPACING_MODIFIER_LETTERS,
+ COMBINING_DIACRITICAL_MARKS,
+ GREEK,
+ CYRILLIC,
+ CYRILLIC_SUPPLEMENTARY,
+ ARMENIAN,
+ HEBREW,
+ ARABIC,
+ SYRIAC,
+ THAANA,
+ DEVANAGARI,
+ BENGALI,
+ GURMUKHI,
+ GUJARATI,
+ ORIYA,
+ TAMIL,
+ TELUGU,
+ KANNADA,
+ MALAYALAM,
+ SINHALA,
+ THAI,
+ LAO,
+ TIBETAN,
+ MYANMAR,
+ GEORGIAN,
+ HANGUL_JAMO,
+ ETHIOPIC,
+ CHEROKEE,
+ UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS,
+ OGHAM,
+ RUNIC,
+ TAGALOG,
+ HANUNOO,
+ BUHID,
+ TAGBANWA,
+ KHMER,
+ MONGOLIAN,
+ LIMBU,
+ TAI_LE,
+ KHMER_SYMBOLS,
+ PHONETIC_EXTENSIONS,
+ LATIN_EXTENDED_ADDITIONAL,
+ GREEK_EXTENDED,
+ GENERAL_PUNCTUATION,
+ SUPERSCRIPTS_AND_SUBSCRIPTS,
+ CURRENCY_SYMBOLS,
+ COMBINING_MARKS_FOR_SYMBOLS,
+ LETTERLIKE_SYMBOLS,
+ NUMBER_FORMS,
+ ARROWS,
+ MATHEMATICAL_OPERATORS,
+ MISCELLANEOUS_TECHNICAL,
+ CONTROL_PICTURES,
+ OPTICAL_CHARACTER_RECOGNITION,
+ ENCLOSED_ALPHANUMERICS,
+ BOX_DRAWING,
+ BLOCK_ELEMENTS,
+ GEOMETRIC_SHAPES,
+ MISCELLANEOUS_SYMBOLS,
+ DINGBATS,
+ MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A,
+ SUPPLEMENTAL_ARROWS_A,
+ BRAILLE_PATTERNS,
+ SUPPLEMENTAL_ARROWS_B,
+ MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B,
+ SUPPLEMENTAL_MATHEMATICAL_OPERATORS,
+ MISCELLANEOUS_SYMBOLS_AND_ARROWS,
+ CJK_RADICALS_SUPPLEMENT,
+ KANGXI_RADICALS,
+ IDEOGRAPHIC_DESCRIPTION_CHARACTERS,
+ CJK_SYMBOLS_AND_PUNCTUATION,
+ HIRAGANA,
+ KATAKANA,
+ BOPOMOFO,
+ HANGUL_COMPATIBILITY_JAMO,
+ KANBUN,
+ BOPOMOFO_EXTENDED,
+ KATAKANA_PHONETIC_EXTENSIONS,
+ ENCLOSED_CJK_LETTERS_AND_MONTHS,
+ CJK_COMPATIBILITY,
+ CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A,
+ YIJING_HEXAGRAM_SYMBOLS,
+ CJK_UNIFIED_IDEOGRAPHS,
+ YI_SYLLABLES,
+ YI_RADICALS,
+ HANGUL_SYLLABLES,
+ HIGH_SURROGATES,
+ HIGH_PRIVATE_USE_SURROGATES,
+ LOW_SURROGATES,
+ PRIVATE_USE_AREA,
+ CJK_COMPATIBILITY_IDEOGRAPHS,
+ ALPHABETIC_PRESENTATION_FORMS,
+ ARABIC_PRESENTATION_FORMS_A,
+ VARIATION_SELECTORS,
+ COMBINING_HALF_MARKS,
+ CJK_COMPATIBILITY_FORMS,
+ SMALL_FORM_VARIANTS,
+ ARABIC_PRESENTATION_FORMS_B,
+ HALFWIDTH_AND_FULLWIDTH_FORMS,
+ SPECIALS,
+ LINEAR_B_SYLLABARY,
+ LINEAR_B_IDEOGRAMS,
+ AEGEAN_NUMBERS,
+ OLD_ITALIC,
+ GOTHIC,
+ UGARITIC,
+ DESERET,
+ SHAVIAN,
+ OSMANYA,
+ CYPRIOT_SYLLABARY,
+ BYZANTINE_MUSICAL_SYMBOLS,
+ MUSICAL_SYMBOLS,
+ TAI_XUAN_JING_SYMBOLS,
+ MATHEMATICAL_ALPHANUMERIC_SYMBOLS,
+ CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B,
+ CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT,
+ TAGS,
+ VARIATION_SELECTORS_SUPPLEMENT,
+ SUPPLEMENTARY_PRIVATE_USE_AREA_A,
+ SUPPLEMENTARY_PRIVATE_USE_AREA_B,
+ };
+ } // class UnicodeBlock
+
+ /**
+ * The immutable value of this Character.
+ *
+ * @serial the value of this Character
+ */
+ private final char value;
+
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = 3786198910865385080L;
+
+ /**
+ * Smallest value allowed for radix arguments in Java. This value is 2.
+ *
+ * @see #digit(char, int)
+ * @see #forDigit(int, int)
+ * @see Integer#toString(int, int)
+ * @see Integer#valueOf(String)
+ */
+ public static final int MIN_RADIX = 2;
+
+ /**
+ * Largest value allowed for radix arguments in Java. This value is 36.
+ *
+ * @see #digit(char, int)
+ * @see #forDigit(int, int)
+ * @see Integer#toString(int, int)
+ * @see Integer#valueOf(String)
+ */
+ public static final int MAX_RADIX = 36;
+
+ /**
+ * The minimum value the char data type can hold.
+ * This value is <code>'\\u0000'</code>.
+ */
+ public static final char MIN_VALUE = '\u0000';
+
+ /**
+ * The maximum value the char data type can hold.
+ * This value is <code>'\\uFFFF'</code>.
+ */
+ public static final char MAX_VALUE = '\uFFFF';
+
+ /**
+ * The minimum Unicode 4.0 code point. This value is <code>0</code>.
+ * @since 1.5
+ */
+ public static final int MIN_CODE_POINT = 0;
+
+ /**
+ * The maximum Unicode 4.0 code point, which is greater than the range
+ * of the char data type.
+ * This value is <code>0x10FFFF</code>.
+ * @since 1.5
+ */
+ public static final int MAX_CODE_POINT = 0x10FFFF;
+
+ /**
+ * The minimum Unicode high surrogate code unit, or
+ * <emph>leading-surrogate</emph>, in the UTF-16 character encoding.
+ * This value is <code>'\uD800'</code>.
+ * @since 1.5
+ */
+ public static final char MIN_HIGH_SURROGATE = '\uD800';
+
+ /**
+ * The maximum Unicode high surrogate code unit, or
+ * <emph>leading-surrogate</emph>, in the UTF-16 character encoding.
+ * This value is <code>'\uDBFF'</code>.
+ * @since 1.5
+ */
+ public static final char MAX_HIGH_SURROGATE = '\uDBFF';
+
+ /**
+ * The minimum Unicode low surrogate code unit, or
+ * <emph>trailing-surrogate</emph>, in the UTF-16 character encoding.
+ * This value is <code>'\uDC00'</code>.
+ * @since 1.5
+ */
+ public static final char MIN_LOW_SURROGATE = '\uDC00';
+
+ /**
+ * The maximum Unicode low surrogate code unit, or
+ * <emph>trailing-surrogate</emph>, in the UTF-16 character encoding.
+ * This value is <code>'\uDFFF'</code>.
+ * @since 1.5
+ */
+ public static final char MAX_LOW_SURROGATE = '\uDFFF';
+
+ /**
+ * The minimum Unicode surrogate code unit in the UTF-16 character encoding.
+ * This value is <code>'\uD800'</code>.
+ * @since 1.5
+ */
+ public static final char MIN_SURROGATE = MIN_HIGH_SURROGATE;
+
+ /**
+ * The maximum Unicode surrogate code unit in the UTF-16 character encoding.
+ * This value is <code>'\uDFFF'</code>.
+ * @since 1.5
+ */
+ public static final char MAX_SURROGATE = MAX_LOW_SURROGATE;
+
+ /**
+ * The lowest possible supplementary Unicode code point (the first code
+ * point outside the basic multilingual plane (BMP)).
+ * This value is <code>0x10000</code>.
+ */
+ public static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x10000;
+
+ /**
+ * Class object representing the primitive char data type.
+ *
+ * @since 1.1
+ */
+ public static final Class<Character> TYPE = (Class<Character>) VMClassLoader.getPrimitiveClass('C');
+
+ /**
+ * The number of bits needed to represent a <code>char</code>.
+ * @since 1.5
+ */
+ public static final int SIZE = 16;
+
+ // This caches some Character values, and is used by boxing
+ // conversions via valueOf(). We must cache at least 0..127;
+ // this constant controls how much we actually cache.
+ private static final int MAX_CACHE = 127;
+ private static Character[] charCache = new Character[MAX_CACHE + 1];
+
+ /**
+ * Lu = Letter, Uppercase (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte UPPERCASE_LETTER = 1;
+
+ /**
+ * Ll = Letter, Lowercase (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte LOWERCASE_LETTER = 2;
+
+ /**
+ * Lt = Letter, Titlecase (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte TITLECASE_LETTER = 3;
+
+ /**
+ * Mn = Mark, Non-Spacing (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte NON_SPACING_MARK = 6;
+
+ /**
+ * Mc = Mark, Spacing Combining (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte COMBINING_SPACING_MARK = 8;
+
+ /**
+ * Me = Mark, Enclosing (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte ENCLOSING_MARK = 7;
+
+ /**
+ * Nd = Number, Decimal Digit (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte DECIMAL_DIGIT_NUMBER = 9;
+
+ /**
+ * Nl = Number, Letter (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte LETTER_NUMBER = 10;
+
+ /**
+ * No = Number, Other (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte OTHER_NUMBER = 11;
+
+ /**
+ * Zs = Separator, Space (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte SPACE_SEPARATOR = 12;
+
+ /**
+ * Zl = Separator, Line (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte LINE_SEPARATOR = 13;
+
+ /**
+ * Zp = Separator, Paragraph (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte PARAGRAPH_SEPARATOR = 14;
+
+ /**
+ * Cc = Other, Control (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte CONTROL = 15;
+
+ /**
+ * Cf = Other, Format (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte FORMAT = 16;
+
+ /**
+ * Cs = Other, Surrogate (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte SURROGATE = 19;
+
+ /**
+ * Co = Other, Private Use (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte PRIVATE_USE = 18;
+
+ /**
+ * Cn = Other, Not Assigned (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte UNASSIGNED = 0;
+
+ /**
+ * Lm = Letter, Modifier (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte MODIFIER_LETTER = 4;
+
+ /**
+ * Lo = Letter, Other (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte OTHER_LETTER = 5;
+
+ /**
+ * Pc = Punctuation, Connector (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte CONNECTOR_PUNCTUATION = 23;
+
+ /**
+ * Pd = Punctuation, Dash (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte DASH_PUNCTUATION = 20;
+
+ /**
+ * Ps = Punctuation, Open (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte START_PUNCTUATION = 21;
+
+ /**
+ * Pe = Punctuation, Close (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte END_PUNCTUATION = 22;
+
+ /**
+ * Pi = Punctuation, Initial Quote (Informative).
+ *
+ * @since 1.4
+ */
+ public static final byte INITIAL_QUOTE_PUNCTUATION = 29;
+
+ /**
+ * Pf = Punctuation, Final Quote (Informative).
+ *
+ * @since 1.4
+ */
+ public static final byte FINAL_QUOTE_PUNCTUATION = 30;
+
+ /**
+ * Po = Punctuation, Other (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte OTHER_PUNCTUATION = 24;
+
+ /**
+ * Sm = Symbol, Math (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte MATH_SYMBOL = 25;
+
+ /**
+ * Sc = Symbol, Currency (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte CURRENCY_SYMBOL = 26;
+
+ /**
+ * Sk = Symbol, Modifier (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte MODIFIER_SYMBOL = 27;
+
+ /**
+ * So = Symbol, Other (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte OTHER_SYMBOL = 28;
+
+ /**
+ * Undefined bidirectional character type. Undefined char values have
+ * undefined directionality in the Unicode specification.
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_UNDEFINED = -1;
+
+ /**
+ * Strong bidirectional character type "L".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_LEFT_TO_RIGHT = 0;
+
+ /**
+ * Strong bidirectional character type "R".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_RIGHT_TO_LEFT = 1;
+
+ /**
+ * Strong bidirectional character type "AL".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC = 2;
+
+ /**
+ * Weak bidirectional character type "EN".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_EUROPEAN_NUMBER = 3;
+
+ /**
+ * Weak bidirectional character type "ES".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR = 4;
+
+ /**
+ * Weak bidirectional character type "ET".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR = 5;
+
+ /**
+ * Weak bidirectional character type "AN".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_ARABIC_NUMBER = 6;
+
+ /**
+ * Weak bidirectional character type "CS".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_COMMON_NUMBER_SEPARATOR = 7;
+
+ /**
+ * Weak bidirectional character type "NSM".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_NONSPACING_MARK = 8;
+
+ /**
+ * Weak bidirectional character type "BN".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_BOUNDARY_NEUTRAL = 9;
+
+ /**
+ * Neutral bidirectional character type "B".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_PARAGRAPH_SEPARATOR = 10;
+
+ /**
+ * Neutral bidirectional character type "S".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_SEGMENT_SEPARATOR = 11;
+
+ /**
+ * Strong bidirectional character type "WS".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_WHITESPACE = 12;
+
+ /**
+ * Neutral bidirectional character type "ON".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_OTHER_NEUTRALS = 13;
+
+ /**
+ * Strong bidirectional character type "LRE".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING = 14;
+
+ /**
+ * Strong bidirectional character type "LRO".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE = 15;
+
+ /**
+ * Strong bidirectional character type "RLE".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING = 16;
+
+ /**
+ * Strong bidirectional character type "RLO".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE = 17;
+
+ /**
+ * Weak bidirectional character type "PDF".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18;
+
+ /**
+ * Mask for grabbing the type out of the result of readChar.
+ * @see #readChar(char)
+ */
+ private static final int TYPE_MASK = 0x1F;
+
+ /**
+ * Mask for grabbing the non-breaking space flag out of the result of
+ * readChar.
+ * @see #readChar(char)
+ */
+ private static final int NO_BREAK_MASK = 0x20;
+
+ /**
+ * Mask for grabbing the mirrored directionality flag out of the result
+ * of readChar.
+ * @see #readChar(char)
+ */
+ private static final int MIRROR_MASK = 0x40;
+
+ /**
+ * Grabs an attribute offset from the Unicode attribute database. The lower
+ * 5 bits are the character type, the next 2 bits are flags, and the top
+ * 9 bits are the offset into the attribute tables. Note that the top 9
+ * bits are meaningless in this context; they are useful only in the native
+ * code.
+ *
+ * @param ch the character to look up
+ * @return the character's attribute offset and type
+ * @see #TYPE_MASK
+ * @see #NO_BREAK_MASK
+ * @see #MIRROR_MASK
+ */
+ private static native char readChar(char ch);
+
+ /**
+ * Grabs an attribute offset from the Unicode attribute database. The lower
+ * 5 bits are the character type, the next 2 bits are flags, and the top
+ * 9 bits are the offset into the attribute tables. Note that the top 9
+ * bits are meaningless in this context; they are useful only in the native
+ * code.
+ *
+ * @param codePoint the character to look up
+ * @return the character's attribute offset and type
+ * @see #TYPE_MASK
+ * @see #NO_BREAK_MASK
+ * @see #MIRROR_MASK
+ */
+ private static native char readCodePoint(int codePoint);
+
+ /**
+ * Wraps up a character.
+ *
+ * @param value the character to wrap
+ */
+ public Character(char value)
+ {
+ this.value = value;
+ }
+
+ /**
+ * Returns the character which has been wrapped by this class.
+ *
+ * @return the character wrapped
+ */
+ public char charValue()
+ {
+ return value;
+ }
+
+ /**
+ * Returns the numerical value (unsigned) of the wrapped character.
+ * Range of returned values: 0x0000-0xFFFF.
+ *
+ * @return the value of the wrapped character
+ */
+ public int hashCode()
+ {
+ return value;
+ }
+
+ /**
+ * Determines if an object is equal to this object. This is only true for
+ * another Character object wrapping the same value.
+ *
+ * @param o object to compare
+ * @return true if o is a Character with the same value
+ */
+ public boolean equals(Object o)
+ {
+ return o instanceof Character && value == ((Character) o).value;
+ }
+
+ /**
+ * Converts the wrapped character into a String.
+ *
+ * @return a String containing one character -- the wrapped character
+ * of this instance
+ */
+ public String toString()
+ {
+ // This assumes that String.valueOf(char) can create a single-character
+ // String more efficiently than through the public API.
+ return String.valueOf(value);
+ }
+
+ /**
+ * Returns a String of length 1 representing the specified character.
+ *
+ * @param ch the character to convert
+ * @return a String containing the character
+ * @since 1.4
+ */
+ public static String toString(char ch)
+ {
+ // This assumes that String.valueOf(char) can create a single-character
+ // String more efficiently than through the public API.
+ return String.valueOf(ch);
+ }
+
+ /**
+ * Determines if a character is a Unicode lowercase letter. For example,
+ * <code>'a'</code> is lowercase.
+ * <br>
+ * lowercase = [Ll]
+ *
+ * @param ch character to test
+ * @return true if ch is a Unicode lowercase letter, else false
+ * @see #isUpperCase(char)
+ * @see #isTitleCase(char)
+ * @see #toLowerCase(char)
+ * @see #getType(char)
+ */
+ public static boolean isLowerCase(char ch)
+ {
+ return getType(ch) == LOWERCASE_LETTER;
+ }
+
+ /**
+ * Determines if a character is a Unicode lowercase letter. For example,
+ * <code>'a'</code> is lowercase. Unlike isLowerCase(char), this method
+ * supports supplementary Unicode code points.
+ * <br>
+ * lowercase = [Ll]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is a Unicode lowercase letter, else false
+ * @see #isUpperCase(int)
+ * @see #isTitleCase(int)
+ * @see #toLowerCase(int)
+ * @see #getType(int)
+ * @since 1.5
+ */
+ public static boolean isLowerCase(int codePoint)
+ {
+ return getType(codePoint) == LOWERCASE_LETTER;
+ }
+
+ /**
+ * Determines if a character is a Unicode uppercase letter. For example,
+ * <code>'A'</code> is uppercase.
+ * <br>
+ * uppercase = [Lu]
+ *
+ * @param ch character to test
+ * @return true if ch is a Unicode uppercase letter, else false
+ * @see #isLowerCase(char)
+ * @see #isTitleCase(char)
+ * @see #toUpperCase(char)
+ * @see #getType(char)
+ */
+ public static boolean isUpperCase(char ch)
+ {
+ return getType(ch) == UPPERCASE_LETTER;
+ }
+
+ /**
+ * Determines if a character is a Unicode uppercase letter. For example,
+ * <code>'A'</code> is uppercase. Unlike isUpperCase(char), this method
+ * supports supplementary Unicode code points.
+ * <br>
+ * uppercase = [Lu]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is a Unicode uppercase letter, else false
+ * @see #isLowerCase(int)
+ * @see #isTitleCase(int)
+ * @see #toUpperCase(int)
+ * @see #getType(int)
+ * @since 1.5
+ */
+ public static boolean isUpperCase(int codePoint)
+ {
+ return getType(codePoint) == UPPERCASE_LETTER;
+ }
+
+ /**
+ * Determines if a character is a Unicode titlecase letter. For example,
+ * the character "Lj" (Latin capital L with small letter j) is titlecase.
+ * <br>
+ * titlecase = [Lt]
+ *
+ * @param ch character to test
+ * @return true if ch is a Unicode titlecase letter, else false
+ * @see #isLowerCase(char)
+ * @see #isUpperCase(char)
+ * @see #toTitleCase(char)
+ * @see #getType(char)
+ */
+ public static boolean isTitleCase(char ch)
+ {
+ return getType(ch) == TITLECASE_LETTER;
+ }
+
+ /**
+ * Determines if a character is a Unicode titlecase letter. For example,
+ * the character "Lj" (Latin capital L with small letter j) is titlecase.
+ * Unlike isTitleCase(char), this method supports supplementary Unicode
+ * code points.
+ * <br>
+ * titlecase = [Lt]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is a Unicode titlecase letter, else false
+ * @see #isLowerCase(int)
+ * @see #isUpperCase(int)
+ * @see #toTitleCase(int)
+ * @see #getType(int)
+ * @since 1.5
+ */
+ public static boolean isTitleCase(int codePoint)
+ {
+ return getType(codePoint) == TITLECASE_LETTER;
+ }
+
+ /**
+ * Determines if a character is a Unicode decimal digit. For example,
+ * <code>'0'</code> is a digit.
+ * <br>
+ * Unicode decimal digit = [Nd]
+ *
+ * @param ch character to test
+ * @return true if ch is a Unicode decimal digit, else false
+ * @see #digit(char, int)
+ * @see #forDigit(int, int)
+ * @see #getType(char)
+ */
+ public static boolean isDigit(char ch)
+ {
+ return getType(ch) == DECIMAL_DIGIT_NUMBER;
+ }
+
+ /**
+ * Determines if a character is a Unicode decimal digit. For example,
+ * <code>'0'</code> is a digit. Unlike isDigit(char), this method
+ * supports supplementary Unicode code points.
+ * <br>
+ * Unicode decimal digit = [Nd]
+ *
+ * @param codePoint character to test
+ * @return true if ccodePoint is a Unicode decimal digit, else false
+ * @see #digit(int, int)
+ * @see #forDigit(int, int)
+ * @see #getType(int)
+ * @since 1.5
+ */
+ public static boolean isDigit(int codePoint)
+ {
+ return getType(codePoint) == DECIMAL_DIGIT_NUMBER;
+ }
+
+ /**
+ * Determines if a character is part of the Unicode Standard. This is an
+ * evolving standard, but covers every character in the data file.
+ * <br>
+ * defined = not [Cn]
+ *
+ * @param ch character to test
+ * @return true if ch is a Unicode character, else false
+ * @see #isDigit(char)
+ * @see #isLetter(char)
+ * @see #isLetterOrDigit(char)
+ * @see #isLowerCase(char)
+ * @see #isTitleCase(char)
+ * @see #isUpperCase(char)
+ */
+ public static boolean isDefined(char ch)
+ {
+ return getType(ch) != UNASSIGNED;
+ }
+
+ /**
+ * Determines if a character is part of the Unicode Standard. This is an
+ * evolving standard, but covers every character in the data file. Unlike
+ * isDefined(char), this method supports supplementary Unicode code points.
+ * <br>
+ * defined = not [Cn]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is a Unicode character, else false
+ * @see #isDigit(int)
+ * @see #isLetter(int)
+ * @see #isLetterOrDigit(int)
+ * @see #isLowerCase(int)
+ * @see #isTitleCase(int)
+ * @see #isUpperCase(int)
+ * @since 1.5
+ */
+ public static boolean isDefined(int codePoint)
+ {
+ return getType(codePoint) != UNASSIGNED;
+ }
+
+ /**
+ * Determines if a character is a Unicode letter. Not all letters have case,
+ * so this may return true when isLowerCase and isUpperCase return false.
+ * <br>
+ * letter = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]
+ *
+ * @param ch character to test
+ * @return true if ch is a Unicode letter, else false
+ * @see #isDigit(char)
+ * @see #isJavaIdentifierStart(char)
+ * @see #isJavaLetter(char)
+ * @see #isJavaLetterOrDigit(char)
+ * @see #isLetterOrDigit(char)
+ * @see #isLowerCase(char)
+ * @see #isTitleCase(char)
+ * @see #isUnicodeIdentifierStart(char)
+ * @see #isUpperCase(char)
+ */
+ public static boolean isLetter(char ch)
+ {
+ return ((1 << getType(ch))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER))) != 0;
+ }
+
+ /**
+ * Determines if a character is a Unicode letter. Not all letters have case,
+ * so this may return true when isLowerCase and isUpperCase return false.
+ * Unlike isLetter(char), this method supports supplementary Unicode code
+ * points.
+ * <br>
+ * letter = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is a Unicode letter, else false
+ * @see #isDigit(int)
+ * @see #isJavaIdentifierStart(int)
+ * @see #isJavaLetter(int)
+ * @see #isJavaLetterOrDigit(int)
+ * @see #isLetterOrDigit(int)
+ * @see #isLowerCase(int)
+ * @see #isTitleCase(int)
+ * @see #isUnicodeIdentifierStart(int)
+ * @see #isUpperCase(int)
+ * @since 1.5
+ */
+ public static boolean isLetter(int codePoint)
+ {
+ return ((1 << getType(codePoint))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER))) != 0;
+ }
+
+ /**
+ * Returns the index into the given CharSequence that is offset
+ * <code>codePointOffset</code> code points from <code>index</code>.
+ * @param seq the CharSequence
+ * @param index the start position in the CharSequence
+ * @param codePointOffset the number of code points offset from the start
+ * position
+ * @return the index into the CharSequence that is codePointOffset code
+ * points offset from index
+ *
+ * @throws NullPointerException if seq is null
+ * @throws IndexOutOfBoundsException if index is negative or greater than the
+ * length of the sequence.
+ * @throws IndexOutOfBoundsException if codePointOffset is positive and the
+ * subsequence from index to the end of seq has fewer than codePointOffset
+ * code points
+ * @throws IndexOutOfBoundsException if codePointOffset is negative and the
+ * subsequence from the start of seq to index has fewer than
+ * (-codePointOffset) code points
+ * @since 1.5
+ */
+ public static int offsetByCodePoints(CharSequence seq,
+ int index,
+ int codePointOffset)
+ {
+ int len = seq.length();
+ if (index < 0 || index > len)
+ throw new IndexOutOfBoundsException();
+
+ int numToGo = codePointOffset;
+ int offset = index;
+ int adjust = 1;
+ if (numToGo >= 0)
+ {
+ for (; numToGo > 0; offset++)
+ {
+ numToGo--;
+ if (Character.isHighSurrogate(seq.charAt(offset))
+ && (offset + 1) < len
+ && Character.isLowSurrogate(seq.charAt(offset + 1)))
+ offset++;
+ }
+ return offset;
+ }
+ else
+ {
+ numToGo *= -1;
+ for (; numToGo > 0;)
+ {
+ numToGo--;
+ offset--;
+ if (Character.isLowSurrogate(seq.charAt(offset))
+ && (offset - 1) >= 0
+ && Character.isHighSurrogate(seq.charAt(offset - 1)))
+ offset--;
+ }
+ return offset;
+ }
+ }
+
+ /**
+ * Returns the index into the given char subarray that is offset
+ * <code>codePointOffset</code> code points from <code>index</code>.
+ * @param a the char array
+ * @param start the start index of the subarray
+ * @param count the length of the subarray
+ * @param index the index to be offset
+ * @param codePointOffset the number of code points offset from <code>index
+ * </code>
+ * @return the index into the char array
+ *
+ * @throws NullPointerException if a is null
+ * @throws IndexOutOfBoundsException if start or count is negative or if
+ * start + count is greater than the length of the array
+ * @throws IndexOutOfBoundsException if index is less than start or larger
+ * than start + count
+ * @throws IndexOutOfBoundsException if codePointOffset is positive and the
+ * subarray from index to start + count - 1 has fewer than codePointOffset
+ * code points.
+ * @throws IndexOutOfBoundsException if codePointOffset is negative and the
+ * subarray from start to index - 1 has fewer than (-codePointOffset) code
+ * points
+ * @since 1.5
+
+ */
+ public static int offsetByCodePoints(char[] a,
+ int start,
+ int count,
+ int index,
+ int codePointOffset)
+ {
+ int len = a.length;
+ int end = start + count;
+ if (start < 0 || count < 0 || end > len || index < start || index > end)
+ throw new IndexOutOfBoundsException();
+
+ int numToGo = codePointOffset;
+ int offset = index;
+ int adjust = 1;
+ if (numToGo >= 0)
+ {
+ for (; numToGo > 0; offset++)
+ {
+ numToGo--;
+ if (Character.isHighSurrogate(a[offset])
+ && (offset + 1) < len
+ && Character.isLowSurrogate(a[offset + 1]))
+ offset++;
+ }
+ return offset;
+ }
+ else
+ {
+ numToGo *= -1;
+ for (; numToGo > 0;)
+ {
+ numToGo--;
+ offset--;
+ if (Character.isLowSurrogate(a[offset])
+ && (offset - 1) >= 0
+ && Character.isHighSurrogate(a[offset - 1]))
+ offset--;
+ if (offset < start)
+ throw new IndexOutOfBoundsException();
+ }
+ return offset;
+ }
+
+ }
+
+ /**
+ * Returns the number of Unicode code points in the specified range of the
+ * given CharSequence. The first char in the range is at position
+ * beginIndex and the last one is at position endIndex - 1. Paired
+ * surrogates (supplementary characters are represented by a pair of chars -
+ * one from the high surrogates and one from the low surrogates)
+ * count as just one code point.
+ * @param seq the CharSequence to inspect
+ * @param beginIndex the beginning of the range
+ * @param endIndex the end of the range
+ * @return the number of Unicode code points in the given range of the
+ * sequence
+ * @throws NullPointerException if seq is null
+ * @throws IndexOutOfBoundsException if beginIndex is negative, endIndex is
+ * larger than the length of seq, or if beginIndex is greater than endIndex.
+ * @since 1.5
+ */
+ public static int codePointCount(CharSequence seq, int beginIndex,
+ int endIndex)
+ {
+ int len = seq.length();
+ if (beginIndex < 0 || endIndex > len || beginIndex > endIndex)
+ throw new IndexOutOfBoundsException();
+
+ int count = 0;
+ for (int i = beginIndex; i < endIndex; i++)
+ {
+ count++;
+ // If there is a pairing, count it only once.
+ if (isHighSurrogate(seq.charAt(i)) && (i + 1) < endIndex
+ && isLowSurrogate(seq.charAt(i + 1)))
+ i ++;
+ }
+ return count;
+ }
+
+ /**
+ * Returns the number of Unicode code points in the specified range of the
+ * given char array. The first char in the range is at position
+ * offset and the length of the range is count. Paired surrogates
+ * (supplementary characters are represented by a pair of chars -
+ * one from the high surrogates and one from the low surrogates)
+ * count as just one code point.
+ * @param a the char array to inspect
+ * @param offset the beginning of the range
+ * @param count the length of the range
+ * @return the number of Unicode code points in the given range of the
+ * array
+ * @throws NullPointerException if a is null
+ * @throws IndexOutOfBoundsException if offset or count is negative or if
+ * offset + countendIndex is larger than the length of a.
+ * @since 1.5
+ */
+ public static int codePointCount(char[] a, int offset,
+ int count)
+ {
+ int len = a.length;
+ int end = offset + count;
+ if (offset < 0 || count < 0 || end > len)
+ throw new IndexOutOfBoundsException();
+
+ int counter = 0;
+ for (int i = offset; i < end; i++)
+ {
+ counter++;
+ // If there is a pairing, count it only once.
+ if (isHighSurrogate(a[i]) && (i + 1) < end
+ && isLowSurrogate(a[i + 1]))
+ i ++;
+ }
+ return counter;
+ }
+
+ /**
+ * Determines if a character is a Unicode letter or a Unicode digit. This
+ * is the combination of isLetter and isDigit.
+ * <br>
+ * letter or digit = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nd]
+ *
+ * @param ch character to test
+ * @return true if ch is a Unicode letter or a Unicode digit, else false
+ * @see #isDigit(char)
+ * @see #isJavaIdentifierPart(char)
+ * @see #isJavaLetter(char)
+ * @see #isJavaLetterOrDigit(char)
+ * @see #isLetter(char)
+ * @see #isUnicodeIdentifierPart(char)
+ */
+ public static boolean isLetterOrDigit(char ch)
+ {
+ return ((1 << getType(ch))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << DECIMAL_DIGIT_NUMBER))) != 0;
+ }
+
+ /**
+ * Determines if a character is a Unicode letter or a Unicode digit. This
+ * is the combination of isLetter and isDigit. Unlike isLetterOrDigit(char),
+ * this method supports supplementary Unicode code points.
+ * <br>
+ * letter or digit = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nd]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is a Unicode letter or a Unicode digit, else false
+ * @see #isDigit(int)
+ * @see #isJavaIdentifierPart(int)
+ * @see #isJavaLetter(int)
+ * @see #isJavaLetterOrDigit(int)
+ * @see #isLetter(int)
+ * @see #isUnicodeIdentifierPart(int)
+ * @since 1.5
+ */
+ public static boolean isLetterOrDigit(int codePoint)
+ {
+ return ((1 << getType(codePoint)
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << DECIMAL_DIGIT_NUMBER))) != 0);
+ }
+
+ /**
+ * Determines if a character can start a Java identifier. This is the
+ * combination of isLetter, any character where getType returns
+ * LETTER_NUMBER, currency symbols (like '$'), and connecting punctuation
+ * (like '_').
+ *
+ * @param ch character to test
+ * @return true if ch can start a Java identifier, else false
+ * @deprecated Replaced by {@link #isJavaIdentifierStart(char)}
+ * @see #isJavaLetterOrDigit(char)
+ * @see #isJavaIdentifierStart(char)
+ * @see #isJavaIdentifierPart(char)
+ * @see #isLetter(char)
+ * @see #isLetterOrDigit(char)
+ * @see #isUnicodeIdentifierStart(char)
+ */
+ public static boolean isJavaLetter(char ch)
+ {
+ return isJavaIdentifierStart(ch);
+ }
+
+ /**
+ * Determines if a character can start a Java identifier. This is the
+ * combination of isLetter, any character where getType returns
+ * LETTER_NUMBER, currency symbols (like '$'), and connecting punctuation
+ * (like '_'). Unlike isJavaIdentifierStart(char), this method supports
+ * supplementary Unicode code points.
+ * <br>
+ * Java identifier start = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Sc]|[Pc]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint can start a Java identifier, else false
+ * @see #isJavaIdentifierPart(int)
+ * @see #isLetter(int)
+ * @see #isUnicodeIdentifierStart(int)
+ * @since 1.5
+ */
+ public static boolean isJavaIdentifierStart(int codePoint)
+ {
+ return ((1 << getType(codePoint))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << LETTER_NUMBER)
+ | (1 << CURRENCY_SYMBOL)
+ | (1 << CONNECTOR_PUNCTUATION))) != 0;
+ }
+
+ /**
+ * Determines if a character can follow the first letter in
+ * a Java identifier. This is the combination of isJavaLetter (isLetter,
+ * type of LETTER_NUMBER, currency, connecting punctuation) and digit,
+ * numeric letter (like Roman numerals), combining marks, non-spacing marks,
+ * or isIdentifierIgnorable.
+ *
+ * @param ch character to test
+ * @return true if ch can follow the first letter in a Java identifier
+ * @deprecated Replaced by {@link #isJavaIdentifierPart(char)}
+ * @see #isJavaLetter(char)
+ * @see #isJavaIdentifierStart(char)
+ * @see #isJavaIdentifierPart(char)
+ * @see #isLetter(char)
+ * @see #isLetterOrDigit(char)
+ * @see #isUnicodeIdentifierPart(char)
+ * @see #isIdentifierIgnorable(char)
+ */
+ public static boolean isJavaLetterOrDigit(char ch)
+ {
+ return isJavaIdentifierPart(ch);
+ }
+
+ /**
+ * Determines if a character can start a Java identifier. This is the
+ * combination of isLetter, any character where getType returns
+ * LETTER_NUMBER, currency symbols (like '$'), and connecting punctuation
+ * (like '_').
+ * <br>
+ * Java identifier start = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Sc]|[Pc]
+ *
+ * @param ch character to test
+ * @return true if ch can start a Java identifier, else false
+ * @see #isJavaIdentifierPart(char)
+ * @see #isLetter(char)
+ * @see #isUnicodeIdentifierStart(char)
+ * @since 1.1
+ */
+ public static boolean isJavaIdentifierStart(char ch)
+ {
+ return ((1 << getType(ch))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << LETTER_NUMBER)
+ | (1 << CURRENCY_SYMBOL)
+ | (1 << CONNECTOR_PUNCTUATION))) != 0;
+ }
+
+ /**
+ * Determines if a character can follow the first letter in
+ * a Java identifier. This is the combination of isJavaLetter (isLetter,
+ * type of LETTER_NUMBER, currency, connecting punctuation) and digit,
+ * numeric letter (like Roman numerals), combining marks, non-spacing marks,
+ * or isIdentifierIgnorable.
+ * <br>
+ * Java identifier extender =
+ * [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Sc]|[Pc]|[Mn]|[Mc]|[Nd]|[Cf]
+ * |U+0000-U+0008|U+000E-U+001B|U+007F-U+009F
+ *
+ * @param ch character to test
+ * @return true if ch can follow the first letter in a Java identifier
+ * @see #isIdentifierIgnorable(char)
+ * @see #isJavaIdentifierStart(char)
+ * @see #isLetterOrDigit(char)
+ * @see #isUnicodeIdentifierPart(char)
+ * @since 1.1
+ */
+ public static boolean isJavaIdentifierPart(char ch)
+ {
+ int category = getType(ch);
+ return ((1 << category)
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << NON_SPACING_MARK)
+ | (1 << COMBINING_SPACING_MARK)
+ | (1 << DECIMAL_DIGIT_NUMBER)
+ | (1 << LETTER_NUMBER)
+ | (1 << CURRENCY_SYMBOL)
+ | (1 << CONNECTOR_PUNCTUATION)
+ | (1 << FORMAT))) != 0
+ || (category == CONTROL && isIdentifierIgnorable(ch));
+ }
+
+ /**
+ * Determines if a character can follow the first letter in
+ * a Java identifier. This is the combination of isJavaLetter (isLetter,
+ * type of LETTER_NUMBER, currency, connecting punctuation) and digit,
+ * numeric letter (like Roman numerals), combining marks, non-spacing marks,
+ * or isIdentifierIgnorable. Unlike isJavaIdentifierPart(char), this method
+ * supports supplementary Unicode code points.
+ * <br>
+ * Java identifier extender =
+ * [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Sc]|[Pc]|[Mn]|[Mc]|[Nd]|[Cf]
+ * |U+0000-U+0008|U+000E-U+001B|U+007F-U+009F
+ *
+ * @param codePoint character to test
+ * @return true if codePoint can follow the first letter in a Java identifier
+ * @see #isIdentifierIgnorable(int)
+ * @see #isJavaIdentifierStart(int)
+ * @see #isLetterOrDigit(int)
+ * @see #isUnicodeIdentifierPart(int)
+ * @since 1.5
+ */
+ public static boolean isJavaIdentifierPart(int codePoint)
+ {
+ int category = getType(codePoint);
+ return ((1 << category)
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << NON_SPACING_MARK)
+ | (1 << COMBINING_SPACING_MARK)
+ | (1 << DECIMAL_DIGIT_NUMBER)
+ | (1 << LETTER_NUMBER)
+ | (1 << CURRENCY_SYMBOL)
+ | (1 << CONNECTOR_PUNCTUATION)
+ | (1 << FORMAT))) != 0
+ || (category == CONTROL && isIdentifierIgnorable(codePoint));
+ }
+
+ /**
+ * Determines if a character can start a Unicode identifier. Only
+ * letters can start a Unicode identifier, but this includes characters
+ * in LETTER_NUMBER.
+ * <br>
+ * Unicode identifier start = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]
+ *
+ * @param ch character to test
+ * @return true if ch can start a Unicode identifier, else false
+ * @see #isJavaIdentifierStart(char)
+ * @see #isLetter(char)
+ * @see #isUnicodeIdentifierPart(char)
+ * @since 1.1
+ */
+ public static boolean isUnicodeIdentifierStart(char ch)
+ {
+ return ((1 << getType(ch))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << LETTER_NUMBER))) != 0;
+ }
+
+ /**
+ * Determines if a character can start a Unicode identifier. Only
+ * letters can start a Unicode identifier, but this includes characters
+ * in LETTER_NUMBER. Unlike isUnicodeIdentifierStart(char), this method
+ * supports supplementary Unicode code points.
+ * <br>
+ * Unicode identifier start = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint can start a Unicode identifier, else false
+ * @see #isJavaIdentifierStart(int)
+ * @see #isLetter(int)
+ * @see #isUnicodeIdentifierPart(int)
+ * @since 1.5
+ */
+ public static boolean isUnicodeIdentifierStart(int codePoint)
+ {
+ return ((1 << getType(codePoint))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << LETTER_NUMBER))) != 0;
+ }
+
+ /**
+ * Determines if a character can follow the first letter in
+ * a Unicode identifier. This includes letters, connecting punctuation,
+ * digits, numeric letters, combining marks, non-spacing marks, and
+ * isIdentifierIgnorable.
+ * <br>
+ * Unicode identifier extender =
+ * [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Mn]|[Mc]|[Nd]|[Pc]|[Cf]|
+ * |U+0000-U+0008|U+000E-U+001B|U+007F-U+009F
+ *
+ * @param ch character to test
+ * @return true if ch can follow the first letter in a Unicode identifier
+ * @see #isIdentifierIgnorable(char)
+ * @see #isJavaIdentifierPart(char)
+ * @see #isLetterOrDigit(char)
+ * @see #isUnicodeIdentifierStart(char)
+ * @since 1.1
+ */
+ public static boolean isUnicodeIdentifierPart(char ch)
+ {
+ int category = getType(ch);
+ return ((1 << category)
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << NON_SPACING_MARK)
+ | (1 << COMBINING_SPACING_MARK)
+ | (1 << DECIMAL_DIGIT_NUMBER)
+ | (1 << LETTER_NUMBER)
+ | (1 << CONNECTOR_PUNCTUATION)
+ | (1 << FORMAT))) != 0
+ || (category == CONTROL && isIdentifierIgnorable(ch));
+ }
+
+ /**
+ * Determines if a character can follow the first letter in
+ * a Unicode identifier. This includes letters, connecting punctuation,
+ * digits, numeric letters, combining marks, non-spacing marks, and
+ * isIdentifierIgnorable. Unlike isUnicodeIdentifierPart(char), this method
+ * supports supplementary Unicode code points.
+ * <br>
+ * Unicode identifier extender =
+ * [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Mn]|[Mc]|[Nd]|[Pc]|[Cf]|
+ * |U+0000-U+0008|U+000E-U+001B|U+007F-U+009F
+ *
+ * @param codePoint character to test
+ * @return true if codePoint can follow the first letter in a Unicode
+ * identifier
+ * @see #isIdentifierIgnorable(int)
+ * @see #isJavaIdentifierPart(int)
+ * @see #isLetterOrDigit(int)
+ * @see #isUnicodeIdentifierStart(int)
+ * @since 1.5
+ */
+ public static boolean isUnicodeIdentifierPart(int codePoint)
+ {
+ int category = getType(codePoint);
+ return ((1 << category)
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << NON_SPACING_MARK)
+ | (1 << COMBINING_SPACING_MARK)
+ | (1 << DECIMAL_DIGIT_NUMBER)
+ | (1 << LETTER_NUMBER)
+ | (1 << CONNECTOR_PUNCTUATION)
+ | (1 << FORMAT))) != 0
+ || (category == CONTROL && isIdentifierIgnorable(codePoint));
+ }
+
+ /**
+ * Determines if a character is ignorable in a Unicode identifier. This
+ * includes the non-whitespace ISO control characters (<code>'\u0000'</code>
+ * through <code>'\u0008'</code>, <code>'\u000E'</code> through
+ * <code>'\u001B'</code>, and <code>'\u007F'</code> through
+ * <code>'\u009F'</code>), and FORMAT characters.
+ * <br>
+ * Unicode identifier ignorable = [Cf]|U+0000-U+0008|U+000E-U+001B
+ * |U+007F-U+009F
+ *
+ * @param ch character to test
+ * @return true if ch is ignorable in a Unicode or Java identifier
+ * @see #isJavaIdentifierPart(char)
+ * @see #isUnicodeIdentifierPart(char)
+ * @since 1.1
+ */
+ public static boolean isIdentifierIgnorable(char ch)
+ {
+ return (ch <= '\u009F' && (ch < '\t' || ch >= '\u007F'
+ || (ch <= '\u001B' && ch >= '\u000E')))
+ || getType(ch) == FORMAT;
+ }
+
+ /**
+ * Determines if a character is ignorable in a Unicode identifier. This
+ * includes the non-whitespace ISO control characters (<code>'\u0000'</code>
+ * through <code>'\u0008'</code>, <code>'\u000E'</code> through
+ * <code>'\u001B'</code>, and <code>'\u007F'</code> through
+ * <code>'\u009F'</code>), and FORMAT characters. Unlike
+ * isIdentifierIgnorable(char), this method supports supplementary Unicode
+ * code points.
+ * <br>
+ * Unicode identifier ignorable = [Cf]|U+0000-U+0008|U+000E-U+001B
+ * |U+007F-U+009F
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is ignorable in a Unicode or Java identifier
+ * @see #isJavaIdentifierPart(int)
+ * @see #isUnicodeIdentifierPart(int)
+ * @since 1.5
+ */
+ public static boolean isIdentifierIgnorable(int codePoint)
+ {
+ return ((codePoint >= 0 && codePoint <= 0x0008)
+ || (codePoint >= 0x000E && codePoint <= 0x001B)
+ || (codePoint >= 0x007F && codePoint <= 0x009F)
+ || getType(codePoint) == FORMAT);
+ }
+
+ /**
+ * Converts a Unicode character into its lowercase equivalent mapping.
+ * If a mapping does not exist, then the character passed is returned.
+ * Note that isLowerCase(toLowerCase(ch)) does not always return true.
+ *
+ * @param ch character to convert to lowercase
+ * @return lowercase mapping of ch, or ch if lowercase mapping does
+ * not exist
+ * @see #isLowerCase(char)
+ * @see #isUpperCase(char)
+ * @see #toTitleCase(char)
+ * @see #toUpperCase(char)
+ */
+ public static native char toLowerCase(char ch);
+
+ /**
+ * Converts a Unicode character into its lowercase equivalent mapping.
+ * If a mapping does not exist, then the character passed is returned.
+ * Note that isLowerCase(toLowerCase(codePoint)) does not always return true.
+ * Unlike toLowerCase(char), this method supports supplementary Unicode
+ * code points.
+ *
+ * @param codePoint character to convert to lowercase
+ * @return lowercase mapping of codePoint, or codePoint if lowercase
+ * mapping does not exist
+ * @see #isLowerCase(int)
+ * @see #isUpperCase(int)
+ * @see #toTitleCase(int)
+ * @see #toUpperCase(int)
+ * @since 1.5
+ */
+ public static native int toLowerCase(int codePoint);
+
+ /**
+ * Converts a Unicode character into its uppercase equivalent mapping.
+ * If a mapping does not exist, then the character passed is returned.
+ * Note that isUpperCase(toUpperCase(ch)) does not always return true.
+ *
+ * @param ch character to convert to uppercase
+ * @return uppercase mapping of ch, or ch if uppercase mapping does
+ * not exist
+ * @see #isLowerCase(char)
+ * @see #isUpperCase(char)
+ * @see #toLowerCase(char)
+ * @see #toTitleCase(char)
+ */
+ public static native char toUpperCase(char ch);
+
+ /**
+ * Converts a Unicode character into its uppercase equivalent mapping.
+ * If a mapping does not exist, then the character passed is returned.
+ * Note that isUpperCase(toUpperCase(codePoint)) does not always return true.
+ * Unlike toUpperCase(char), this method supports supplementary
+ * Unicode code points.
+ *
+ * @param codePoint character to convert to uppercase
+ * @return uppercase mapping of codePoint, or codePoint if uppercase
+ * mapping does not exist
+ * @see #isLowerCase(int)
+ * @see #isUpperCase(int)
+ * @see #toLowerCase(int)
+ * @see #toTitleCase(int)
+ * @since 1.5
+ */
+ public static native int toUpperCase(int codePoint);
+
+ /**
+ * Converts a Unicode character into its titlecase equivalent mapping.
+ * If a mapping does not exist, then the character passed is returned.
+ * Note that isTitleCase(toTitleCase(ch)) does not always return true.
+ *
+ * @param ch character to convert to titlecase
+ * @return titlecase mapping of ch, or ch if titlecase mapping does
+ * not exist
+ * @see #isTitleCase(char)
+ * @see #toLowerCase(char)
+ * @see #toUpperCase(char)
+ */
+ public static native char toTitleCase(char ch);
+
+ /**
+ * Converts a Unicode character into its titlecase equivalent mapping.
+ * If a mapping does not exist, then the character passed is returned.
+ * Note that isTitleCase(toTitleCase(codePoint)) does not always return true.
+ * Unlike toTitleCase(char), this method supports supplementary
+ * Unicode code points.
+ *
+ * @param codePoint character to convert to titlecase
+ * @return titlecase mapping of codePoint, or codePoint if titlecase
+ * mapping does not exist
+ * @see #isTitleCase(int)
+ * @see #toLowerCase(int)
+ * @see #toUpperCase(int)
+ * @since 1.5
+ */
+ public static native int toTitleCase(int codePoint);
+
+ /**
+ * Converts a character into a digit of the specified radix. If the radix
+ * exceeds MIN_RADIX or MAX_RADIX, or if the result of getNumericValue(ch)
+ * exceeds the radix, or if ch is not a decimal digit or in the case
+ * insensitive set of 'a'-'z', the result is -1.
+ * <br>
+ * character argument boundary = [Nd]|U+0041-U+005A|U+0061-U+007A
+ * |U+FF21-U+FF3A|U+FF41-U+FF5A
+ *
+ * @param ch character to convert into a digit
+ * @param radix radix in which ch is a digit
+ * @return digit which ch represents in radix, or -1 not a valid digit
+ * @see #MIN_RADIX
+ * @see #MAX_RADIX
+ * @see #forDigit(int, int)
+ * @see #isDigit(char)
+ * @see #getNumericValue(char)
+ */
+ public static native int digit(char ch, int radix);
+
+ /**
+ * Converts a character into a digit of the specified radix. If the radix
+ * exceeds MIN_RADIX or MAX_RADIX, or if the result of getNumericValue(int)
+ * exceeds the radix, or if codePoint is not a decimal digit or in the case
+ * insensitive set of 'a'-'z', the result is -1. Unlike digit(char, int),
+ * this method supports supplementary Unicode code points.
+ * <br>
+ * character argument boundary = [Nd]|U+0041-U+005A|U+0061-U+007A
+ * |U+FF21-U+FF3A|U+FF41-U+FF5A
+ *
+ * @param codePoint character to convert into a digit
+ * @param radix radix in which codePoint is a digit
+ * @return digit which codePoint represents in radix, or -1 not a valid digit
+ * @see #MIN_RADIX
+ * @see #MAX_RADIX
+ * @see #forDigit(int, int)
+ * @see #isDigit(int)
+ * @see #getNumericValue(int)
+ * @since 1.5
+ */
+ public static native int digit(int codePoint, int radix);
+
+ /**
+ * Returns the Unicode numeric value property of a character. For example,
+ * <code>'\\u216C'</code> (the Roman numeral fifty) returns 50.
+ *
+ * <p>This method also returns values for the letters A through Z, (not
+ * specified by Unicode), in these ranges: <code>'\u0041'</code>
+ * through <code>'\u005A'</code> (uppercase); <code>'\u0061'</code>
+ * through <code>'\u007A'</code> (lowercase); and <code>'\uFF21'</code>
+ * through <code>'\uFF3A'</code>, <code>'\uFF41'</code> through
+ * <code>'\uFF5A'</code> (full width variants).
+ *
+ * <p>If the character lacks a numeric value property, -1 is returned.
+ * If the character has a numeric value property which is not representable
+ * as a nonnegative integer, such as a fraction, -2 is returned.
+ *
+ * character argument boundary = [Nd]|[Nl]|[No]|U+0041-U+005A|U+0061-U+007A
+ * |U+FF21-U+FF3A|U+FF41-U+FF5A
+ *
+ * @param ch character from which the numeric value property will
+ * be retrieved
+ * @return the numeric value property of ch, or -1 if it does not exist, or
+ * -2 if it is not representable as a nonnegative integer
+ * @see #forDigit(int, int)
+ * @see #digit(char, int)
+ * @see #isDigit(char)
+ * @since 1.1
+ */
+ public static native int getNumericValue(char ch);
+
+ /**
+ * Returns the Unicode numeric value property of a character. For example,
+ * <code>'\\u216C'</code> (the Roman numeral fifty) returns 50.
+ *
+ * <p>This method also returns values for the letters A through Z, (not
+ * specified by Unicode), in these ranges: <code>'\u0041'</code>
+ * through <code>'\u005A'</code> (uppercase); <code>'\u0061'</code>
+ * through <code>'\u007A'</code> (lowercase); and <code>'\uFF21'</code>
+ * through <code>'\uFF3A'</code>, <code>'\uFF41'</code> through
+ * <code>'\uFF5A'</code> (full width variants).
+ *
+ * <p>If the character lacks a numeric value property, -1 is returned.
+ * If the character has a numeric value property which is not representable
+ * as a nonnegative integer, such as a fraction, -2 is returned.
+ *
+ * Unlike getNumericValue(char), this method supports supplementary Unicode
+ * code points.
+ *
+ * character argument boundary = [Nd]|[Nl]|[No]|U+0041-U+005A|U+0061-U+007A
+ * |U+FF21-U+FF3A|U+FF41-U+FF5A
+ *
+ * @param codePoint character from which the numeric value property will
+ * be retrieved
+ * @return the numeric value property of codePoint, or -1 if it does not
+ * exist, or -2 if it is not representable as a nonnegative integer
+ * @see #forDigit(int, int)
+ * @see #digit(int, int)
+ * @see #isDigit(int)
+ * @since 1.5
+ */
+ public static native int getNumericValue(int codePoint);
+
+ /**
+ * Determines if a character is a ISO-LATIN-1 space. This is only the five
+ * characters <code>'\t'</code>, <code>'\n'</code>, <code>'\f'</code>,
+ * <code>'\r'</code>, and <code>' '</code>.
+ * <br>
+ * Java space = U+0020|U+0009|U+000A|U+000C|U+000D
+ *
+ * @param ch character to test
+ * @return true if ch is a space, else false
+ * @deprecated Replaced by {@link #isWhitespace(char)}
+ * @see #isSpaceChar(char)
+ * @see #isWhitespace(char)
+ */
+ public static boolean isSpace(char ch)
+ {
+ // Performing the subtraction up front alleviates need to compare longs.
+ return ch-- <= ' ' && ((1 << ch)
+ & ((1 << (' ' - 1))
+ | (1 << ('\t' - 1))
+ | (1 << ('\n' - 1))
+ | (1 << ('\r' - 1))
+ | (1 << ('\f' - 1)))) != 0;
+ }
+
+ /**
+ * Determines if a character is a Unicode space character. This includes
+ * SPACE_SEPARATOR, LINE_SEPARATOR, and PARAGRAPH_SEPARATOR.
+ * <br>
+ * Unicode space = [Zs]|[Zp]|[Zl]
+ *
+ * @param ch character to test
+ * @return true if ch is a Unicode space, else false
+ * @see #isWhitespace(char)
+ * @since 1.1
+ */
+ public static boolean isSpaceChar(char ch)
+ {
+ return ((1 << getType(ch))
+ & ((1 << SPACE_SEPARATOR)
+ | (1 << LINE_SEPARATOR)
+ | (1 << PARAGRAPH_SEPARATOR))) != 0;
+ }
+
+ /**
+ * Determines if a character is a Unicode space character. This includes
+ * SPACE_SEPARATOR, LINE_SEPARATOR, and PARAGRAPH_SEPARATOR. Unlike
+ * isSpaceChar(char), this method supports supplementary Unicode code points.
+ * <br>
+ * Unicode space = [Zs]|[Zp]|[Zl]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is a Unicode space, else false
+ * @see #isWhitespace(int)
+ * @since 1.5
+ */
+ public static boolean isSpaceChar(int codePoint)
+ {
+ return ((1 << getType(codePoint))
+ & ((1 << SPACE_SEPARATOR)
+ | (1 << LINE_SEPARATOR)
+ | (1 << PARAGRAPH_SEPARATOR))) != 0;
+ }
+
+ /**
+ * Determines if a character is Java whitespace. This includes Unicode
+ * space characters (SPACE_SEPARATOR, LINE_SEPARATOR, and
+ * PARAGRAPH_SEPARATOR) except the non-breaking spaces
+ * (<code>'\u00A0'</code>, <code>'\u2007'</code>, and <code>'\u202F'</code>);
+ * and these characters: <code>'\u0009'</code>, <code>'\u000A'</code>,
+ * <code>'\u000B'</code>, <code>'\u000C'</code>, <code>'\u000D'</code>,
+ * <code>'\u001C'</code>, <code>'\u001D'</code>, <code>'\u001E'</code>,
+ * and <code>'\u001F'</code>.
+ * <br>
+ * Java whitespace = ([Zs] not Nb)|[Zl]|[Zp]|U+0009-U+000D|U+001C-U+001F
+ *
+ * @param ch character to test
+ * @return true if ch is Java whitespace, else false
+ * @see #isSpaceChar(char)
+ * @since 1.1
+ */
+ public static boolean isWhitespace(char ch)
+ {
+ int attr = readChar(ch);
+ return ((((1 << (attr & TYPE_MASK))
+ & ((1 << SPACE_SEPARATOR)
+ | (1 << LINE_SEPARATOR)
+ | (1 << PARAGRAPH_SEPARATOR))) != 0)
+ && (attr & NO_BREAK_MASK) == 0)
+ || (ch <= '\u001F' && ((1 << ch)
+ & ((1 << '\t')
+ | (1 << '\n')
+ | (1 << '\u000B')
+ | (1 << '\u000C')
+ | (1 << '\r')
+ | (1 << '\u001C')
+ | (1 << '\u001D')
+ | (1 << '\u001E')
+ | (1 << '\u001F'))) != 0);
+ }
+
+ /**
+ * Determines if a character is Java whitespace. This includes Unicode
+ * space characters (SPACE_SEPARATOR, LINE_SEPARATOR, and
+ * PARAGRAPH_SEPARATOR) except the non-breaking spaces
+ * (<code>'\u00A0'</code>, <code>'\u2007'</code>, and <code>'\u202F'</code>);
+ * and these characters: <code>'\u0009'</code>, <code>'\u000A'</code>,
+ * <code>'\u000B'</code>, <code>'\u000C'</code>, <code>'\u000D'</code>,
+ * <code>'\u001C'</code>, <code>'\u001D'</code>, <code>'\u001E'</code>,
+ * and <code>'\u001F'</code>. Unlike isWhitespace(char), this method
+ * supports supplementary Unicode code points.
+ * <br>
+ * Java whitespace = ([Zs] not Nb)|[Zl]|[Zp]|U+0009-U+000D|U+001C-U+001F
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is Java whitespace, else false
+ * @see #isSpaceChar(int)
+ * @since 1.5
+ */
+ public static boolean isWhitespace(int codePoint)
+ {
+ int plane = codePoint >>> 16;
+ if (plane > 2 && plane != 14)
+ return false;
+ int attr = readCodePoint(codePoint);
+ return ((((1 << (attr & TYPE_MASK))
+ & ((1 << SPACE_SEPARATOR)
+ | (1 << LINE_SEPARATOR)
+ | (1 << PARAGRAPH_SEPARATOR))) != 0)
+ && (attr & NO_BREAK_MASK) == 0)
+ || (codePoint <= '\u001F' && ((1 << codePoint)
+ & ((1 << '\t')
+ | (1 << '\n')
+ | (1 << '\u000B')
+ | (1 << '\u000C')
+ | (1 << '\r')
+ | (1 << '\u001C')
+ | (1 << '\u001D')
+ | (1 << '\u001E')
+ | (1 << '\u001F'))) != 0);
+ }
+
+ /**
+ * Determines if a character has the ISO Control property.
+ * <br>
+ * ISO Control = [Cc]
+ *
+ * @param ch character to test
+ * @return true if ch is an ISO Control character, else false
+ * @see #isSpaceChar(char)
+ * @see #isWhitespace(char)
+ * @since 1.1
+ */
+ public static boolean isISOControl(char ch)
+ {
+ return getType(ch) == CONTROL;
+ }
+
+ /**
+ * Determines if a character has the ISO Control property. Unlike
+ * isISOControl(char), this method supports supplementary unicode
+ * code points.
+ * <br>
+ * ISO Control = [Cc]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is an ISO Control character, else false
+ * @see #isSpaceChar(int)
+ * @see #isWhitespace(int)
+ * @since 1.5
+ */
+ public static boolean isISOControl(int codePoint)
+ {
+ return getType(codePoint) == CONTROL;
+ }
+
+ /**
+ * Returns the Unicode general category property of a character.
+ *
+ * @param ch character from which the general category property will
+ * be retrieved
+ * @return the character category property of ch as an integer
+ * @see #UNASSIGNED
+ * @see #UPPERCASE_LETTER
+ * @see #LOWERCASE_LETTER
+ * @see #TITLECASE_LETTER
+ * @see #MODIFIER_LETTER
+ * @see #OTHER_LETTER
+ * @see #NON_SPACING_MARK
+ * @see #ENCLOSING_MARK
+ * @see #COMBINING_SPACING_MARK
+ * @see #DECIMAL_DIGIT_NUMBER
+ * @see #LETTER_NUMBER
+ * @see #OTHER_NUMBER
+ * @see #SPACE_SEPARATOR
+ * @see #LINE_SEPARATOR
+ * @see #PARAGRAPH_SEPARATOR
+ * @see #CONTROL
+ * @see #FORMAT
+ * @see #PRIVATE_USE
+ * @see #SURROGATE
+ * @see #DASH_PUNCTUATION
+ * @see #START_PUNCTUATION
+ * @see #END_PUNCTUATION
+ * @see #CONNECTOR_PUNCTUATION
+ * @see #OTHER_PUNCTUATION
+ * @see #MATH_SYMBOL
+ * @see #CURRENCY_SYMBOL
+ * @see #MODIFIER_SYMBOL
+ * @see #INITIAL_QUOTE_PUNCTUATION
+ * @see #FINAL_QUOTE_PUNCTUATION
+ * @since 1.1
+ */
+ public static native int getType(char ch);
+
+ /**
+ * Returns the Unicode general category property of a character. Supports
+ * supplementary Unicode code points.
+ *
+ * @param codePoint character from which the general category property will
+ * be retrieved
+ * @return the character category property of codePoint as an integer
+ * @see #UNASSIGNED
+ * @see #UPPERCASE_LETTER
+ * @see #LOWERCASE_LETTER
+ * @see #TITLECASE_LETTER
+ * @see #MODIFIER_LETTER
+ * @see #OTHER_LETTER
+ * @see #NON_SPACING_MARK
+ * @see #ENCLOSING_MARK
+ * @see #COMBINING_SPACING_MARK
+ * @see #DECIMAL_DIGIT_NUMBER
+ * @see #LETTER_NUMBER
+ * @see #OTHER_NUMBER
+ * @see #SPACE_SEPARATOR
+ * @see #LINE_SEPARATOR
+ * @see #PARAGRAPH_SEPARATOR
+ * @see #CONTROL
+ * @see #FORMAT
+ * @see #PRIVATE_USE
+ * @see #SURROGATE
+ * @see #DASH_PUNCTUATION
+ * @see #START_PUNCTUATION
+ * @see #END_PUNCTUATION
+ * @see #CONNECTOR_PUNCTUATION
+ * @see #OTHER_PUNCTUATION
+ * @see #MATH_SYMBOL
+ * @see #CURRENCY_SYMBOL
+ * @see #MODIFIER_SYMBOL
+ * @see #INITIAL_QUOTE_PUNCTUATION
+ * @see #FINAL_QUOTE_PUNCTUATION
+ * @since 1.5
+ */
+ public static native int getType(int codePoint);
+
+ /**
+ * Converts a digit into a character which represents that digit
+ * in a specified radix. If the radix exceeds MIN_RADIX or MAX_RADIX,
+ * or the digit exceeds the radix, then the null character <code>'\0'</code>
+ * is returned. Otherwise the return value is in '0'-'9' and 'a'-'z'.
+ * <br>
+ * return value boundary = U+0030-U+0039|U+0061-U+007A
+ *
+ * @param digit digit to be converted into a character
+ * @param radix radix of digit
+ * @return character representing digit in radix, or '\0'
+ * @see #MIN_RADIX
+ * @see #MAX_RADIX
+ * @see #digit(char, int)
+ */
+ public static char forDigit(int digit, int radix)
+ {
+ if (radix < MIN_RADIX || radix > MAX_RADIX
+ || digit < 0 || digit >= radix)
+ return '\0';
+ return (char) (digit < 10 ? ('0' + digit) : ('a' - 10 + digit));
+ }
+
+ /**
+ * Returns the Unicode directionality property of the character. This
+ * is used in the visual ordering of text.
+ *
+ * @param ch the character to look up
+ * @return the directionality constant, or DIRECTIONALITY_UNDEFINED
+ * @see #DIRECTIONALITY_UNDEFINED
+ * @see #DIRECTIONALITY_LEFT_TO_RIGHT
+ * @see #DIRECTIONALITY_RIGHT_TO_LEFT
+ * @see #DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
+ * @see #DIRECTIONALITY_EUROPEAN_NUMBER
+ * @see #DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR
+ * @see #DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
+ * @see #DIRECTIONALITY_ARABIC_NUMBER
+ * @see #DIRECTIONALITY_COMMON_NUMBER_SEPARATOR
+ * @see #DIRECTIONALITY_NONSPACING_MARK
+ * @see #DIRECTIONALITY_BOUNDARY_NEUTRAL
+ * @see #DIRECTIONALITY_PARAGRAPH_SEPARATOR
+ * @see #DIRECTIONALITY_SEGMENT_SEPARATOR
+ * @see #DIRECTIONALITY_WHITESPACE
+ * @see #DIRECTIONALITY_OTHER_NEUTRALS
+ * @see #DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING
+ * @see #DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE
+ * @see #DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING
+ * @see #DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE
+ * @see #DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
+ * @since 1.4
+ */
+ public static native byte getDirectionality(char ch);
+
+ /**
+ * Returns the Unicode directionality property of the character. This
+ * is used in the visual ordering of text. Unlike getDirectionality(char),
+ * this method supports supplementary Unicode code points.
+ *
+ * @param codePoint the character to look up
+ * @return the directionality constant, or DIRECTIONALITY_UNDEFINED
+ * @see #DIRECTIONALITY_UNDEFINED
+ * @see #DIRECTIONALITY_LEFT_TO_RIGHT
+ * @see #DIRECTIONALITY_RIGHT_TO_LEFT
+ * @see #DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
+ * @see #DIRECTIONALITY_EUROPEAN_NUMBER
+ * @see #DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR
+ * @see #DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
+ * @see #DIRECTIONALITY_ARABIC_NUMBER
+ * @see #DIRECTIONALITY_COMMON_NUMBER_SEPARATOR
+ * @see #DIRECTIONALITY_NONSPACING_MARK
+ * @see #DIRECTIONALITY_BOUNDARY_NEUTRAL
+ * @see #DIRECTIONALITY_PARAGRAPH_SEPARATOR
+ * @see #DIRECTIONALITY_SEGMENT_SEPARATOR
+ * @see #DIRECTIONALITY_WHITESPACE
+ * @see #DIRECTIONALITY_OTHER_NEUTRALS
+ * @see #DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING
+ * @see #DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE
+ * @see #DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING
+ * @see #DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE
+ * @see #DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
+ * @since 1.5
+ */
+ public static native byte getDirectionality(int codePoint);
+
+ /**
+ * Determines whether the character is mirrored according to Unicode. For
+ * example, <code>\u0028</code> (LEFT PARENTHESIS) appears as '(' in
+ * left-to-right text, but ')' in right-to-left text.
+ *
+ * @param ch the character to look up
+ * @return true if the character is mirrored
+ * @since 1.4
+ */
+ public static boolean isMirrored(char ch)
+ {
+ return (readChar(ch) & MIRROR_MASK) != 0;
+ }
+
+ /**
+ * Determines whether the character is mirrored according to Unicode. For
+ * example, <code>\u0028</code> (LEFT PARENTHESIS) appears as '(' in
+ * left-to-right text, but ')' in right-to-left text. Unlike
+ * isMirrored(char), this method supports supplementary Unicode code points.
+ *
+ * @param codePoint the character to look up
+ * @return true if the character is mirrored
+ * @since 1.5
+ */
+ public static boolean isMirrored(int codePoint)
+ {
+ int plane = codePoint >>> 16;
+ if (plane > 2 && plane != 14)
+ return false;
+ return (readCodePoint(codePoint) & MIRROR_MASK) != 0;
+ }
+
+ /**
+ * Compares another Character to this Character, numerically.
+ *
+ * @param anotherCharacter Character to compare with this Character
+ * @return a negative integer if this Character is less than
+ * anotherCharacter, zero if this Character is equal, and
+ * a positive integer if this Character is greater
+ * @throws NullPointerException if anotherCharacter is null
+ * @since 1.2
+ */
+ public int compareTo(Character anotherCharacter)
+ {
+ return value - anotherCharacter.value;
+ }
+
+ /**
+ * Returns an <code>Character</code> object wrapping the value.
+ * In contrast to the <code>Character</code> constructor, this method
+ * will cache some values. It is used by boxing conversion.
+ *
+ * @param val the value to wrap
+ * @return the <code>Character</code>
+ *
+ * @since 1.5
+ */
+ public static Character valueOf(char val)
+ {
+ if (val > MAX_CACHE)
+ return new Character(val);
+ synchronized (charCache)
+ {
+ if (charCache[val - MIN_VALUE] == null)
+ charCache[val - MIN_VALUE] = new Character(val);
+ return charCache[val - MIN_VALUE];
+ }
+ }
+
+ /**
+ * Reverse the bytes in val.
+ * @since 1.5
+ */
+ public static char reverseBytes(char val)
+ {
+ return (char) (((val >> 8) & 0xff) | ((val << 8) & 0xff00));
+ }
+
+ /**
+ * Converts a unicode code point to a UTF-16 representation of that
+ * code point.
+ *
+ * @param codePoint the unicode code point
+ *
+ * @return the UTF-16 representation of that code point
+ *
+ * @throws IllegalArgumentException if the code point is not a valid
+ * unicode code point
+ *
+ * @since 1.5
+ */
+ public static char[] toChars(int codePoint)
+ {
+ if (!isValidCodePoint(codePoint))
+ throw new IllegalArgumentException("Illegal Unicode code point : "
+ + codePoint);
+ char[] result = new char[charCount(codePoint)];
+ int ignore = toChars(codePoint, result, 0);
+ return result;
+ }
+
+ /**
+ * Converts a unicode code point to its UTF-16 representation.
+ *
+ * @param codePoint the unicode code point
+ * @param dst the target char array
+ * @param dstIndex the start index for the target
+ *
+ * @return number of characters written to <code>dst</code>
+ *
+ * @throws IllegalArgumentException if <code>codePoint</code> is not a
+ * valid unicode code point
+ * @throws NullPointerException if <code>dst</code> is <code>null</code>
+ * @throws IndexOutOfBoundsException if <code>dstIndex</code> is not valid
+ * in <code>dst</code> or if the UTF-16 representation does not
+ * fit into <code>dst</code>
+ *
+ * @since 1.5
+ */
+ public static int toChars(int codePoint, char[] dst, int dstIndex)
+ {
+ if (!isValidCodePoint(codePoint))
+ {
+ throw new IllegalArgumentException("not a valid code point: "
+ + codePoint);
+ }
+
+ int result;
+ if (isSupplementaryCodePoint(codePoint))
+ {
+ // Write second char first to cause IndexOutOfBoundsException
+ // immediately.
+ final int cp2 = codePoint - 0x10000;
+ dst[dstIndex + 1] = (char) ((cp2 % 0x400) + (int) MIN_LOW_SURROGATE);
+ dst[dstIndex] = (char) ((cp2 / 0x400) + (int) MIN_HIGH_SURROGATE);
+ result = 2;
+ }
+ else
+ {
+ dst[dstIndex] = (char) codePoint;
+ result = 1;
+ }
+ return result;
+ }
+
+ /**
+ * Return number of 16-bit characters required to represent the given
+ * code point.
+ *
+ * @param codePoint a unicode code point
+ *
+ * @return 2 if codePoint >= 0x10000, 1 otherwise.
+ *
+ * @since 1.5
+ */
+ public static int charCount(int codePoint)
+ {
+ return
+ (codePoint >= MIN_SUPPLEMENTARY_CODE_POINT)
+ ? 2
+ : 1;
+ }
+
+ /**
+ * Determines whether the specified code point is
+ * in the range 0x10000 .. 0x10FFFF, i.e. the character is within the Unicode
+ * supplementary character range.
+ *
+ * @param codePoint a Unicode code point
+ *
+ * @return <code>true</code> if code point is in supplementary range
+ *
+ * @since 1.5
+ */
+ public static boolean isSupplementaryCodePoint(int codePoint)
+ {
+ return codePoint >= MIN_SUPPLEMENTARY_CODE_POINT
+ && codePoint <= MAX_CODE_POINT;
+ }
+
+ /**
+ * Determines whether the specified code point is
+ * in the range 0x0000 .. 0x10FFFF, i.e. it is a valid Unicode code point.
+ *
+ * @param codePoint a Unicode code point
+ *
+ * @return <code>true</code> if code point is valid
+ *
+ * @since 1.5
+ */
+ public static boolean isValidCodePoint(int codePoint)
+ {
+ return codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT;
+ }
+
+ /**
+ * Return true if the given character is a high surrogate.
+ * @param ch the character
+ * @return true if the character is a high surrogate character
+ *
+ * @since 1.5
+ */
+ public static boolean isHighSurrogate(char ch)
+ {
+ return ch >= MIN_HIGH_SURROGATE && ch <= MAX_HIGH_SURROGATE;
+ }
+
+ /**
+ * Return true if the given character is a low surrogate.
+ * @param ch the character
+ * @return true if the character is a low surrogate character
+ *
+ * @since 1.5
+ */
+ public static boolean isLowSurrogate(char ch)
+ {
+ return ch >= MIN_LOW_SURROGATE && ch <= MAX_LOW_SURROGATE;
+ }
+
+ /**
+ * Return true if the given characters compose a surrogate pair.
+ * This is true if the first character is a high surrogate and the
+ * second character is a low surrogate.
+ * @param ch1 the first character
+ * @param ch2 the first character
+ * @return true if the characters compose a surrogate pair
+ *
+ * @since 1.5
+ */
+ public static boolean isSurrogatePair(char ch1, char ch2)
+ {
+ return isHighSurrogate(ch1) && isLowSurrogate(ch2);
+ }
+
+ /**
+ * Given a valid surrogate pair, this returns the corresponding
+ * code point.
+ * @param high the high character of the pair
+ * @param low the low character of the pair
+ * @return the corresponding code point
+ *
+ * @since 1.5
+ */
+ public static int toCodePoint(char high, char low)
+ {
+ return ((high - MIN_HIGH_SURROGATE) * 0x400) +
+ (low - MIN_LOW_SURROGATE) + 0x10000;
+ }
+
+ /**
+ * Get the code point at the specified index in the CharSequence.
+ * This is like CharSequence#charAt(int), but if the character is
+ * the start of a surrogate pair, and there is a following
+ * character, and this character completes the pair, then the
+ * corresponding supplementary code point is returned. Otherwise,
+ * the character at the index is returned.
+ *
+ * @param sequence the CharSequence
+ * @param index the index of the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public static int codePointAt(CharSequence sequence, int index)
+ {
+ int len = sequence.length();
+ if (index < 0 || index >= len)
+ throw new IndexOutOfBoundsException();
+ char high = sequence.charAt(index);
+ if (! isHighSurrogate(high) || ++index >= len)
+ return high;
+ char low = sequence.charAt(index);
+ if (! isLowSurrogate(low))
+ return high;
+ return toCodePoint(high, low);
+ }
+
+ /**
+ * Get the code point at the specified index in the CharSequence.
+ * If the character is the start of a surrogate pair, and there is a
+ * following character, and this character completes the pair, then
+ * the corresponding supplementary code point is returned.
+ * Otherwise, the character at the index is returned.
+ *
+ * @param chars the character array in which to look
+ * @param index the index of the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public static int codePointAt(char[] chars, int index)
+ {
+ return codePointAt(chars, index, chars.length);
+ }
+
+ /**
+ * Get the code point at the specified index in the CharSequence.
+ * If the character is the start of a surrogate pair, and there is a
+ * following character within the specified range, and this
+ * character completes the pair, then the corresponding
+ * supplementary code point is returned. Otherwise, the character
+ * at the index is returned.
+ *
+ * @param chars the character array in which to look
+ * @param index the index of the codepoint to get, starting at 0
+ * @param limit the limit past which characters should not be examined
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;=
+ * limit, or if limit is negative or &gt;= the length of the array
+ * @since 1.5
+ */
+ public static int codePointAt(char[] chars, int index, int limit)
+ {
+ if (index < 0 || index >= limit || limit < 0 || limit > chars.length)
+ throw new IndexOutOfBoundsException();
+ char high = chars[index];
+ if (! isHighSurrogate(high) || ++index >= limit)
+ return high;
+ char low = chars[index];
+ if (! isLowSurrogate(low))
+ return high;
+ return toCodePoint(high, low);
+ }
+
+ /**
+ * Get the code point before the specified index. This is like
+ * #codePointAt(char[], int), but checks the characters at
+ * <code>index-1</code> and <code>index-2</code> to see if they form
+ * a supplementary code point. If they do not, the character at
+ * <code>index-1</code> is returned.
+ *
+ * @param chars the character array
+ * @param index the index just past the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public static int codePointBefore(char[] chars, int index)
+ {
+ return codePointBefore(chars, index, 1);
+ }
+
+ /**
+ * Get the code point before the specified index. This is like
+ * #codePointAt(char[], int), but checks the characters at
+ * <code>index-1</code> and <code>index-2</code> to see if they form
+ * a supplementary code point. If they do not, the character at
+ * <code>index-1</code> is returned. The start parameter is used to
+ * limit the range of the array which may be examined.
+ *
+ * @param chars the character array
+ * @param index the index just past the codepoint to get, starting at 0
+ * @param start the index before which characters should not be examined
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is &gt; start or &gt;
+ * the length of the array, or if limit is negative or &gt;= the
+ * length of the array
+ * @since 1.5
+ */
+ public static int codePointBefore(char[] chars, int index, int start)
+ {
+ if (index < start || index > chars.length
+ || start < 0 || start >= chars.length)
+ throw new IndexOutOfBoundsException();
+ --index;
+ char low = chars[index];
+ if (! isLowSurrogate(low) || --index < start)
+ return low;
+ char high = chars[index];
+ if (! isHighSurrogate(high))
+ return low;
+ return toCodePoint(high, low);
+ }
+
+ /**
+ * Get the code point before the specified index. This is like
+ * #codePointAt(CharSequence, int), but checks the characters at
+ * <code>index-1</code> and <code>index-2</code> to see if they form
+ * a supplementary code point. If they do not, the character at
+ * <code>index-1</code> is returned.
+ *
+ * @param sequence the CharSequence
+ * @param index the index just past the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public static int codePointBefore(CharSequence sequence, int index)
+ {
+ int len = sequence.length();
+ if (index < 1 || index > len)
+ throw new IndexOutOfBoundsException();
+ --index;
+ char low = sequence.charAt(index);
+ if (! isLowSurrogate(low) || --index < 0)
+ return low;
+ char high = sequence.charAt(index);
+ if (! isHighSurrogate(high))
+ return low;
+ return toCodePoint(high, low);
+ }
+} // class Character
diff --git a/libjava/java/lang/Class$1.h b/libjava/java/lang/Class$1.h
new file mode 100644
index 000000000..7c18cbb4e
--- /dev/null
+++ b/libjava/java/lang/Class$1.h
@@ -0,0 +1,24 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Class$1__
+#define __java_lang_Class$1__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Class$1 : public ::java::lang::Object
+{
+
+public: // actually package-private
+ Class$1(::java::lang::reflect::AccessibleObject *);
+public:
+ virtual ::java::lang::Object * run();
+private:
+ ::java::lang::reflect::AccessibleObject * __attribute__((aligned(__alignof__( ::java::lang::Object)))) val$obj;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Class$1__
diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h
new file mode 100644
index 000000000..d4a918483
--- /dev/null
+++ b/libjava/java/lang/Class.h
@@ -0,0 +1,758 @@
+// Class.h - Header file for java.lang.Class. -*- c++ -*-
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// Written primary using compiler source and Class.java as guides.
+#ifndef __JAVA_LANG_CLASS_H__
+#define __JAVA_LANG_CLASS_H__
+
+#pragma interface
+
+#include <stddef.h>
+#include <java/lang/Object.h>
+#include <java/lang/String.h>
+#include <java/net/URL.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/security/ProtectionDomain.h>
+#include <java/lang/Package.h>
+
+// Avoid including SystemClassLoader.h.
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class SystemClassLoader;
+ }
+ }
+ }
+}
+
+// We declare these here to avoid including gcj/cni.h.
+extern "C" void _Jv_InitClass (jclass klass);
+extern "C" jclass _Jv_NewClassFromInitializer
+ (const char *class_initializer);
+extern "C" void _Jv_RegisterNewClasses (char **classes);
+extern "C" void _Jv_RegisterClasses (const jclass *classes);
+extern "C" void _Jv_RegisterClasses_Counted (const jclass *classes,
+ size_t count);
+
+// This must be predefined with "C" linkage.
+extern "C" void *_Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface,
+ int meth_idx);
+extern "C" void *_Jv_ResolvePoolEntry (jclass this_class, jint index);
+
+// These are the possible values for the `state' field of the class
+// structure. Note that ordering is important here. Whenever the
+// state changes, one should notify all waiters of this class.
+enum
+{
+ JV_STATE_NOTHING = 0, // Set by compiler.
+
+ JV_STATE_PRELOADING = 1, // Can do _Jv_FindClass.
+
+ // There is an invariant through libgcj that a class will always be
+ // at a state greater than or equal to JV_STATE_LOADING when it is
+ // returned by a class loader to user code. Hence, defineclass.cc
+ // installs supers before returning a class, C++-ABI-compiled
+ // classes are created with supers installed, and BC-ABI-compiled
+ // classes are linked to this state before being returned by their
+ // class loader.
+ JV_STATE_LOADING = 3, // Has super installed.
+ JV_STATE_READ = 4, // Has been completely defined.
+ JV_STATE_LOADED = 5, // Has Miranda methods defined.
+
+ JV_STATE_COMPILED = 6, // This was a compiled class.
+
+ JV_STATE_PREPARED = 7, // Layout & static init done.
+ JV_STATE_LINKED = 9, // Strings interned.
+
+ JV_STATE_IN_PROGRESS = 10, // <clinit> running.
+
+ JV_STATE_ERROR = 12,
+
+ JV_STATE_PHANTOM = 13, // Bytecode is missing. In many cases we can
+ // work around that. If not, throw a
+ // NoClassDefFoundError.
+
+ JV_STATE_DONE = 14, // Must be last.
+
+
+};
+
+struct _Jv_Field;
+struct _Jv_VTable;
+union _Jv_word;
+struct _Jv_ArrayVTable;
+class _Jv_Linker;
+class _Jv_ExecutionEngine;
+class _Jv_CompiledEngine;
+class _Jv_IndirectCompiledEngine;
+
+#ifdef INTERPRETER
+class _Jv_InterpreterEngine;
+class _Jv_ClassReader;
+class _Jv_InterpClass;
+class _Jv_InterpMethod;
+#endif
+
+class _Jv_ClosureList
+{
+ _Jv_ClosureList *next;
+ void *ptr;
+public:
+ void registerClosure (jclass klass, void *ptr);
+ static void releaseClosures (_Jv_ClosureList **closures);
+};
+
+struct _Jv_Constants
+{
+ jint size;
+ jbyte *tags;
+ _Jv_word *data;
+};
+
+struct _Jv_Method
+{
+ // Method name.
+ _Jv_Utf8Const *name;
+ // Method signature.
+ _Jv_Utf8Const *signature;
+ // Access flags.
+ _Jv_ushort accflags;
+ // Method's index in the vtable.
+ _Jv_ushort index;
+ // Pointer to underlying function.
+ void *ncode;
+ // NULL-terminated list of exception class names; can be NULL if
+ // there are none such.
+ _Jv_Utf8Const **throws;
+
+ _Jv_Method *getNextMethod ()
+ { return this + 1; }
+};
+
+// The table used to resolve interface calls.
+struct _Jv_IDispatchTable
+{
+ // Index into interface's ioffsets.
+ jshort iindex;
+ jshort itable_length;
+ // Class Interface dispatch table.
+ void *itable[0];
+};
+
+// Used by _Jv_Linker::get_interfaces ()
+struct _Jv_ifaces
+{
+ jclass *list;
+ jshort len;
+ jshort count;
+};
+
+struct _Jv_MethodSymbol
+{
+ _Jv_Utf8Const *class_name;
+ _Jv_Utf8Const *name;
+ _Jv_Utf8Const *signature;
+};
+
+struct _Jv_OffsetTable
+{
+ jint state;
+ jint offsets[];
+};
+
+struct _Jv_AddressTable
+{
+ jint state;
+ void *addresses[];
+};
+
+struct _Jv_CatchClass
+{
+ java::lang::Class **address;
+ _Jv_Utf8Const *classname;
+};
+
+// Possible values for the assertion_code field in the type assertion table.
+enum
+{
+ JV_ASSERT_END_OF_TABLE = 0,
+ JV_ASSERT_TYPES_COMPATIBLE = 1,
+ JV_ASSERT_IS_INSTANTIABLE = 2
+};
+
+// Entry in the type assertion table, used to validate type constraints
+// for binary compatibility.
+struct _Jv_TypeAssertion
+{
+ jint assertion_code;
+ _Jv_Utf8Const *op1;
+ _Jv_Utf8Const *op2;
+};
+
+typedef enum
+{
+ JV_CLASS_ATTR,
+ JV_METHOD_ATTR,
+ JV_FIELD_ATTR,
+ JV_DONE_ATTR
+} jv_attr_type;
+
+typedef enum
+{
+ JV_INNER_CLASSES_KIND,
+ JV_ENCLOSING_METHOD_KIND,
+ JV_SIGNATURE_KIND,
+ JV_ANNOTATIONS_KIND,
+ JV_PARAMETER_ANNOTATIONS_KIND,
+ JV_ANNOTATION_DEFAULT_KIND
+} jv_attr_kind;
+
+#define JV_PRIMITIVE_VTABLE ((_Jv_VTable *) -1)
+
+#define JV_CLASS(Obj) ((jclass) (*(_Jv_VTable **) Obj)->clas)
+
+// Forward declarations for friends of java::lang::Class
+
+// Friend functions implemented in natClass.cc.
+_Jv_Method *_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature);
+jboolean _Jv_IsAssignableFrom (jclass, jclass);
+jboolean _Jv_IsAssignableFromSlow (jclass, jclass);
+jboolean _Jv_InterfaceAssignableFrom (jclass, jclass);
+
+_Jv_Method* _Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *,
+ _Jv_Utf8Const*, jclass * = NULL);
+java::lang::reflect::Method *_Jv_GetReflectedMethod (jclass klass,
+ _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature);
+jfieldID JvGetFirstInstanceField (jclass);
+jint JvNumInstanceFields (jclass);
+jfieldID JvGetFirstStaticField (jclass);
+jint JvNumStaticFields (jclass);
+
+jobject _Jv_AllocObject (jclass);
+void *_Jv_AllocObj (jint, jclass);
+void *_Jv_AllocPtrFreeObj (jint, jclass);
+void *_Jv_AllocArray (jint, jclass);
+
+bool _Jv_getInterfaceMethod(jclass, jclass&, int&,
+ const _Jv_Utf8Const*,
+ const _Jv_Utf8Const*);
+
+jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv *, jclass, jfieldID,
+ jboolean);
+jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID,
+ jboolean);
+jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);
+
+jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);
+jmethodID _Jv_FromReflectedConstructor (java::lang::reflect::Constructor *);
+jint JvNumMethods (jclass);
+jmethodID JvGetFirstMethod (jclass);
+_Jv_Utf8Const *_Jv_GetClassNameUtf8 (jclass);
+
+#ifdef INTERPRETER
+// Finds a desired interpreter method in the given class or NULL if not found
+class _Jv_MethodBase;
+_Jv_MethodBase *_Jv_FindInterpreterMethod (jclass, jmethodID);
+jstring _Jv_GetInterpClassSourceFile (jclass);
+#endif
+
+jbyte _Jv_GetClassState (jclass);
+
+void _Jv_RegisterClassHookDefault (jclass klass);
+void _Jv_RegisterInitiatingLoader (jclass,java::lang::ClassLoader*);
+void _Jv_UnregisterInitiatingLoader (jclass,java::lang::ClassLoader*);
+void _Jv_UnregisterClass (jclass);
+jclass _Jv_FindClassNoException (_Jv_Utf8Const *name,
+ java::lang::ClassLoader *loader);
+jclass _Jv_FindClass (_Jv_Utf8Const *name,
+ java::lang::ClassLoader *loader);
+jclass _Jv_FindClassInCache (_Jv_Utf8Const *name);
+jclass _Jv_PopClass (void);
+void _Jv_PushClass (jclass k);
+void _Jv_NewArrayClass (jclass element,
+ java::lang::ClassLoader *loader,
+ _Jv_VTable *array_vtable = 0);
+jclass _Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
+ java::lang::ClassLoader *loader);
+void _Jv_InitNewClassFields (jclass klass);
+
+// Friend functions and classes in prims.cc
+void _Jv_InitPrimClass (jclass, const char *, char, int);
+jstring _Jv_GetMethodString (jclass, _Jv_Method *, jclass = NULL);
+
+jboolean _Jv_CheckAccess (jclass self_klass, jclass other_klass,
+ jint flags);
+jclass _Jv_GetArrayClass (jclass klass, java::lang::ClassLoader *loader);
+
+jboolean _Jv_IsInterpretedClass (jclass);
+jboolean _Jv_IsBinaryCompatibilityABI (jclass);
+
+jboolean _Jv_IsPhantomClass (jclass);
+
+void _Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::SystemClassLoader *);
+
+#ifdef INTERPRETER
+void _Jv_InitField (jobject, jclass, int);
+#endif
+
+class _Jv_StackTrace;
+class _Jv_BytecodeVerifier;
+
+void _Jv_sharedlib_register_hook (jclass klass);
+
+/* Find the class that defines the given method. Returns NULL
+ if it cannot be found. Searches both interpreted and native
+ classes. */
+jclass _Jv_GetMethodDeclaringClass (jmethodID method);
+
+class java::lang::Class : public java::lang::Object
+{
+public:
+ static jclass forName (jstring className, jboolean initialize,
+ java::lang::ClassLoader *loader);
+ static jclass forName (jstring className);
+ JArray<jclass> *getClasses (void);
+
+ java::lang::ClassLoader *getClassLoader (void);
+private:
+ java::lang::ClassLoader *getClassLoader (jclass caller);
+public:
+ // This is an internal method that circumvents the usual security
+ // checks when getting the class loader.
+ java::lang::ClassLoader *getClassLoaderInternal (void)
+ {
+ return loader;
+ }
+
+ java::lang::reflect::Constructor *getConstructor (JArray<jclass> *);
+ JArray<java::lang::reflect::Constructor *> *getConstructors (void);
+ java::lang::reflect::Constructor *getDeclaredConstructor (JArray<jclass> *);
+ JArray<java::lang::reflect::Constructor *> *getDeclaredConstructors (jboolean);
+ java::lang::reflect::Field *getDeclaredField (jstring);
+ JArray<java::lang::reflect::Field *> *getDeclaredFields ();
+ JArray<java::lang::reflect::Field *> *getDeclaredFields (jboolean);
+ java::lang::reflect::Method *getDeclaredMethod (jstring, JArray<jclass> *);
+ JArray<java::lang::reflect::Method *> *getDeclaredMethods (void);
+
+ JArray<jclass> *getDeclaredClasses (void);
+ JArray<jclass> *getDeclaredClasses (jboolean);
+ jclass getDeclaringClass (void);
+
+ java::lang::reflect::Field *getField (jstring);
+private:
+ JArray<java::lang::reflect::Field *> internalGetFields ();
+ java::lang::reflect::Field *getField (jstring, jint);
+ jint _getMethods (JArray<java::lang::reflect::Method *> *result,
+ jint offset);
+ java::lang::reflect::Field *getPrivateField (jstring);
+ java::lang::reflect::Method *getPrivateMethod (jstring, JArray<jclass> *);
+ java::security::ProtectionDomain *getProtectionDomain0 ();
+
+ java::lang::reflect::Method *_getMethod (jstring, JArray<jclass> *);
+ java::lang::reflect::Method *_getDeclaredMethod (jstring, JArray<jclass> *);
+
+ jstring getReflectionSignature (jint /*jv_attr_type*/ type,
+ jint obj_index);
+ jstring getReflectionSignature (::java::lang::reflect::Method *);
+ jstring getReflectionSignature (::java::lang::reflect::Constructor *);
+ jstring getReflectionSignature (::java::lang::reflect::Field *);
+
+ jstring getClassSignature();
+ jobject getMethodDefaultValue (::java::lang::reflect::Method *);
+
+public:
+ JArray<java::lang::reflect::Field *> *getFields (void);
+
+ JArray<jclass> *getInterfaces (void);
+
+ void getSignature (java::lang::StringBuffer *buffer);
+ static jstring getSignature (JArray<jclass> *, jboolean is_constructor);
+ JArray<java::lang::reflect::Method *> *getMethods (void);
+
+ inline jint getModifiers (void)
+ {
+ return accflags & java::lang::reflect::Modifier::ALL_FLAGS;
+ }
+
+ jstring getName (void);
+
+ java::net::URL *getResource (jstring resourceName);
+ java::io::InputStream *getResourceAsStream (jstring resourceName);
+ JArray<jobject> *getSigners (void);
+ void setSigners(JArray<jobject> *);
+
+ inline jclass getSuperclass (void)
+ {
+ return superclass;
+ }
+
+ inline jclass getInterface (jint n)
+ {
+ return interfaces[n];
+ }
+
+ inline jboolean isArray (void)
+ {
+ return name->first() == '[';
+ }
+
+ inline jclass getComponentType (void)
+ {
+ return isArray () ? element_type : 0;
+ }
+
+ jboolean isAssignableFrom (jclass cls);
+ jboolean isInstance (jobject obj);
+
+ inline jboolean isInterface (void)
+ {
+ return (accflags & java::lang::reflect::Modifier::INTERFACE) != 0;
+ }
+
+ inline jboolean isPrimitive (void)
+ {
+ return vtable == JV_PRIMITIVE_VTABLE;
+ }
+
+ jobject newInstance (void);
+ java::security::ProtectionDomain *getProtectionDomain (void);
+ java::lang::Package *getPackage (void);
+ jstring toString (void);
+ jboolean desiredAssertionStatus (void);
+
+ JArray<java::lang::reflect::TypeVariable *> *getTypeParameters (void);
+
+ jint getEnclosingMethodData(void);
+ java::lang::Class *getEnclosingClass (void);
+ java::lang::reflect::Constructor *getEnclosingConstructor (void);
+ java::lang::reflect::Method *getEnclosingMethod (void);
+ jobjectArray getDeclaredAnnotations(jint, jint, jint);
+ jobjectArray getDeclaredAnnotations(::java::lang::reflect::Method *,
+ jboolean);
+ jobjectArray getDeclaredAnnotations(::java::lang::reflect::Constructor *,
+ jboolean);
+ jobjectArray getDeclaredAnnotations(::java::lang::reflect::Field *);
+ JArray< ::java::lang::annotation::Annotation *> *getDeclaredAnnotationsInternal();
+
+ jboolean isEnum (void)
+ {
+ return (accflags & 0x4000) != 0;
+ }
+ jboolean isSynthetic (void)
+ {
+ return (accflags & 0x1000) != 0;
+ }
+ jboolean isAnnotation (void)
+ {
+ return (accflags & 0x2000) != 0;
+ }
+
+ jboolean isAnonymousClass();
+ jboolean isLocalClass();
+ jboolean isMemberClass();
+
+ // FIXME: this probably shouldn't be public.
+ jint size (void)
+ {
+ return size_in_bytes;
+ }
+
+ // The index of the first method we declare ourself (as opposed to
+ // inheriting).
+ inline jint firstMethodIndex (void)
+ {
+ return vtable_method_count - method_count;
+ }
+
+ // finalization
+ void finalize ();
+
+ // This constructor is used to create Class object for the primitive
+ // types. See prims.cc.
+ Class ();
+
+ // Given the BC ABI version, return the size of an Class initializer.
+ static jlong initializerSize (jlong ABI)
+ {
+ unsigned long version = ABI & 0xfffff;
+ int abi_rev = version % 100;
+
+ // The reflection_data field was added by abi_rev 1.
+ if (abi_rev == 0)
+ return ((char*)(&::java::lang::Class::class$.reflection_data)
+ - (char*)&::java::lang::Class::class$);
+
+ return sizeof (::java::lang::Class);
+ }
+
+ static java::lang::Class class$;
+
+private:
+
+ void memberAccessCheck (jint flags);
+
+ void initializeClass (void);
+
+ static jstring getPackagePortion (jstring);
+
+ void set_state (jint nstate)
+ {
+ state = nstate;
+ notifyAll ();
+ }
+
+ jint findInnerClassAttribute();
+ jint findDeclaredClasses(JArray<jclass> *, jboolean, jint);
+
+ // Friend functions implemented in natClass.cc.
+ friend _Jv_Method *::_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature);
+ friend jboolean (::_Jv_IsAssignableFrom) (jclass, jclass);
+ friend jboolean (::_Jv_IsAssignableFromSlow) (jclass, jclass);
+ friend jboolean (::_Jv_InterfaceAssignableFrom) (jclass, jclass);
+ friend void *::_Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface,
+ int method_idx);
+
+ friend void ::_Jv_InitClass (jclass klass);
+ friend java::lang::Class* ::_Jv_NewClassFromInitializer (const char *class_initializer);
+ friend void _Jv_RegisterNewClasses (void **classes);
+
+ friend _Jv_Method* ::_Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *,
+ _Jv_Utf8Const*, jclass *);
+ friend java::lang::reflect::Method* ::_Jv_GetReflectedMethod (jclass klass,
+ _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature);
+ friend jfieldID (::JvGetFirstInstanceField) (jclass);
+ friend jint (::JvNumInstanceFields) (jclass);
+ friend jfieldID (::JvGetFirstStaticField) (jclass);
+ friend jint (::JvNumStaticFields) (jclass);
+
+ friend jobject (::_Jv_AllocObject) (jclass);
+ friend void *::_Jv_AllocObj (jint, jclass);
+ friend void *::_Jv_AllocPtrFreeObj (jint, jclass);
+ friend void *::_Jv_AllocArray (jint, jclass);
+
+ friend jobject (::_Jv_JNI_ToReflectedField) (_Jv_JNIEnv *, jclass, jfieldID,
+ jboolean);
+ friend jobject (::_Jv_JNI_ToReflectedMethod) (_Jv_JNIEnv *, jclass, jmethodID,
+ jboolean);
+ friend jfieldID (::_Jv_FromReflectedField) (java::lang::reflect::Field *);
+
+ friend jmethodID (::_Jv_FromReflectedMethod) (java::lang::reflect::Method *);
+ friend jmethodID (::_Jv_FromReflectedConstructor) (java::lang::reflect::Constructor *);
+ friend jint (::JvNumMethods) (jclass);
+ friend jmethodID (::JvGetFirstMethod) (jclass);
+ friend _Jv_Utf8Const *::_Jv_GetClassNameUtf8 (jclass);
+#ifdef INTERPRETER
+ friend _Jv_MethodBase *(::_Jv_FindInterpreterMethod) (jclass klass,
+ jmethodID desired_method);
+ friend jstring ::_Jv_GetInterpClassSourceFile (jclass);
+#endif
+ friend jbyte (::_Jv_GetClassState) (jclass klass);
+
+ // Friends classes and functions to implement the ClassLoader
+ friend class java::lang::ClassLoader;
+ friend class java::lang::VMClassLoader;
+
+ friend class java::io::ObjectOutputStream;
+ friend class java::io::ObjectInputStream;
+ friend class java::io::ObjectStreamClass;
+
+ friend void ::_Jv_RegisterClasses (const jclass *classes);
+ friend void ::_Jv_RegisterClasses_Counted (const jclass *classes,
+ size_t count);
+ friend void ::_Jv_RegisterClassHookDefault (jclass klass);
+ friend void ::_Jv_RegisterInitiatingLoader (jclass,java::lang::ClassLoader*);
+ friend void ::_Jv_UnregisterInitiatingLoader (jclass,java::lang::ClassLoader*);
+ friend void ::_Jv_UnregisterClass (jclass);
+ friend jclass (::_Jv_FindClassNoException) (_Jv_Utf8Const *name,
+ java::lang::ClassLoader *loader);
+ friend jclass (::_Jv_FindClass) (_Jv_Utf8Const *name,
+ java::lang::ClassLoader *loader);
+ friend jclass (::_Jv_FindClassInCache) (_Jv_Utf8Const *name);
+ friend jclass (::_Jv_PopClass) (void);
+ friend void ::_Jv_PushClass (jclass k);
+ friend void ::_Jv_NewArrayClass (jclass element,
+ java::lang::ClassLoader *loader,
+ _Jv_VTable *array_vtable);
+ friend jclass (::_Jv_NewClass) (_Jv_Utf8Const *name, jclass superclass,
+ java::lang::ClassLoader *loader);
+ friend void ::_Jv_InitNewClassFields (jclass klass);
+
+ // in prims.cc
+ friend void ::_Jv_InitPrimClass (jclass, const char *, char, int);
+
+ friend jstring (::_Jv_GetMethodString) (jclass, _Jv_Method *, jclass);
+
+ friend jboolean (::_Jv_CheckAccess) (jclass self_klass, jclass other_klass,
+ jint flags);
+
+ friend bool (::_Jv_getInterfaceMethod) (jclass, jclass&, int&,
+ const _Jv_Utf8Const*,
+ const _Jv_Utf8Const*);
+
+ friend jclass (::_Jv_GetArrayClass) (jclass klass,
+ java::lang::ClassLoader *loader);
+
+ friend jboolean (::_Jv_IsInterpretedClass) (jclass);
+ friend jboolean (::_Jv_IsBinaryCompatibilityABI) (jclass);
+
+ friend jboolean (::_Jv_IsPhantomClass) (jclass);
+
+#ifdef INTERPRETER
+ friend void ::_Jv_InitField (jobject, jclass, int);
+
+ friend class ::_Jv_ClassReader;
+ friend class ::_Jv_InterpClass;
+ friend class ::_Jv_InterpMethod;
+ friend class ::_Jv_InterpreterEngine;
+#endif
+ friend class ::_Jv_StackTrace;
+
+#ifdef JV_MARKOBJ_DECL
+ friend JV_MARKOBJ_DECL;
+#endif
+
+ friend class ::_Jv_BytecodeVerifier;
+ friend class java::io::VMObjectStreamClass;
+
+ friend class ::_Jv_Linker;
+ friend class ::_Jv_ExecutionEngine;
+ friend class ::_Jv_CompiledEngine;
+ friend class ::_Jv_IndirectCompiledEngine;
+ friend class ::_Jv_ClosureList;
+
+ friend void ::_Jv_sharedlib_register_hook (jclass klass);
+
+ friend void *::_Jv_ResolvePoolEntry (jclass this_class, jint index);
+
+ friend void ::_Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::SystemClassLoader *);
+
+ friend class java::lang::reflect::Field;
+ friend class java::lang::reflect::Method;
+ friend class java::lang::reflect::Constructor;
+ friend class java::lang::reflect::VMProxy;
+
+ // Chain for class pool. This also doubles as the ABI version
+ // number. It is only used for this purpose at class registration
+ // time, and only for precompiled classes.
+ jclass next_or_version;
+ // Name of class.
+ _Jv_Utf8Const *name;
+ // Access flags for class.
+ _Jv_ushort accflags;
+ // The superclass, or null for Object.
+ jclass superclass;
+ // Class constants.
+ _Jv_Constants constants;
+ // Methods. If this is an array class, then this field holds a
+ // pointer to the element type.
+ union
+ {
+ _Jv_Method *methods;
+ jclass element_type;
+ };
+ // Number of methods. If this class is primitive, this holds the
+ // character used to represent this type in a signature.
+ jshort method_count;
+ // Number of methods in the vtable.
+ jshort vtable_method_count;
+ // The fields.
+ _Jv_Field *fields;
+ // Size of instance fields, in bytes.
+ jint size_in_bytes;
+ // Total number of fields (instance and static).
+ jshort field_count;
+ // Number of static fields.
+ jshort static_field_count;
+ // The vtbl for all objects of this class.
+ _Jv_VTable *vtable;
+ // Virtual method offset table.
+ _Jv_OffsetTable *otable;
+ // Offset table symbols.
+ _Jv_MethodSymbol *otable_syms;
+ // Address table
+ _Jv_AddressTable *atable;
+ _Jv_MethodSymbol *atable_syms;
+ // Interface table
+ _Jv_AddressTable *itable;
+ _Jv_MethodSymbol *itable_syms;
+ _Jv_CatchClass *catch_classes;
+ // Interfaces implemented by this class.
+ jclass *interfaces;
+ // The class loader for this class.
+ java::lang::ClassLoader *loader;
+ // Number of interfaces.
+ jshort interface_count;
+ // State of this class.
+ jbyte state;
+ // The thread which has locked this class. Used during class
+ // initialization.
+ java::lang::Thread *thread;
+ // How many levels of "extends" this class is removed from Object.
+ jshort depth;
+ // Vector of this class's superclasses, ordered by decreasing depth.
+ jclass *ancestors;
+ // In a regular class, this field points to the Class Interface Dispatch
+ // Table. In an interface, it points to the ioffsets table.
+ union
+ {
+ _Jv_IDispatchTable *idt;
+ jshort *ioffsets;
+ };
+ // Pointer to the class that represents an array of this class.
+ jclass arrayclass;
+ // Security Domain to which this class belongs (or null).
+ java::security::ProtectionDomain *protectionDomain;
+ // Pointer to the type assertion table for this class.
+ _Jv_TypeAssertion *assertion_table;
+ // Signers of this class (or null).
+ JArray<jobject> *hack_signers;
+ // Used by Jv_PopClass and _Jv_PushClass to communicate with StackTrace.
+ jclass chain;
+ // Additional data, specific to the generator (JIT, native,
+ // interpreter) of this class.
+ void *aux_info;
+ // Execution engine.
+ _Jv_ExecutionEngine *engine;
+ // Reflection data.
+ unsigned char *reflection_data;
+};
+
+// Inline functions that are friends of java::lang::Class
+
+inline void _Jv_InitClass (jclass klass)
+{
+ if (__builtin_expect (klass->state == JV_STATE_DONE, true))
+ return;
+ klass->initializeClass ();
+}
+
+// Return array class corresponding to element type KLASS, creating it if
+// necessary.
+inline jclass
+_Jv_GetArrayClass (jclass klass, java::lang::ClassLoader *loader)
+{
+ extern void _Jv_NewArrayClass (jclass element,
+ java::lang::ClassLoader *loader,
+ _Jv_VTable *array_vtable = 0);
+ if (__builtin_expect (!klass->arrayclass, false))
+ _Jv_NewArrayClass (klass, loader);
+ return klass->arrayclass;
+}
+
+#endif /* __JAVA_LANG_CLASS_H__ */
diff --git a/libjava/java/lang/Class.java b/libjava/java/lang/Class.java
new file mode 100644
index 000000000..a4e8ee592
--- /dev/null
+++ b/libjava/java/lang/Class.java
@@ -0,0 +1,1430 @@
+/* Class.java -- Representation of a Java class.
+ Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+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.reflect.ClassSignatureParser;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericDeclaration;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.HashMap;
+import java.util.Collection;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Inherited;
+import java.lang.reflect.AccessibleObject;
+
+/**
+ * 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.
+ *
+ * <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>[&lt;signature format&gt;;</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 (ebb9@email.byu.edu)
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @since 1.0
+ * @see ClassLoader
+ */
+public final class Class<T>
+ implements Type, AnnotatedElement, GenericDeclaration, Serializable
+{
+ /**
+ * Class is non-instantiable from Java code; only the VM can create
+ * instances of this class.
+ */
+ private Class ()
+ {
+ }
+
+ // Initialize the class.
+ private native void initializeClass ();
+
+ // finalization
+ protected native void finalize () throws Throwable;
+
+ /**
+ * Use the classloader of the current class to load, link, and initialize
+ * a class. This is equivalent to your code calling
+ * <code>Class.forName(name, true, getClass().getClassLoader())</code>.
+ *
+ * @param name the name of the class to find
+ * @return the Class object representing the class
+ * @throws ClassNotFoundException if the class was not found by the
+ * classloader
+ * @throws LinkageError if linking the class fails
+ * @throws ExceptionInInitializerError if the class loads, but an exception
+ * occurs during initialization
+ */
+ public static native Class<?> forName (String className)
+ throws ClassNotFoundException;
+
+ // A private internal method that is called by compiler-generated code.
+ private static Class forName (String className, Class caller)
+ throws ClassNotFoundException
+ {
+ return forName(className, true, caller.getClassLoaderInternal());
+ }
+
+
+ /**
+ * Use the specified classloader to load and link a class. If the loader
+ * is null, this uses the bootstrap class loader (provide the security
+ * check succeeds). Unfortunately, this method cannot be used to obtain
+ * the Class objects for primitive types or for void, you have to use
+ * the fields in the appropriate java.lang wrapper classes.
+ *
+ * <p>Calls <code>classloader.loadclass(name, initialize)</code>.
+ *
+ * @param name the name of the class to find
+ * @param initialize whether or not to initialize the class at this time
+ * @param classloader the classloader to use to find the class; null means
+ * to use the bootstrap class loader
+ * @throws ClassNotFoundException if the class was not found by the
+ * classloader
+ * @throws LinkageError if linking the class fails
+ * @throws ExceptionInInitializerError if the class loads, but an exception
+ * occurs during initialization
+ * @throws SecurityException if the <code>classloader</code> argument
+ * is <code>null</code> and the caller does not have the
+ * <code>RuntimePermission("getClassLoader")</code> permission
+ * @see ClassLoader
+ * @since 1.2
+ */
+ public static native Class<?> forName (String className, boolean initialize,
+ ClassLoader loader)
+ throws ClassNotFoundException;
+
+ /**
+ * Get all the public member classes and interfaces declared in this
+ * class or inherited from superclasses. This returns an array of length
+ * 0 if there are no member classes, including for primitive types. A
+ * security check may be performed, with
+ * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return all public member classes in this class
+ * @throws SecurityException if the security check fails
+ * @since 1.1
+ */
+ public Class<?>[] getClasses()
+ {
+ memberAccessCheck(Member.PUBLIC);
+ return internalGetClasses();
+ }
+
+ /**
+ * Like <code>getClasses()</code> but without the security checks.
+ */
+ private Class<?>[] internalGetClasses()
+ {
+ ArrayList<Class> list = new ArrayList<Class>();
+ list.addAll(Arrays.asList(getDeclaredClasses(true)));
+ Class superClass = getSuperclass();
+ if (superClass != null)
+ list.addAll(Arrays.asList(superClass.internalGetClasses()));
+ return list.toArray(new Class<?>[list.size()]);
+ }
+
+ /**
+ * Get the ClassLoader that loaded this class. If the class was loaded
+ * by the bootstrap classloader, this method will return null.
+ * If there is a security manager, and the caller's class loader is not
+ * an ancestor of the requested one, a security check of
+ * <code>RuntimePermission("getClassLoader")</code>
+ * must first succeed. Primitive types and void return null.
+ *
+ * @return the ClassLoader that loaded this class
+ * @throws SecurityException if the security check fails
+ * @see ClassLoader
+ * @see RuntimePermission
+ */
+ public native ClassLoader getClassLoader ();
+
+ // A private internal method that is called by compiler-generated code.
+ private final native ClassLoader getClassLoader (Class caller);
+
+ /**
+ * Internal method that circumvents the usual security checks when
+ * getting the class loader.
+ */
+ private native ClassLoader getClassLoaderInternal ();
+
+ /**
+ * If this is an array, get the Class representing the type of array.
+ * Examples: "[[Ljava.lang.String;" would return "[Ljava.lang.String;", and
+ * calling getComponentType on that would give "java.lang.String". If
+ * this is not an array, returns null.
+ *
+ * @return the array type of this class, or null
+ * @see Array
+ * @since 1.1
+ */
+ public native Class<?> getComponentType ();
+
+ /**
+ * Get a public constructor declared in this class. If the constructor takes
+ * no argument, an array of zero elements and null are equivalent for the
+ * types argument. A security check may be performed, with
+ * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @param types the type of each parameter
+ * @return the constructor
+ * @throws NoSuchMethodException if the constructor does not exist
+ * @throws SecurityException if the security check fails
+ * @see #getConstructors()
+ * @since 1.1
+ */
+ public native Constructor<T> getConstructor(Class<?>... args)
+ throws NoSuchMethodException;
+
+ /**
+ * Get all the public constructors of this class. This returns an array of
+ * length 0 if there are no constructors, including for primitive types,
+ * arrays, and interfaces. It does, however, include the default
+ * constructor if one was supplied by the compiler. A security check may
+ * be performed, with <code>checkMemberAccess(this, Member.PUBLIC)</code>
+ * as well as <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return all public constructors in this class
+ * @throws SecurityException if the security check fails
+ * @since 1.1
+ */
+ public Constructor<?>[] getConstructors()
+ {
+ memberAccessCheck(Member.PUBLIC);
+ return getDeclaredConstructors(true);
+ }
+
+ /**
+ * Get a constructor declared in this class. If the constructor takes no
+ * argument, an array of zero elements and null are equivalent for the
+ * types argument. A security check may be performed, with
+ * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @param types the type of each parameter
+ * @return the constructor
+ * @throws NoSuchMethodException if the constructor does not exist
+ * @throws SecurityException if the security check fails
+ * @see #getDeclaredConstructors()
+ * @since 1.1
+ */
+ public native Constructor<T> getDeclaredConstructor(Class<?>... args)
+ throws NoSuchMethodException;
+
+ /**
+ * Get all the declared member classes and interfaces in this class, but
+ * not those inherited from superclasses. This returns an array of length
+ * 0 if there are no member classes, including for primitive types. A
+ * security check may be performed, with
+ * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return all declared member classes in this class
+ * @throws SecurityException if the security check fails
+ * @since 1.1
+ */
+ public Class<?>[] getDeclaredClasses()
+ {
+ memberAccessCheck(Member.DECLARED);
+ return getDeclaredClasses(false);
+ }
+
+ native Class<?>[] getDeclaredClasses (boolean publicOnly);
+
+ /**
+ * Get all the declared constructors of this class. This returns an array of
+ * length 0 if there are no constructors, including for primitive types,
+ * arrays, and interfaces. It does, however, include the default
+ * constructor if one was supplied by the compiler. A security check may
+ * be performed, with <code>checkMemberAccess(this, Member.DECLARED)</code>
+ * as well as <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return all constructors in this class
+ * @throws SecurityException if the security check fails
+ * @since 1.1
+ */
+ public Constructor<?>[] getDeclaredConstructors()
+ {
+ memberAccessCheck(Member.DECLARED);
+ return getDeclaredConstructors(false);
+ }
+
+ native Constructor<?>[] getDeclaredConstructors (boolean publicOnly);
+
+ /**
+ * Get a field declared in this class, where name is its simple name. The
+ * implicit length field of arrays is not available. A security check may
+ * be performed, with <code>checkMemberAccess(this, Member.DECLARED)</code>
+ * as well as <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @param name the name of the field
+ * @return the field
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws SecurityException if the security check fails
+ * @see #getDeclaredFields()
+ * @since 1.1
+ */
+ public native Field getDeclaredField(String fieldName)
+ throws NoSuchFieldException;
+
+ /**
+ * Get all the declared fields in this class, but not those inherited from
+ * superclasses. This returns an array of length 0 if there are no fields,
+ * including for primitive types. This does not return the implicit length
+ * field of arrays. A security check may be performed, with
+ * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return all declared fields in this class
+ * @throws SecurityException if the security check fails
+ * @since 1.1
+ */
+ public Field[] getDeclaredFields()
+ {
+ memberAccessCheck(Member.DECLARED);
+ return getDeclaredFields(false);
+ }
+
+ native Field[] getDeclaredFields (boolean publicOnly);
+
+ private native Method _getDeclaredMethod(String methodName, Class[] args);
+
+ /**
+ * Get a method declared in this class, where name is its simple name. The
+ * implicit methods of Object are not available from arrays or interfaces.
+ * Constructors (named "&lt;init&gt;" in the class file) and class initializers
+ * (name "&lt;clinit&gt;") are not available. The Virtual Machine allows
+ * multiple methods with the same signature but differing return types; in
+ * such a case the most specific return types are favored, then the final
+ * choice is arbitrary. If the method takes no argument, an array of zero
+ * elements and null are equivalent for the types argument. A security
+ * check may be performed, with
+ * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @param methodName the name of the method
+ * @param types the type of each parameter
+ * @return the method
+ * @throws NoSuchMethodException if the method does not exist
+ * @throws SecurityException if the security check fails
+ * @see #getDeclaredMethods()
+ * @since 1.1
+ */
+ public Method getDeclaredMethod(String methodName, Class<?>... args)
+ throws NoSuchMethodException
+ {
+ memberAccessCheck(Member.DECLARED);
+
+ if ("<init>".equals(methodName) || "<clinit>".equals(methodName))
+ throw new NoSuchMethodException(methodName);
+
+ Method match = _getDeclaredMethod(methodName, args);
+ if (match == null)
+ throw new NoSuchMethodException(methodName);
+ return match;
+ }
+
+ /**
+ * Get all the declared methods in this class, but not those inherited from
+ * superclasses. This returns an array of length 0 if there are no methods,
+ * including for primitive types. This does include the implicit methods of
+ * arrays and interfaces which mirror methods of Object, nor does it
+ * include constructors or the class initialization methods. The Virtual
+ * Machine allows multiple methods with the same signature but differing
+ * return types; all such methods are in the returned array. A security
+ * check may be performed, with
+ * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return all declared methods in this class
+ * @throws SecurityException if the security check fails
+ * @since 1.1
+ */
+ public native Method[] getDeclaredMethods();
+
+ /**
+ * If this is a nested or inner class, return the class that declared it.
+ * If not, return null.
+ *
+ * @return the declaring class of this class
+ * @since 1.1
+ */
+ // This is marked as unimplemented in the JCL book.
+ public native Class<?> getDeclaringClass ();
+
+ private native Field getField (String fieldName, int hash)
+ throws NoSuchFieldException;
+
+ /**
+ * Get a public field declared or inherited in this class, where name is
+ * its simple name. If the class contains multiple accessible fields by
+ * that name, an arbitrary one is returned. The implicit length field of
+ * arrays is not available. A security check may be performed, with
+ * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @param fieldName the name of the field
+ * @return the field
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws SecurityException if the security check fails
+ * @see #getFields()
+ * @since 1.1
+ */
+ public Field getField(String fieldName)
+ throws NoSuchFieldException
+ {
+ memberAccessCheck(Member.PUBLIC);
+ Field field = getField(fieldName, fieldName.hashCode());
+ if (field == null)
+ throw new NoSuchFieldException(fieldName);
+ return field;
+ }
+
+ /**
+ * Get all the public fields declared in this class or inherited from
+ * superclasses. This returns an array of length 0 if there are no fields,
+ * including for primitive types. This does not return the implicit length
+ * field of arrays. A security check may be performed, with
+ * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return all public fields in this class
+ * @throws SecurityException if the security check fails
+ * @since 1.1
+ */
+ public Field[] getFields()
+ {
+ memberAccessCheck(Member.PUBLIC);
+ return internalGetFields();
+ }
+
+ /**
+ * Like <code>getFields()</code> but without the security checks.
+ */
+ private Field[] internalGetFields()
+ {
+ LinkedHashSet set = new LinkedHashSet();
+ set.addAll(Arrays.asList(getDeclaredFields(true)));
+ Class[] interfaces = getInterfaces();
+ for (int i = 0; i < interfaces.length; i++)
+ set.addAll(Arrays.asList(interfaces[i].internalGetFields()));
+ Class superClass = getSuperclass();
+ if (superClass != null)
+ set.addAll(Arrays.asList(superClass.internalGetFields()));
+ return (Field[])set.toArray(new Field[set.size()]);
+ }
+
+ /**
+ * Returns the <code>Package</code> in which this class is defined
+ * Returns null when this information is not available from the
+ * classloader of this class.
+ *
+ * @return the package for this class, if it is available
+ * @since 1.2
+ */
+ public Package getPackage()
+ {
+ ClassLoader cl = getClassLoaderInternal();
+ if (cl != null)
+ return cl.getPackage(getPackagePortion(getName()));
+ else
+ return VMClassLoader.getPackage(getPackagePortion(getName()));
+ }
+
+ /**
+ * Get the interfaces this class <em>directly</em> implements, in the
+ * order that they were declared. This returns an empty array, not null,
+ * for Object, primitives, void, and classes or interfaces with no direct
+ * superinterface. Array types return Cloneable and Serializable.
+ *
+ * @return the interfaces this class directly implements
+ */
+ public native Class<?>[] getInterfaces ();
+
+ private final native void getSignature(StringBuffer buffer);
+ private static final native String getSignature(Class[] args,
+ boolean is_construtor);
+
+ public native Method _getMethod(String methodName, Class[] args);
+
+ /**
+ * Get a public method declared or inherited in this class, where name is
+ * its simple name. The implicit methods of Object are not available from
+ * interfaces. Constructors (named "&lt;init&gt;" in the class file) and class
+ * initializers (name "&lt;clinit&gt;") are not available. The Virtual
+ * Machine allows multiple methods with the same signature but differing
+ * return types, and the class can inherit multiple methods of the same
+ * return type; in such a case the most specific return types are favored,
+ * then the final choice is arbitrary. If the method takes no argument, an
+ * array of zero elements and null are equivalent for the types argument.
+ * A security check may be performed, with
+ * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @param methodName the name of the method
+ * @param types the type of each parameter
+ * @return the method
+ * @throws NoSuchMethodException if the method does not exist
+ * @throws SecurityException if the security check fails
+ * @see #getMethods()
+ * @since 1.1
+ */
+ public Method getMethod(String methodName, Class<?>... args)
+ throws NoSuchMethodException
+ {
+ memberAccessCheck(Member.PUBLIC);
+
+ if ("<init>".equals(methodName) || "<clinit>".equals(methodName))
+ throw new NoSuchMethodException(methodName);
+
+ Method method = _getMethod(methodName, args);
+ if (method == null)
+ throw new NoSuchMethodException(methodName);
+ return method;
+ }
+
+ private native int _getMethods (Method[] result, int offset);
+
+ /**
+ * Get all the public methods declared in this class or inherited from
+ * superclasses. This returns an array of length 0 if there are no methods,
+ * including for primitive types. This does not include the implicit
+ * methods of interfaces which mirror methods of Object, nor does it
+ * include constructors or the class initialization methods. The Virtual
+ * Machine allows multiple methods with the same signature but differing
+ * return types; all such methods are in the returned array. A security
+ * check may be performed, with
+ * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return all public methods in this class
+ * @throws SecurityException if the security check fails
+ * @since 1.1
+ */
+ public native Method[] getMethods();
+
+ /**
+ * Get the modifiers of this class. These can be decoded using Modifier,
+ * and is limited to one of public, protected, or private, and any of
+ * final, static, abstract, or interface. An array class has the same
+ * public, protected, or private modifier as its component type, and is
+ * marked final but not an interface. Primitive types and void are marked
+ * public and final, but not an interface.
+ *
+ * @return the modifiers of this class
+ * @see Modifer
+ * @since 1.1
+ */
+ public native int getModifiers ();
+
+ /**
+ * Get the name of this class, separated by dots for package separators.
+ * If the class represents a primitive type, or void, then the
+ * name of the type as it appears in the Java programming language
+ * is returned. For instance, <code>Byte.TYPE.getName()</code>
+ * returns "byte".
+ *
+ * Arrays are specially encoded as shown on this table.
+ * <pre>
+ * array type [<em>element type</em>
+ * (note that the element type is encoded per
+ * this table)
+ * boolean Z
+ * byte B
+ * char C
+ * short S
+ * int I
+ * long J
+ * float F
+ * double D
+ * void V
+ * class or interface, alone: &lt;dotted name&gt;
+ * class or interface, as element type: L&lt;dotted name&gt;;
+ * </pre>
+ *
+ * @return the name of this class
+ */
+ public native String getName ();
+
+ /**
+ * Get a resource URL using this class's package using the
+ * getClassLoader().getResource() method. If this class was loaded using
+ * the system classloader, ClassLoader.getSystemResource() is used instead.
+ *
+ * <p>If the name you supply is absolute (it starts with a <code>/</code>),
+ * then the leading <code>/</code> is removed and it is passed on to
+ * getResource(). If it is relative, the package name is prepended, and
+ * <code>.</code>'s are replaced with <code>/</code>.
+ *
+ * <p>The URL returned is system- and classloader-dependent, and could
+ * change across implementations.
+ *
+ * @param resourceName the name of the resource, generally a path
+ * @return the URL to the resource
+ * @throws NullPointerException if name is null
+ * @since 1.1
+ */
+ public URL getResource(String resourceName)
+ {
+ String name = resourcePath(resourceName);
+ ClassLoader loader = getClassLoaderInternal();
+ if (loader == null)
+ return ClassLoader.getSystemResource(name);
+ return loader.getResource(name);
+ }
+
+ /**
+ * Get a resource using this class's package using the
+ * getClassLoader().getResourceAsStream() method. If this class was loaded
+ * using the system classloader, ClassLoader.getSystemResource() is used
+ * instead.
+ *
+ * <p>If the name you supply is absolute (it starts with a <code>/</code>),
+ * then the leading <code>/</code> is removed and it is passed on to
+ * getResource(). If it is relative, the package name is prepended, and
+ * <code>.</code>'s are replaced with <code>/</code>.
+ *
+ * <p>The URL returned is system- and classloader-dependent, and could
+ * change across implementations.
+ *
+ * @param resourceName the name of the resource, generally a path
+ * @return an InputStream with the contents of the resource in it, or null
+ * @throws NullPointerException if name is null
+ * @since 1.1
+ */
+ public InputStream getResourceAsStream(String resourceName)
+ {
+ String name = resourcePath(resourceName);
+ ClassLoader loader = getClassLoaderInternal();
+ if (loader == null)
+ return ClassLoader.getSystemResourceAsStream(name);
+ return loader.getResourceAsStream(name);
+ }
+
+ private String resourcePath(String resourceName)
+ {
+ if (resourceName.length() > 0)
+ {
+ if (resourceName.charAt(0) != '/')
+ {
+ String pkg = getPackagePortion(getName());
+ if (pkg.length() > 0)
+ resourceName = pkg.replace('.','/') + '/' + resourceName;
+ }
+ else
+ {
+ resourceName = resourceName.substring(1);
+ }
+ }
+ return resourceName;
+ }
+
+ /**
+ * Get the signers of this class. This returns null if there are no signers,
+ * such as for primitive types or void.
+ *
+ * @return the signers of this class
+ * @since 1.1
+ */
+ public native Object[] getSigners ();
+
+ /**
+ * Set the signers of this class.
+ *
+ * @param signers the signers of this class
+ */
+ native void setSigners(Object[] signers);
+
+ /**
+ * Get the direct superclass of this class. If this is an interface,
+ * Object, a primitive type, or void, it will return null. If this is an
+ * array type, it will return Object.
+ *
+ * @return the direct superclass of this class
+ */
+ public native Class<? super T> getSuperclass ();
+
+ /**
+ * Return whether this class is an array type.
+ *
+ * @return whether this class is an array type
+ * @since 1.1
+ */
+ public native boolean isArray ();
+
+ /**
+ * Discover whether an instance of the Class parameter would be an
+ * instance of this Class as well. Think of doing
+ * <code>isInstance(c.newInstance())</code> or even
+ * <code>c.newInstance() instanceof (this class)</code>. While this
+ * checks widening conversions for objects, it must be exact for primitive
+ * types.
+ *
+ * @param c the class to check
+ * @return whether an instance of c would be an instance of this class
+ * as well
+ * @throws NullPointerException if c is null
+ * @since 1.1
+ */
+ public native boolean isAssignableFrom (Class<?> c);
+
+ /**
+ * Discover whether an Object is an instance of this Class. Think of it
+ * as almost like <code>o instanceof (this class)</code>.
+ *
+ * @param o the Object to check
+ * @return whether o is an instance of this class
+ * @since 1.1
+ */
+ public native boolean isInstance (Object o);
+
+ /**
+ * Check whether this class is an interface or not. Array types are not
+ * interfaces.
+ *
+ * @return whether this class is an interface or not
+ */
+ public native boolean isInterface ();
+
+ /**
+ * Return whether this class is a primitive type. A primitive type class
+ * is a class representing a kind of "placeholder" for the various
+ * primitive types, or void. You can access the various primitive type
+ * classes through java.lang.Boolean.TYPE, java.lang.Integer.TYPE, etc.,
+ * or through boolean.class, int.class, etc.
+ *
+ * @return whether this class is a primitive type
+ * @see Boolean#TYPE
+ * @see Byte#TYPE
+ * @see Character#TYPE
+ * @see Short#TYPE
+ * @see Integer#TYPE
+ * @see Long#TYPE
+ * @see Float#TYPE
+ * @see Double#TYPE
+ * @see Void#TYPE
+ * @since 1.1
+ */
+ public native boolean isPrimitive ();
+
+ /**
+ * Get a new instance of this class by calling the no-argument constructor.
+ * The class is initialized if it has not been already. A security check
+ * may be performed, with <code>checkMemberAccess(this, Member.PUBLIC)</code>
+ * as well as <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return a new instance of this class
+ * @throws InstantiationException if there is not a no-arg constructor
+ * for this class, including interfaces, abstract classes, arrays,
+ * primitive types, and void; or if an exception occurred during
+ * the constructor
+ * @throws IllegalAccessException if you are not allowed to access the
+ * no-arg constructor because of scoping reasons
+ * @throws SecurityException if the security check fails
+ * @throws ExceptionInInitializerError if class initialization caused by
+ * this call fails with an exception
+ */
+ public native T newInstance ()
+ throws InstantiationException, IllegalAccessException;
+
+ // We need a native method to retrieve the protection domain, because we
+ // can't add fields to java.lang.Class that are accessible from Java.
+ private native ProtectionDomain getProtectionDomain0();
+
+ /**
+ * Returns the protection domain of this class. If the classloader did not
+ * record the protection domain when creating this class the unknown
+ * protection domain is returned which has a <code>null</code> code source
+ * and all permissions. A security check may be performed, with
+ * <code>RuntimePermission("getProtectionDomain")</code>.
+ *
+ * @return the protection domain
+ * @throws SecurityException if the security manager exists and the caller
+ * does not have <code>RuntimePermission("getProtectionDomain")</code>.
+ * @see RuntimePermission
+ * @since 1.2
+ */
+ public ProtectionDomain getProtectionDomain()
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(VMClassLoader.protectionDomainPermission);
+
+ ProtectionDomain protectionDomain = getProtectionDomain0();
+
+ if (protectionDomain == null)
+ return VMClassLoader.unknownProtectionDomain;
+ else
+ return protectionDomain;
+ }
+
+ /**
+ * Return the human-readable form of this Object. For an object, this
+ * is either "interface " or "class " followed by <code>getName()</code>,
+ * for primitive types and void it is just <code>getName()</code>.
+ *
+ * @return the human-readable form of this Object
+ */
+ public String toString()
+ {
+ if (isPrimitive())
+ return getName();
+ return (isInterface() ? "interface " : "class ") + getName();
+ }
+
+ /**
+ * Returns the desired assertion status of this class, if it were to be
+ * initialized at this moment. The class assertion status, if set, is
+ * returned; the backup is the default package status; then if there is
+ * a class loader, that default is returned; and finally the system default
+ * is returned. This method seldom needs calling in user code, but exists
+ * for compilers to implement the assert statement. Note that there is no
+ * guarantee that the result of this method matches the class's actual
+ * assertion status.
+ *
+ * @return the desired assertion status
+ * @see ClassLoader#setClassAssertionStatus(String, boolean)
+ * @see ClassLoader#setPackageAssertionStatus(String, boolean)
+ * @see ClassLoader#setDefaultAssertionStatus(boolean)
+ * @since 1.4
+ */
+ public boolean desiredAssertionStatus()
+ {
+ ClassLoader c = getClassLoaderInternal();
+ Object status;
+ if (c == null)
+ return VMClassLoader.defaultAssertionStatus();
+ if (c.classAssertionStatus != null)
+ synchronized (c)
+ {
+ status = c.classAssertionStatus.get(getName());
+ if (status != null)
+ return status.equals(Boolean.TRUE);
+ }
+ else
+ {
+ status = ClassLoader.systemClassAssertionStatus.get(getName());
+ if (status != null)
+ return status.equals(Boolean.TRUE);
+ }
+ if (c.packageAssertionStatus != null)
+ synchronized (c)
+ {
+ String name = getPackagePortion(getName());
+ if ("".equals(name))
+ status = c.packageAssertionStatus.get(null);
+ else
+ do
+ {
+ status = c.packageAssertionStatus.get(name);
+ name = getPackagePortion(name);
+ }
+ while (! "".equals(name) && status == null);
+ if (status != null)
+ return status.equals(Boolean.TRUE);
+ }
+ else
+ {
+ String name = getPackagePortion(getName());
+ if ("".equals(name))
+ status = ClassLoader.systemPackageAssertionStatus.get(null);
+ else
+ do
+ {
+ status = ClassLoader.systemPackageAssertionStatus.get(name);
+ name = getPackagePortion(name);
+ }
+ while (! "".equals(name) && status == null);
+ if (status != null)
+ return status.equals(Boolean.TRUE);
+ }
+ return c.defaultAssertionStatus;
+ }
+
+ /**
+ * Strip the last portion of the name (after the last dot).
+ *
+ * @param name the name to get package of
+ * @return the package name, or "" if no package
+ */
+ private static String getPackagePortion(String name)
+ {
+ int lastInd = name.lastIndexOf('.');
+ if (lastInd == -1)
+ return "";
+ return name.substring(0, lastInd);
+ }
+
+ /**
+ * Perform security checks common to all of the methods that
+ * get members of this Class.
+ */
+ private void memberAccessCheck(int which)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ sm.checkMemberAccess(this, which);
+ Package pkg = getPackage();
+ if (pkg != null)
+ sm.checkPackageAccess(pkg.getName());
+ }
+ }
+
+
+ /**
+ * <p>
+ * Casts this class to represent a subclass of the specified class.
+ * This method is useful for `narrowing' the type of a class so that
+ * the class object, and instances of that class, can match the contract
+ * of a more restrictive method. For example, if this class has the
+ * static type of <code>Class&lt;Object&gt;</code>, and a dynamic type of
+ * <code>Class&lt;Rectangle&gt;</code>, then, assuming <code>Shape</code> is
+ * a superclass of <code>Rectangle</code>, this method can be used on
+ * this class with the parameter, <code>Class&lt;Shape&gt;</code>, to retain
+ * the same instance but with the type
+ * <code>Class&lt;? extends Shape&gt;</code>.
+ * </p>
+ * <p>
+ * If this class can be converted to an instance which is parameterised
+ * over a subtype of the supplied type, <code>U</code>, then this method
+ * returns an appropriately cast reference to this object. Otherwise,
+ * a <code>ClassCastException</code> is thrown.
+ * </p>
+ *
+ * @param klass the class object, the parameterized type (<code>U</code>) of
+ * which should be a superclass of the parameterized type of
+ * this instance.
+ * @return a reference to this object, appropriately cast.
+ * @throws ClassCastException if this class can not be converted to one
+ * which represents a subclass of the specified
+ * type, <code>U</code>.
+ * @since 1.5
+ */
+ public <U> Class<? extends U> asSubclass(Class<U> klass)
+ {
+ if (! klass.isAssignableFrom(this))
+ throw new ClassCastException();
+ return (Class<? extends U>) this;
+ }
+
+ /**
+ * Returns the specified object, cast to this <code>Class</code>' type.
+ *
+ * @param obj the object to cast
+ * @throws ClassCastException if obj is not an instance of this class
+ * @since 1.5
+ */
+ public T cast(Object obj)
+ {
+ if (obj != null && ! isInstance(obj))
+ throw new ClassCastException();
+ return (T) obj;
+ }
+
+ /**
+ * Returns the enumeration constants of this class, or
+ * null if this class is not an <code>Enum</code>.
+ *
+ * @return an array of <code>Enum</code> constants
+ * associated with this class, or null if this
+ * class is not an <code>enum</code>.
+ * @since 1.5
+ */
+ public T[] getEnumConstants()
+ {
+ if (isEnum())
+ {
+ try
+ {
+ Method m = getMethod("values");
+ setAccessible(m);
+ return (T[]) m.invoke(null);
+ }
+ catch (NoSuchMethodException exception)
+ {
+ throw new Error("Enum lacks values() method");
+ }
+ catch (IllegalAccessException exception)
+ {
+ throw new Error("Unable to access Enum class");
+ }
+ catch (InvocationTargetException exception)
+ {
+ throw new
+ RuntimeException("The values method threw an exception",
+ exception);
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Returns true if this class is an <code>Enum</code>.
+ *
+ * @return true if this is an enumeration class.
+ * @since 1.5
+ */
+ public native boolean isEnum();
+
+
+ /**
+ * Returns true if this class is a synthetic class, generated by
+ * the compiler.
+ *
+ * @return true if this is a synthetic class.
+ * @since 1.5
+ */
+ public native boolean isSynthetic();
+
+
+ /**
+ * Returns true if this class is an <code>Annotation</code>.
+ *
+ * @return true if this is an annotation class.
+ * @since 1.5
+ */
+ public native boolean isAnnotation();
+
+
+ /**
+ * Returns the simple name for this class, as used in the source
+ * code. For normal classes, this is the content returned by
+ * <code>getName()</code> which follows the last ".". Anonymous
+ * classes have no name, and so the result of calling this method is
+ * "". The simple name of an array consists of the simple name of
+ * its component type, followed by "[]". Thus, an array with the
+ * component type of an anonymous class has a simple name of simply
+ * "[]".
+ *
+ * @return the simple name for this class.
+ * @since 1.5
+ */
+ public String getSimpleName()
+ {
+ if (isAnonymousClass())
+ return "";
+ if (isArray())
+ return getComponentType().getSimpleName() + "[]";
+
+ String fullName = getName();
+ Class enclosingClass = getEnclosingClass();
+ if (enclosingClass == null)
+ // It's a top level class.
+ return fullName.substring(fullName.lastIndexOf(".") + 1);
+
+ fullName = fullName.substring(enclosingClass.getName().length());
+
+ // We've carved off the enclosing class name; now we must have '$'
+ // followed optionally by digits, followed by the class name.
+ int pos = 1;
+ while (Character.isDigit(fullName.charAt(pos)))
+ ++pos;
+ fullName = fullName.substring(pos);
+
+ return fullName;
+ }
+
+ /**
+ * Returns the class which immediately encloses this class. If this class
+ * is a top-level class, this method returns <code>null</code>.
+ *
+ * @return the immediate enclosing class, or <code>null</code> if this is
+ * a top-level class.
+ * @since 1.5
+ */
+ public native Class<?> getEnclosingClass();
+
+ /**
+ * Returns the constructor which immediately encloses this class. If
+ * this class is a top-level class, or a local or anonymous class
+ * immediately enclosed by a type definition, instance initializer
+ * or static initializer, then <code>null</code> is returned.
+ *
+ * @return the immediate enclosing constructor if this class is
+ * declared within a constructor. Otherwise, <code>null</code>
+ * is returned.
+ * @since 1.5
+ */
+ public native Constructor<T> getEnclosingConstructor();
+
+ /**
+ * Returns the method which immediately encloses this class. If
+ * this class is a top-level class, or a local or anonymous class
+ * immediately enclosed by a type definition, instance initializer
+ * or static initializer, then <code>null</code> is returned.
+ *
+ * @return the immediate enclosing method if this class is
+ * declared within a method. Otherwise, <code>null</code>
+ * is returned.
+ * @since 1.5
+ */
+ public native Method getEnclosingMethod();
+
+ private native String getClassSignature();
+
+ /**
+ * <p>
+ * Returns an array of <code>Type</code> objects which represent the
+ * interfaces directly implemented by this class or extended by this
+ * interface.
+ * </p>
+ * <p>
+ * If one of the superinterfaces is a parameterized type, then the
+ * object returned for this interface reflects the actual type
+ * parameters used in the source code. Type parameters are created
+ * using the semantics specified by the <code>ParameterizedType</code>
+ * interface, and only if an instance has not already been created.
+ * </p>
+ * <p>
+ * The order of the interfaces in the array matches the order in which
+ * the interfaces are declared. For classes which represent an array,
+ * an array of two interfaces, <code>Cloneable</code> and
+ * <code>Serializable</code>, is always returned, with the objects in
+ * that order. A class representing a primitive type or void always
+ * returns an array of zero size.
+ * </p>
+ *
+ * @return an array of interfaces implemented or extended by this class.
+ * @throws GenericSignatureFormatError if the generic signature of one
+ * of the interfaces does not comply with that specified by the Java
+ * Virtual Machine specification, 3rd edition.
+ * @throws TypeNotPresentException if any of the superinterfaces refers
+ * to a non-existant type.
+ * @throws MalformedParameterizedTypeException if any of the interfaces
+ * refer to a parameterized type that can not be instantiated for
+ * some reason.
+ * @since 1.5
+ * @see java.lang.reflect.ParameterizedType
+ */
+ public Type[] getGenericInterfaces()
+ {
+ if (isPrimitive())
+ return new Type[0];
+
+ String sig = getClassSignature();
+ if (sig == null)
+ return getInterfaces();
+
+ ClassSignatureParser p = new ClassSignatureParser(this, sig);
+ return p.getInterfaceTypes();
+ }
+
+ /**
+ * <p>
+ * Returns a <code>Type</code> object representing the direct superclass,
+ * whether class, interface, primitive type or void, of this class.
+ * If this class is an array class, then a class instance representing
+ * the <code>Object</code> class is returned. If this class is primitive,
+ * an interface, or a representation of either the <code>Object</code>
+ * class or void, then <code>null</code> is returned.
+ * </p>
+ * <p>
+ * If the superclass is a parameterized type, then the
+ * object returned for this interface reflects the actual type
+ * parameters used in the source code. Type parameters are created
+ * using the semantics specified by the <code>ParameterizedType</code>
+ * interface, and only if an instance has not already been created.
+ * </p>
+ *
+ * @return the superclass of this class.
+ * @throws GenericSignatureFormatError if the generic signature of the
+ * class does not comply with that specified by the Java
+ * Virtual Machine specification, 3rd edition.
+ * @throws TypeNotPresentException if the superclass refers
+ * to a non-existant type.
+ * @throws MalformedParameterizedTypeException if the superclass
+ * refers to a parameterized type that can not be instantiated for
+ * some reason.
+ * @since 1.5
+ * @see java.lang.reflect.ParameterizedType
+ */
+ public Type getGenericSuperclass()
+ {
+ if (isArray())
+ return Object.class;
+
+ if (isPrimitive() || isInterface() || this == Object.class)
+ return null;
+
+ String sig = getClassSignature();
+ if (sig == null)
+ return getSuperclass();
+
+ ClassSignatureParser p = new ClassSignatureParser(this, sig);
+ return p.getSuperclassType();
+ }
+
+ /**
+ * Returns an array of <code>TypeVariable</code> objects that represents
+ * the type variables declared by this class, in declaration order.
+ * An array of size zero is returned if this class has no type
+ * variables.
+ *
+ * @return the type variables associated with this class.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public TypeVariable<Class<T>>[] getTypeParameters()
+ {
+ String sig = getClassSignature();
+ if (sig == null)
+ return (TypeVariable<Class<T>>[])new TypeVariable[0];
+
+ ClassSignatureParser p = new ClassSignatureParser(this, sig);
+ return p.getTypeParameters();
+ }
+
+ /**
+ * Returns this class' annotation for the specified annotation type,
+ * or <code>null</code> if no such annotation exists.
+ *
+ * @param annotationClass the type of annotation to look for.
+ * @return this class' annotation for the specified type, or
+ * <code>null</code> if no such annotation exists.
+ * @since 1.5
+ */
+ public <A extends Annotation> A getAnnotation(Class<A> annotationClass)
+ {
+ A foundAnnotation = null;
+ Annotation[] annotations = getAnnotations();
+ for (Annotation annotation : annotations)
+ if (annotation.annotationType() == annotationClass)
+ foundAnnotation = (A) annotation;
+ return foundAnnotation;
+ }
+
+ /**
+ * Returns all annotations associated with this class. If there are
+ * no annotations associated with this class, then a zero-length array
+ * will be returned. The returned array may be modified by the client
+ * code, but this will have no effect on the annotation content of this
+ * class, and hence no effect on the return value of this method for
+ * future callers.
+ *
+ * @return this class' annotations.
+ * @since 1.5
+ */
+ public Annotation[] getAnnotations()
+ {
+ HashMap<Class, Annotation> map = new HashMap<Class, Annotation>();
+ for (Annotation a : getDeclaredAnnotations())
+ map.put((Class) a.annotationType(), a);
+ for (Class<? super T> s = getSuperclass();
+ s != null;
+ s = s.getSuperclass())
+ {
+ for (Annotation a : s.getDeclaredAnnotations())
+ {
+ Class k = (Class) a.annotationType();
+ if (! map.containsKey(k) && k.isAnnotationPresent(Inherited.class))
+ map.put(k, a);
+ }
+ }
+ Collection<Annotation> v = map.values();
+ return v.toArray(new Annotation[v.size()]);
+ }
+
+ /**
+ * <p>
+ * Returns the canonical name of this class, as defined by section
+ * 6.7 of the Java language specification. Each package, top-level class,
+ * top-level interface and primitive type has a canonical name. A member
+ * class has a canonical name, if its parent class has one. Likewise,
+ * an array type has a canonical name, if its component type does.
+ * Local or anonymous classes do not have canonical names.
+ * </p>
+ * <p>
+ * The canonical name for top-level classes, top-level interfaces and
+ * primitive types is always the same as the fully-qualified name.
+ * For array types, the canonical name is the canonical name of its
+ * component type with `[]' appended.
+ * </p>
+ * <p>
+ * The canonical name of a member class always refers to the place where
+ * the class was defined, and is composed of the canonical name of the
+ * defining class and the simple name of the member class, joined by `.'.
+ * For example, if a <code>Person</code> class has an inner class,
+ * <code>M</code>, then both its fully-qualified name and canonical name
+ * is <code>Person.M</code>. A subclass, <code>Staff</code>, of
+ * <code>Person</code> refers to the same inner class by the fully-qualified
+ * name of <code>Staff.M</code>, but its canonical name is still
+ * <code>Person.M</code>.
+ * </p>
+ * <p>
+ * Where no canonical name is present, <code>null</code> is returned.
+ * </p>
+ *
+ * @return the canonical name of the class, or <code>null</code> if the
+ * class doesn't have a canonical name.
+ * @since 1.5
+ */
+ public String getCanonicalName()
+ {
+ if (isArray())
+ {
+ String componentName = getComponentType().getCanonicalName();
+ if (componentName != null)
+ return componentName + "[]";
+ }
+ if (isMemberClass())
+ {
+ String memberName = getDeclaringClass().getCanonicalName();
+ if (memberName != null)
+ return memberName + "." + getSimpleName();
+ }
+ if (isLocalClass() || isAnonymousClass())
+ return null;
+ return getName();
+ }
+
+ /**
+ * Returns all annotations directly defined by this class. If there are
+ * no annotations associated with this class, then a zero-length array
+ * will be returned. The returned array may be modified by the client
+ * code, but this will have no effect on the annotation content of this
+ * class, and hence no effect on the return value of this method for
+ * future callers.
+ *
+ * @return the annotations directly defined by this class.
+ * @since 1.5
+ */
+ public Annotation[] getDeclaredAnnotations()
+ {
+ Annotation[] result = getDeclaredAnnotationsInternal();
+ if (result == null)
+ result = new Annotation[0];
+ return result;
+ }
+
+ private native Annotation[] getDeclaredAnnotationsInternal();
+
+ /**
+ * Returns true if an annotation for the specified type is associated
+ * with this class. This is primarily a short-hand for using marker
+ * annotations.
+ *
+ * @param annotationClass the type of annotation to look for.
+ * @return true if an annotation exists for the specified type.
+ * @since 1.5
+ */
+ public boolean isAnnotationPresent(Class<? extends Annotation>
+ annotationClass)
+ {
+ return getAnnotation(annotationClass) != null;
+ }
+
+ /**
+ * Returns true if this object represents an anonymous class.
+ *
+ * @return true if this object represents an anonymous class.
+ * @since 1.5
+ */
+ public native boolean isAnonymousClass();
+
+ /**
+ * Returns true if this object represents an local class.
+ *
+ * @return true if this object represents an local class.
+ * @since 1.5
+ */
+ public native boolean isLocalClass();
+
+ /**
+ * Returns true if this object represents an member class.
+ *
+ * @return true if this object represents an member class.
+ * @since 1.5
+ */
+ public native boolean isMemberClass();
+
+ /**
+ * Utility method for use by classes in this package.
+ */
+ static void setAccessible(final AccessibleObject obj)
+ {
+ AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ obj.setAccessible(true);
+ return null;
+ }
+ });
+ }
+}
diff --git a/libjava/java/lang/ClassCastException.h b/libjava/java/lang/ClassCastException.h
new file mode 100644
index 000000000..55c0bcc88
--- /dev/null
+++ b/libjava/java/lang/ClassCastException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ClassCastException__
+#define __java_lang_ClassCastException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::ClassCastException : public ::java::lang::RuntimeException
+{
+
+public:
+ ClassCastException();
+ ClassCastException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -9223365651070458532LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ClassCastException__
diff --git a/libjava/java/lang/ClassCircularityError.h b/libjava/java/lang/ClassCircularityError.h
new file mode 100644
index 000000000..81d6f93ad
--- /dev/null
+++ b/libjava/java/lang/ClassCircularityError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ClassCircularityError__
+#define __java_lang_ClassCircularityError__
+
+#pragma interface
+
+#include <java/lang/LinkageError.h>
+
+class java::lang::ClassCircularityError : public ::java::lang::LinkageError
+{
+
+public:
+ ClassCircularityError();
+ ClassCircularityError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 1054362542914539689LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ClassCircularityError__
diff --git a/libjava/java/lang/ClassFormatError.h b/libjava/java/lang/ClassFormatError.h
new file mode 100644
index 000000000..ee6664f56
--- /dev/null
+++ b/libjava/java/lang/ClassFormatError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ClassFormatError__
+#define __java_lang_ClassFormatError__
+
+#pragma interface
+
+#include <java/lang/LinkageError.h>
+
+class java::lang::ClassFormatError : public ::java::lang::LinkageError
+{
+
+public:
+ ClassFormatError();
+ ClassFormatError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -8420114879011949195LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ClassFormatError__
diff --git a/libjava/java/lang/ClassLoader$AnnotationsKey.h b/libjava/java/lang/ClassLoader$AnnotationsKey.h
new file mode 100644
index 000000000..1a395b07b
--- /dev/null
+++ b/libjava/java/lang/ClassLoader$AnnotationsKey.h
@@ -0,0 +1,31 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ClassLoader$AnnotationsKey__
+#define __java_lang_ClassLoader$AnnotationsKey__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::ClassLoader$AnnotationsKey : public ::java::lang::Object
+{
+
+public:
+ ClassLoader$AnnotationsKey(::java::lang::Class *, jint, jint, jint);
+ jboolean equals(::java::lang::Object *);
+ jint hashCode();
+public: // actually package-private
+ jint __attribute__((aligned(__alignof__( ::java::lang::Object)))) member_type;
+ jint member_index;
+ jint kind_req;
+ ::java::lang::Class * declaringClass;
+ jint hashCode__;
+public:
+ static JArray< ::java::lang::annotation::Annotation * > * NIL;
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ClassLoader$AnnotationsKey__
diff --git a/libjava/java/lang/ClassLoader.h b/libjava/java/lang/ClassLoader.h
new file mode 100644
index 000000000..5112eab98
--- /dev/null
+++ b/libjava/java/lang/ClassLoader.h
@@ -0,0 +1,112 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ClassLoader__
+#define __java_lang_ClassLoader__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+extern "Java"
+{
+ namespace java
+ {
+ namespace net
+ {
+ class URL;
+ }
+ namespace nio
+ {
+ class ByteBuffer;
+ }
+ namespace security
+ {
+ class ProtectionDomain;
+ }
+ }
+}
+
+jclass _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader);
+void _Jv_RunMain (jclass klass, const char *name, int argc, const char **argv, bool is_jar);
+
+class java::lang::ClassLoader : public ::java::lang::Object
+{
+
+public: // actually package-private
+ virtual JArray< ::java::lang::Object * > * getDeclaredAnnotations(::java::lang::Class *, jint, jint, jint);
+ virtual JArray< ::java::lang::Object * > * putDeclaredAnnotations(::java::lang::Class *, jint, jint, jint, JArray< ::java::lang::Object * > *);
+public: // actually protected
+ ClassLoader();
+ ClassLoader(::java::lang::ClassLoader *);
+public:
+ virtual ::java::lang::Class * loadClass(::java::lang::String *);
+private:
+ ::java::lang::Class * loadClassFromSig(::java::lang::String *);
+public: // actually protected
+ virtual ::java::lang::Class * loadClass(::java::lang::String *, jboolean);
+ virtual ::java::lang::Class * findClass(::java::lang::String *);
+ virtual ::java::lang::Class * defineClass(JArray< jbyte > *, jint, jint);
+ virtual ::java::lang::Class * defineClass(::java::lang::String *, JArray< jbyte > *, jint, jint);
+ virtual ::java::lang::Class * defineClass(::java::lang::String *, JArray< jbyte > *, jint, jint, ::java::security::ProtectionDomain *);
+ virtual ::java::lang::Class * defineClass(::java::lang::String *, ::java::nio::ByteBuffer *, ::java::security::ProtectionDomain *);
+ virtual void resolveClass(::java::lang::Class *);
+ virtual ::java::lang::Class * findSystemClass(::java::lang::String *);
+public:
+ virtual ::java::lang::ClassLoader * getParent();
+public: // actually protected
+ virtual void setSigners(::java::lang::Class *, JArray< ::java::lang::Object * > *);
+ virtual ::java::lang::Class * findLoadedClass(::java::lang::String *);
+public:
+ virtual ::java::net::URL * getResource(::java::lang::String *);
+ virtual ::java::util::Enumeration * getResources(::java::lang::String *);
+public: // actually protected
+ virtual ::java::util::Enumeration * findResources(::java::lang::String *);
+ virtual ::java::net::URL * findResource(::java::lang::String *);
+public:
+ static ::java::net::URL * getSystemResource(::java::lang::String *);
+ static ::java::util::Enumeration * getSystemResources(::java::lang::String *);
+ virtual ::java::io::InputStream * getResourceAsStream(::java::lang::String *);
+ static ::java::io::InputStream * getSystemResourceAsStream(::java::lang::String *);
+ static ::java::lang::ClassLoader * getSystemClassLoader();
+public: // actually protected
+ virtual ::java::lang::Package * definePackage(::java::lang::String *, ::java::lang::String *, ::java::lang::String *, ::java::lang::String *, ::java::lang::String *, ::java::lang::String *, ::java::lang::String *, ::java::net::URL *);
+ virtual ::java::lang::Package * getPackage(::java::lang::String *);
+ virtual JArray< ::java::lang::Package * > * getPackages();
+ virtual ::java::lang::String * findLibrary(::java::lang::String *);
+public:
+ virtual void setDefaultAssertionStatus(jboolean);
+ virtual void setPackageAssertionStatus(::java::lang::String *, jboolean);
+ virtual void setClassAssertionStatus(::java::lang::String *, jboolean);
+ virtual void clearAssertionStatus();
+public: // actually package-private
+ virtual jboolean isAncestorOf(::java::lang::ClassLoader *);
+private:
+ void checkInitialized();
+public: // actually package-private
+ ::java::util::HashMap * __attribute__((aligned(__alignof__( ::java::lang::Object)))) loadedClasses;
+ ::java::util::HashMap * loadingConstraints;
+ ::java::util::HashMap * definedPackages;
+private:
+ ::java::lang::ClassLoader * parent;
+ jboolean initialized;
+public: // actually package-private
+ static ::java::lang::ClassLoader * systemClassLoader;
+private:
+ ::java::util::concurrent::ConcurrentHashMap * declaredAnnotations;
+public: // actually package-private
+ static ::java::security::ProtectionDomain * defaultProtectionDomain;
+ jboolean defaultAssertionStatus;
+ static ::java::util::Map * systemPackageAssertionStatus;
+ ::java::util::Map * packageAssertionStatus;
+ static ::java::util::Map * systemClassAssertionStatus;
+ ::java::util::Map * classAssertionStatus;
+public:
+ static ::java::lang::Class class$;
+
+ friend jclass (::_Jv_FindClass) (_Jv_Utf8Const *name, java::lang::ClassLoader *loader);
+ friend void ::_Jv_RunMain (jclass klass, const char *name, int argc, const char **argv, bool is_jar);
+};
+
+#endif // __java_lang_ClassLoader__
diff --git a/libjava/java/lang/ClassLoader.java b/libjava/java/lang/ClassLoader.java
new file mode 100644
index 000000000..d55573095
--- /dev/null
+++ b/libjava/java/lang/ClassLoader.java
@@ -0,0 +1,1144 @@
+/* ClassLoader.java -- responsible for loading classes into the VM
+ Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang;
+
+import gnu.classpath.SystemProperties;
+import gnu.classpath.VMStackWalker;
+import gnu.java.util.DoubleEnumeration;
+import gnu.java.util.EmptyEnumeration;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.security.CodeSource;
+import java.security.PermissionCollection;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.lang.annotation.Annotation;
+
+/**
+ * The ClassLoader is a way of customizing the way Java gets its classes
+ * and loads them into memory. The verifier and other standard Java things
+ * still run, but the ClassLoader is allowed great flexibility in determining
+ * where to get the classfiles and when to load and resolve them. For that
+ * matter, a custom ClassLoader can perform on-the-fly code generation or
+ * modification!
+ *
+ * <p>Every classloader has a parent classloader that is consulted before
+ * the 'child' classloader when classes or resources should be loaded.
+ * This is done to make sure that classes can be loaded from an hierarchy of
+ * multiple classloaders and classloaders do not accidentially redefine
+ * already loaded classes by classloaders higher in the hierarchy.
+ *
+ * <p>The grandparent of all classloaders is the bootstrap classloader, which
+ * loads all the standard system classes as implemented by GNU Classpath. The
+ * other special classloader is the system classloader (also called
+ * application classloader) that loads all classes from the CLASSPATH
+ * (<code>java.class.path</code> system property). The system classloader
+ * is responsible for finding the application classes from the classpath,
+ * and delegates all requests for the standard library classes to its parent
+ * the bootstrap classloader. Most programs will load all their classes
+ * through the system classloaders.
+ *
+ * <p>The bootstrap classloader in GNU Classpath is implemented as a couple of
+ * static (native) methods on the package private class
+ * <code>java.lang.VMClassLoader</code>, the system classloader is an
+ * instance of <code>gnu.java.lang.SystemClassLoader</code>
+ * (which is a subclass of <code>java.net.URLClassLoader</code>).
+ *
+ * <p>Users of a <code>ClassLoader</code> will normally just use the methods
+ * <ul>
+ * <li> <code>loadClass()</code> to load a class.</li>
+ * <li> <code>getResource()</code> or <code>getResourceAsStream()</code>
+ * to access a resource.</li>
+ * <li> <code>getResources()</code> to get an Enumeration of URLs to all
+ * the resources provided by the classloader and its parents with the
+ * same name.</li>
+ * </ul>
+ *
+ * <p>Subclasses should implement the methods
+ * <ul>
+ * <li> <code>findClass()</code> which is called by <code>loadClass()</code>
+ * when the parent classloader cannot provide a named class.</li>
+ * <li> <code>findResource()</code> which is called by
+ * <code>getResource()</code> when the parent classloader cannot provide
+ * a named resource.</li>
+ * <li> <code>findResources()</code> which is called by
+ * <code>getResource()</code> to combine all the resources with the
+ * same name from the classloader and its parents.</li>
+ * <li> <code>findLibrary()</code> which is called by
+ * <code>Runtime.loadLibrary()</code> when a class defined by the
+ * classloader wants to load a native library.</li>
+ * </ul>
+ *
+ * @author John Keiser
+ * @author Mark Wielaard
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Class
+ * @since 1.0
+ */
+public abstract class ClassLoader
+{
+ /**
+ * All classes loaded by this classloader. VM's may choose to implement
+ * this cache natively; but it is here available for use if necessary. It
+ * is not private in order to allow native code (and trusted subclasses)
+ * access to this field.
+ */
+ final HashMap loadedClasses = new HashMap();
+
+ /**
+ * Loading constraints registered with this classloader. This maps
+ * a class name to a weak reference to a class. When the reference
+ * is non-null, it means that a reference to the name must resolve
+ * to the indicated class.
+ */
+ final HashMap<String, WeakReference<Class>> loadingConstraints
+ = new HashMap<String, WeakReference<Class>>();
+
+ /**
+ * All packages defined by this classloader. It is not private in order to
+ * allow native code (and trusted subclasses) access to this field.
+ */
+ final HashMap definedPackages = new HashMap();
+
+ /**
+ * The classloader that is consulted before this classloader.
+ * If null then the parent is the bootstrap classloader.
+ */
+ private final ClassLoader parent;
+
+ /**
+ * This is true if this classloader was successfully initialized.
+ * This flag is needed to avoid a class loader attack: even if the
+ * security manager rejects an attempt to create a class loader, the
+ * malicious class could have a finalize method which proceeds to
+ * define classes.
+ */
+ private final boolean initialized;
+
+ /**
+ * System/Application classloader: defaults to an instance of
+ * gnu.java.lang.SystemClassLoader, unless the first invocation of
+ * getSystemClassLoader loads another class loader because of the
+ * java.system.class.loader property. The initialization of this field
+ * is somewhat circular - getSystemClassLoader() checks whether this
+ * field is null in order to bypass a security check.
+ */
+ static final ClassLoader systemClassLoader =
+ VMClassLoader.getSystemClassLoader();
+
+ /**
+ * This cache maps from a Class to its associated annotations. It's
+ * declared here so that when this class loader becomes unreachable,
+ * so will the corresponding cache.
+ */
+
+ private final ConcurrentHashMap<AnnotationsKey,Object[]>
+ declaredAnnotations
+ = new ConcurrentHashMap<AnnotationsKey,Object[]>();
+
+ static final class AnnotationsKey
+ {
+ final int /* jv_attr_type */ member_type;
+ final int member_index;
+ final int /* jv_attr_kind */ kind_req;
+ final Class declaringClass;
+ final int hashCode;
+
+ public AnnotationsKey (Class declaringClass,
+ int member_type,
+ int member_index,
+ int kind_req)
+ {
+ this.member_type = member_type;
+ this.member_index = member_index;
+ this.kind_req = kind_req;
+ this.declaringClass = declaringClass;
+ hashCode = (member_type ^ member_index ^ kind_req
+ ^ declaringClass.hashCode());
+ }
+
+ public boolean equals(Object obj)
+ {
+ AnnotationsKey other = (AnnotationsKey)obj;
+ return (this.member_type == other.member_type
+ && this.member_index == other.member_index
+ && this.kind_req == other.kind_req
+ && this.declaringClass == other.declaringClass);
+ }
+
+ public int hashCode()
+ {
+ return hashCode;
+ }
+
+ public static final Annotation[] NIL = new Annotation[0];
+ }
+
+ final Object[] getDeclaredAnnotations(Class declaringClass,
+ int member_type,
+ int member_index,
+ int kind_req)
+ {
+ Object[] result
+ = declaredAnnotations.get (new AnnotationsKey
+ (declaringClass,
+ member_type,
+ member_index,
+ kind_req));
+ if (result != AnnotationsKey.NIL && result != null)
+ return (Object[])result.clone();
+ return null;
+ }
+
+ final Object[] putDeclaredAnnotations(Class declaringClass,
+ int member_type,
+ int member_index,
+ int kind_req,
+ Object[] annotations)
+ {
+ declaredAnnotations.put
+ (new AnnotationsKey
+ (declaringClass, member_type,
+ member_index, kind_req),
+ annotations == null ? AnnotationsKey.NIL : annotations);
+
+ return annotations == null ? null : (Object[])annotations.clone();
+ }
+
+ static
+ {
+ // Find out if we have to install a default security manager. Note
+ // that this is done here because we potentially need the system
+ // class loader to load the security manager and note also that we
+ // don't need the security manager until the system class loader
+ // is created. If the runtime chooses to use a class loader that
+ // doesn't have the system class loader as its parent, it is
+ // responsible for setting up a security manager before doing so.
+ String secman = SystemProperties.getProperty("java.security.manager");
+ if (secman != null && SecurityManager.current == null)
+ {
+ if (secman.equals("") || secman.equals("default"))
+ {
+ SecurityManager.current = new SecurityManager();
+ }
+ else
+ {
+ try
+ {
+ Class cl = Class.forName(secman, false, systemClassLoader);
+ SecurityManager.current = (SecurityManager) cl.newInstance();
+ }
+ catch (Exception x)
+ {
+ throw (InternalError)
+ new InternalError("Unable to create SecurityManager")
+ .initCause(x);
+ }
+ }
+ }
+ }
+
+ /**
+ * The default protection domain, used when defining a class with a null
+ * paramter for the domain.
+ */
+ static final ProtectionDomain defaultProtectionDomain;
+ static
+ {
+ CodeSource cs = new CodeSource(null, null);
+ PermissionCollection perm = Policy.getPolicy().getPermissions(cs);
+ defaultProtectionDomain = new ProtectionDomain(cs, perm);
+ }
+
+ /**
+ * The desired assertion status of classes loaded by this loader, if not
+ * overridden by package or class instructions.
+ */
+ // Package visible for use by Class.
+ boolean defaultAssertionStatus = VMClassLoader.defaultAssertionStatus();
+
+ /**
+ * The command-line state of the package assertion status overrides. This
+ * map is never modified, so it does not need to be synchronized.
+ */
+ // Package visible for use by Class.
+ static final Map systemPackageAssertionStatus
+ = VMClassLoader.packageAssertionStatus();
+
+ /**
+ * The map of package assertion status overrides, or null if no package
+ * overrides have been specified yet. The values of the map should be
+ * Boolean.TRUE or Boolean.FALSE, and the unnamed package is represented
+ * by the null key. This map must be synchronized on this instance.
+ */
+ // Package visible for use by Class.
+ Map packageAssertionStatus;
+
+ /**
+ * The command-line state of the class assertion status overrides. This
+ * map is never modified, so it does not need to be synchronized.
+ */
+ // Package visible for use by Class.
+ static final Map systemClassAssertionStatus
+ = VMClassLoader.classAssertionStatus();
+
+ /**
+ * The map of class assertion status overrides, or null if no class
+ * overrides have been specified yet. The values of the map should be
+ * Boolean.TRUE or Boolean.FALSE. This map must be synchronized on this
+ * instance.
+ */
+ // Package visible for use by Class.
+ Map classAssertionStatus;
+
+ /**
+ * Create a new ClassLoader with as parent the system classloader. There
+ * may be a security check for <code>checkCreateClassLoader</code>.
+ *
+ * @throws SecurityException if the security check fails
+ */
+ protected ClassLoader() throws SecurityException
+ {
+ this(systemClassLoader);
+ }
+
+ /**
+ * Create a new ClassLoader with the specified parent. The parent will
+ * be consulted when a class or resource is requested through
+ * <code>loadClass()</code> or <code>getResource()</code>. Only when the
+ * parent classloader cannot provide the requested class or resource the
+ * <code>findClass()</code> or <code>findResource()</code> method
+ * of this classloader will be called. There may be a security check for
+ * <code>checkCreateClassLoader</code>.
+ *
+ * @param parent the classloader's parent, or null for the bootstrap
+ * classloader
+ * @throws SecurityException if the security check fails
+ * @since 1.2
+ */
+ protected ClassLoader(ClassLoader parent)
+ {
+ // May we create a new classloader?
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkCreateClassLoader();
+ this.parent = parent;
+ this.initialized = true;
+ }
+
+ /**
+ * Load a class using this ClassLoader or its parent, without resolving
+ * it. Calls <code>loadClass(name, false)</code>.
+ *
+ * <p>Subclasses should not override this method but should override
+ * <code>findClass()</code> which is called by this method.</p>
+ *
+ * @param name the name of the class relative to this ClassLoader
+ * @return the loaded class
+ * @throws ClassNotFoundException if the class cannot be found
+ */
+ public Class<?> loadClass(String name) throws ClassNotFoundException
+ {
+ return loadClass(name, false);
+ }
+
+ private native Class loadClassFromSig(String name)
+ throws ClassNotFoundException;
+
+ /**
+ * Load a class using this ClassLoader or its parent, possibly resolving
+ * it as well using <code>resolveClass()</code>. It first tries to find
+ * out if the class has already been loaded through this classloader by
+ * calling <code>findLoadedClass()</code>. Then it calls
+ * <code>loadClass()</code> on the parent classloader (or when there is
+ * no parent it uses the VM bootclassloader). If the class is still
+ * not loaded it tries to create a new class by calling
+ * <code>findClass()</code>. Finally when <code>resolve</code> is
+ * <code>true</code> it also calls <code>resolveClass()</code> on the
+ * newly loaded class.
+ *
+ * <p>Subclasses should not override this method but should override
+ * <code>findClass()</code> which is called by this method.</p>
+ *
+ * @param name the fully qualified name of the class to load
+ * @param resolve whether or not to resolve the class
+ * @return the loaded class
+ * @throws ClassNotFoundException if the class cannot be found
+ */
+ protected synchronized Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException
+ {
+ SecurityManager sm = SecurityManager.current;
+ if (sm != null)
+ {
+ int lastDot = name.lastIndexOf('.');
+ if (lastDot != -1)
+ sm.checkPackageAccess(name.substring(0, lastDot));
+ }
+
+ // Arrays are handled specially.
+ Class c;
+ if (name.length() > 0 && name.charAt(0) == '[')
+ c = loadClassFromSig(name);
+ else
+ {
+ // Have we already loaded this class?
+ c = findLoadedClass(name);
+ if (c == null)
+ {
+ // Can the class be loaded by a parent?
+ try
+ {
+ if (parent == null)
+ {
+ c = VMClassLoader.loadClass(name, resolve);
+ if (c != null)
+ return c;
+ }
+ else
+ {
+ return parent.loadClass(name, resolve);
+ }
+ }
+ catch (ClassNotFoundException e)
+ {
+ }
+ // Still not found, we have to do it ourself.
+ c = findClass(name);
+ }
+ }
+ if (resolve)
+ resolveClass(c);
+ return c;
+ }
+
+ /**
+ * Called for every class name that is needed but has not yet been
+ * defined by this classloader or one of its parents. It is called by
+ * <code>loadClass()</code> after both <code>findLoadedClass()</code> and
+ * <code>parent.loadClass()</code> couldn't provide the requested class.
+ *
+ * <p>The default implementation throws a
+ * <code>ClassNotFoundException</code>. Subclasses should override this
+ * method. An implementation of this method in a subclass should get the
+ * class bytes of the class (if it can find them), if the package of the
+ * requested class doesn't exist it should define the package and finally
+ * it should call define the actual class. It does not have to resolve the
+ * class. It should look something like the following:<br>
+ *
+ * <pre>
+ * // Get the bytes that describe the requested class
+ * byte[] classBytes = classLoaderSpecificWayToFindClassBytes(name);
+ * // Get the package name
+ * int lastDot = name.lastIndexOf('.');
+ * if (lastDot != -1)
+ * {
+ * String packageName = name.substring(0, lastDot);
+ * // Look if the package already exists
+ * if (getPackage(packageName) == null)
+ * {
+ * // define the package
+ * definePackage(packageName, ...);
+ * }
+ * }
+ * // Define and return the class
+ * return defineClass(name, classBytes, 0, classBytes.length);
+ * </pre>
+ *
+ * <p><code>loadClass()</code> makes sure that the <code>Class</code>
+ * returned by <code>findClass()</code> will later be returned by
+ * <code>findLoadedClass()</code> when the same class name is requested.
+ *
+ * @param name class name to find (including the package name)
+ * @return the requested Class
+ * @throws ClassNotFoundException when the class can not be found
+ * @since 1.2
+ */
+ protected Class<?> findClass(String name) throws ClassNotFoundException
+ {
+ throw new ClassNotFoundException(name);
+ }
+
+ /**
+ * Helper to define a class using a string of bytes. This version is not
+ * secure.
+ *
+ * @param data the data representing the classfile, in classfile format
+ * @param offset the offset into the data where the classfile starts
+ * @param len the length of the classfile data in the array
+ * @return the class that was defined
+ * @throws ClassFormatError if data is not in proper classfile format
+ * @throws IndexOutOfBoundsException if offset or len is negative, or
+ * offset + len exceeds data
+ * @deprecated use {@link #defineClass(String, byte[], int, int)} instead
+ */
+ protected final Class<?> defineClass(byte[] data, int offset, int len)
+ throws ClassFormatError
+ {
+ return defineClass(null, data, offset, len);
+ }
+
+ /**
+ * Helper to define a class using a string of bytes without a
+ * ProtectionDomain. Subclasses should call this method from their
+ * <code>findClass()</code> implementation. The name should use '.'
+ * separators, and discard the trailing ".class". The default protection
+ * domain has the permissions of
+ * <code>Policy.getPolicy().getPermissions(new CodeSource(null, null))</code>.
+ *
+ * @param name the name to give the class, or null if unknown
+ * @param data the data representing the classfile, in classfile format
+ * @param offset the offset into the data where the classfile starts
+ * @param len the length of the classfile data in the array
+ * @return the class that was defined
+ * @throws ClassFormatError if data is not in proper classfile format
+ * @throws IndexOutOfBoundsException if offset or len is negative, or
+ * offset + len exceeds data
+ * @throws SecurityException if name starts with "java."
+ * @since 1.1
+ */
+ protected final Class<?> defineClass(String name, byte[] data, int offset,
+ int len) throws ClassFormatError
+ {
+ return defineClass(name, data, offset, len, null);
+ }
+
+ /**
+ * Helper to define a class using a string of bytes. Subclasses should call
+ * this method from their <code>findClass()</code> implementation. If the
+ * domain is null, the default of
+ * <code>Policy.getPolicy().getPermissions(new CodeSource(null, null))</code>
+ * is used. Once a class has been defined in a package, all further classes
+ * in that package must have the same set of certificates or a
+ * SecurityException is thrown.
+ *
+ * @param name the name to give the class. null if unknown
+ * @param data the data representing the classfile, in classfile format
+ * @param offset the offset into the data where the classfile starts
+ * @param len the length of the classfile data in the array
+ * @param domain the ProtectionDomain to give to the class, null for the
+ * default protection domain
+ * @return the class that was defined
+ * @throws ClassFormatError if data is not in proper classfile format
+ * @throws IndexOutOfBoundsException if offset or len is negative, or
+ * offset + len exceeds data
+ * @throws SecurityException if name starts with "java.", or if certificates
+ * do not match up
+ * @since 1.2
+ */
+ protected final synchronized Class<?> defineClass(String name, byte[] data,
+ int offset, int len,
+ ProtectionDomain domain)
+ throws ClassFormatError
+ {
+ checkInitialized();
+ if (domain == null)
+ domain = defaultProtectionDomain;
+
+ Class retval = VMClassLoader.defineClass(this, name, data,
+ offset, len, domain);
+ loadedClasses.put(retval.getName(), retval);
+ return retval;
+ }
+
+ /**
+ * Helper to define a class using the contents of a byte buffer. If
+ * the domain is null, the default of
+ * <code>Policy.getPolicy().getPermissions(new CodeSource(null,
+ * null))</code> is used. Once a class has been defined in a
+ * package, all further classes in that package must have the same
+ * set of certificates or a SecurityException is thrown.
+ *
+ * @param name the name to give the class. null if unknown
+ * @param buf a byte buffer containing bytes that form a class.
+ * @param domain the ProtectionDomain to give to the class, null for the
+ * default protection domain
+ * @return the class that was defined
+ * @throws ClassFormatError if data is not in proper classfile format
+ * @throws NoClassDefFoundError if the supplied name is not the same as
+ * the one specified by the byte buffer.
+ * @throws SecurityException if name starts with "java.", or if certificates
+ * do not match up
+ * @since 1.5
+ */
+ protected final Class<?> defineClass(String name, ByteBuffer buf,
+ ProtectionDomain domain)
+ throws ClassFormatError
+ {
+ byte[] data = new byte[buf.remaining()];
+ buf.get(data);
+ return defineClass(name, data, 0, data.length, domain);
+ }
+
+ /**
+ * Links the class, if that has not already been done. Linking basically
+ * resolves all references to other classes made by this class.
+ *
+ * @param c the class to resolve
+ * @throws NullPointerException if c is null
+ * @throws LinkageError if linking fails
+ */
+ protected final void resolveClass(Class<?> c)
+ {
+ checkInitialized();
+ VMClassLoader.resolveClass(c);
+ }
+
+ /**
+ * Helper to find a Class using the system classloader, possibly loading it.
+ * A subclass usually does not need to call this, if it correctly
+ * overrides <code>findClass(String)</code>.
+ *
+ * @param name the name of the class to find
+ * @return the found class
+ * @throws ClassNotFoundException if the class cannot be found
+ */
+ protected final Class<?> findSystemClass(String name)
+ throws ClassNotFoundException
+ {
+ checkInitialized();
+ return Class.forName(name, false, systemClassLoader);
+ }
+
+ /**
+ * Returns the parent of this classloader. If the parent of this
+ * classloader is the bootstrap classloader then this method returns
+ * <code>null</code>. A security check may be performed on
+ * <code>RuntimePermission("getClassLoader")</code>.
+ *
+ * @return the parent <code>ClassLoader</code>
+ * @throws SecurityException if the security check fails
+ * @since 1.2
+ */
+ public final ClassLoader getParent()
+ {
+ // Check if we may return the parent classloader.
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ ClassLoader cl = VMStackWalker.getCallingClassLoader();
+ if (cl != null && ! cl.isAncestorOf(this))
+ sm.checkPermission(new RuntimePermission("getClassLoader"));
+ }
+ return parent;
+ }
+
+ /**
+ * Helper to set the signers of a class. This should be called after
+ * defining the class.
+ *
+ * @param c the Class to set signers of
+ * @param signers the signers to set
+ * @since 1.1
+ */
+ protected final void setSigners(Class<?> c, Object[] signers)
+ {
+ checkInitialized();
+ c.setSigners(signers);
+ }
+
+ /**
+ * Helper to find an already-loaded class in this ClassLoader.
+ *
+ * @param name the name of the class to find
+ * @return the found Class, or null if it is not found
+ * @since 1.1
+ */
+ protected final synchronized Class<?> findLoadedClass(String name)
+ {
+ checkInitialized();
+ // NOTE: If the VM is keeping its own cache, it may make sense to have
+ // this method be native.
+ return (Class) loadedClasses.get(name);
+ }
+
+ /**
+ * Get the URL to a resource using this classloader or one of its parents.
+ * First tries to get the resource by calling <code>getResource()</code>
+ * on the parent classloader. If the parent classloader returns null then
+ * it tries finding the resource by calling <code>findResource()</code> on
+ * this classloader. The resource name should be separated by '/' for path
+ * elements.
+ *
+ * <p>Subclasses should not override this method but should override
+ * <code>findResource()</code> which is called by this method.
+ *
+ * @param name the name of the resource relative to this classloader
+ * @return the URL to the resource or null when not found
+ */
+ public URL getResource(String name)
+ {
+ URL result;
+
+ if (parent == null)
+ result = VMClassLoader.getResource(name);
+ else
+ result = parent.getResource(name);
+
+ if (result == null)
+ result = findResource(name);
+ return result;
+ }
+
+ /**
+ * Returns an Enumeration of all resources with a given name that can
+ * be found by this classloader and its parents. Certain classloaders
+ * (such as the URLClassLoader when given multiple jar files) can have
+ * multiple resources with the same name that come from multiple locations.
+ * It can also occur that a parent classloader offers a resource with a
+ * certain name and the child classloader also offers a resource with that
+ * same name. <code>getResource()</code> only offers the first resource (of the
+ * parent) with a given name. This method lists all resources with the
+ * same name. The name should use '/' as path separators.
+ *
+ * <p>The Enumeration is created by first calling <code>getResources()</code>
+ * on the parent classloader and then calling <code>findResources()</code>
+ * on this classloader.</p>
+ *
+ * @param name the resource name
+ * @return an enumaration of all resources found
+ * @throws IOException if I/O errors occur in the process
+ * @since 1.2
+ * @specnote this was <code>final</code> prior to 1.5
+ */
+ public Enumeration<URL> getResources(String name) throws IOException
+ {
+ Enumeration<URL> parentResources;
+ if (parent == null)
+ parentResources = VMClassLoader.getResources(name);
+ else
+ parentResources = parent.getResources(name);
+ return new DoubleEnumeration<URL>(parentResources, findResources(name));
+ }
+
+ /**
+ * Called whenever all locations of a named resource are needed.
+ * It is called by <code>getResources()</code> after it has called
+ * <code>parent.getResources()</code>. The results are combined by
+ * the <code>getResources()</code> method.
+ *
+ * <p>The default implementation always returns an empty Enumeration.
+ * Subclasses should override it when they can provide an Enumeration of
+ * URLs (possibly just one element) to the named resource.
+ * The first URL of the Enumeration should be the same as the one
+ * returned by <code>findResource</code>.
+ *
+ * @param name the name of the resource to be found
+ * @return a possibly empty Enumeration of URLs to the named resource
+ * @throws IOException if I/O errors occur in the process
+ * @since 1.2
+ */
+ protected Enumeration<URL> findResources(String name) throws IOException
+ {
+ return new EmptyEnumeration<URL>();
+ }
+
+ /**
+ * Called whenever a resource is needed that could not be provided by
+ * one of the parents of this classloader. It is called by
+ * <code>getResource()</code> after <code>parent.getResource()</code>
+ * couldn't provide the requested resource.
+ *
+ * <p>The default implementation always returns null. Subclasses should
+ * override this method when they can provide a way to return a URL
+ * to a named resource.
+ *
+ * @param name the name of the resource to be found
+ * @return a URL to the named resource or null when not found
+ * @since 1.2
+ */
+ protected URL findResource(String name)
+ {
+ return null;
+ }
+
+ /**
+ * Get the URL to a resource using the system classloader.
+ *
+ * @param name the name of the resource relative to the system classloader
+ * @return the URL to the resource
+ * @since 1.1
+ */
+ public static final URL getSystemResource(String name)
+ {
+ return systemClassLoader.getResource(name);
+ }
+
+ /**
+ * Get an Enumeration of URLs to resources with a given name using the
+ * the system classloader. The enumeration firsts lists the resources with
+ * the given name that can be found by the bootstrap classloader followed
+ * by the resources with the given name that can be found on the classpath.
+ *
+ * @param name the name of the resource relative to the system classloader
+ * @return an Enumeration of URLs to the resources
+ * @throws IOException if I/O errors occur in the process
+ * @since 1.2
+ */
+ public static Enumeration<URL> getSystemResources(String name)
+ throws IOException
+ {
+ return systemClassLoader.getResources(name);
+ }
+
+ /**
+ * Get a resource as stream using this classloader or one of its parents.
+ * First calls <code>getResource()</code> and if that returns a URL to
+ * the resource then it calls and returns the InputStream given by
+ * <code>URL.openStream()</code>.
+ *
+ * <p>Subclasses should not override this method but should override
+ * <code>findResource()</code> which is called by this method.
+ *
+ * @param name the name of the resource relative to this classloader
+ * @return an InputStream to the resource, or null
+ * @since 1.1
+ */
+ public InputStream getResourceAsStream(String name)
+ {
+ try
+ {
+ URL url = getResource(name);
+ if (url == null)
+ return null;
+ return url.openStream();
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Get a resource using the system classloader.
+ *
+ * @param name the name of the resource relative to the system classloader
+ * @return an input stream for the resource, or null
+ * @since 1.1
+ */
+ public static final InputStream getSystemResourceAsStream(String name)
+ {
+ try
+ {
+ URL url = getSystemResource(name);
+ if (url == null)
+ return null;
+ return url.openStream();
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the system classloader. The system classloader (also called
+ * the application classloader) is the classloader that is used to
+ * load the application classes on the classpath (given by the system
+ * property <code>java.class.path</code>. This is set as the context
+ * class loader for a thread. The system property
+ * <code>java.system.class.loader</code>, if defined, is taken to be the
+ * name of the class to use as the system class loader, which must have
+ * a public constructor which takes a ClassLoader as a parent. The parent
+ * class loader passed in the constructor is the default system class
+ * loader.
+ *
+ * <p>Note that this is different from the bootstrap classloader that
+ * actually loads all the real "system" classes (the bootstrap classloader
+ * is the parent of the returned system classloader).
+ *
+ * <p>A security check will be performed for
+ * <code>RuntimePermission("getClassLoader")</code> if the calling class
+ * is not a parent of the system class loader.
+ *
+ * @return the system class loader
+ * @throws SecurityException if the security check fails
+ * @throws IllegalStateException if this is called recursively
+ * @throws Error if <code>java.system.class.loader</code> fails to load
+ * @since 1.2
+ */
+ public static ClassLoader getSystemClassLoader()
+ {
+ // Check if we may return the system classloader
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ ClassLoader cl = VMStackWalker.getCallingClassLoader();
+ if (cl != null && cl != systemClassLoader)
+ sm.checkPermission(new RuntimePermission("getClassLoader"));
+ }
+
+ return systemClassLoader;
+ }
+
+ /**
+ * Defines a new package and creates a Package object. The package should
+ * be defined before any class in the package is defined with
+ * <code>defineClass()</code>. The package should not yet be defined
+ * before in this classloader or in one of its parents (which means that
+ * <code>getPackage()</code> should return <code>null</code>). All
+ * parameters except the <code>name</code> of the package may be
+ * <code>null</code>.
+ *
+ * <p>Subclasses should call this method from their <code>findClass()</code>
+ * implementation before calling <code>defineClass()</code> on a Class
+ * in a not yet defined Package (which can be checked by calling
+ * <code>getPackage()</code>).
+ *
+ * @param name the name of the Package
+ * @param specTitle the name of the specification
+ * @param specVendor the name of the specification designer
+ * @param specVersion the version of this specification
+ * @param implTitle the name of the implementation
+ * @param implVendor the vendor that wrote this implementation
+ * @param implVersion the version of this implementation
+ * @param sealed if sealed the origin of the package classes
+ * @return the Package object for the specified package
+ * @throws IllegalArgumentException if the package name is null or it
+ * was already defined by this classloader or one of its parents
+ * @see Package
+ * @since 1.2
+ */
+ protected Package definePackage(String name, String specTitle,
+ String specVendor, String specVersion,
+ String implTitle, String implVendor,
+ String implVersion, URL sealed)
+ {
+ if (getPackage(name) != null)
+ throw new IllegalArgumentException("Package " + name
+ + " already defined");
+ Package p = new Package(name, specTitle, specVendor, specVersion,
+ implTitle, implVendor, implVersion, sealed, this);
+ synchronized (definedPackages)
+ {
+ definedPackages.put(name, p);
+ }
+ return p;
+ }
+
+ /**
+ * Returns the Package object for the requested package name. It returns
+ * null when the package is not defined by this classloader or one of its
+ * parents.
+ *
+ * @param name the package name to find
+ * @return the package, if defined
+ * @since 1.2
+ */
+ protected Package getPackage(String name)
+ {
+ Package p;
+ if (parent == null)
+ p = VMClassLoader.getPackage(name);
+ else
+ p = parent.getPackage(name);
+
+ if (p == null)
+ {
+ synchronized (definedPackages)
+ {
+ p = (Package) definedPackages.get(name);
+ }
+ }
+ return p;
+ }
+
+ /**
+ * Returns all Package objects defined by this classloader and its parents.
+ *
+ * @return an array of all defined packages
+ * @since 1.2
+ */
+ protected Package[] getPackages()
+ {
+ // Get all our packages.
+ Package[] packages;
+ synchronized(definedPackages)
+ {
+ packages = new Package[definedPackages.size()];
+ definedPackages.values().toArray(packages);
+ }
+
+ // If we have a parent get all packages defined by our parents.
+ Package[] parentPackages;
+ if (parent == null)
+ parentPackages = VMClassLoader.getPackages();
+ else
+ parentPackages = parent.getPackages();
+
+ Package[] allPackages = new Package[parentPackages.length
+ + packages.length];
+ System.arraycopy(parentPackages, 0, allPackages, 0,
+ parentPackages.length);
+ System.arraycopy(packages, 0, allPackages, parentPackages.length,
+ packages.length);
+ return allPackages;
+ }
+
+ /**
+ * Called by <code>Runtime.loadLibrary()</code> to get an absolute path
+ * to a (system specific) library that was requested by a class loaded
+ * by this classloader. The default implementation returns
+ * <code>null</code>. It should be implemented by subclasses when they
+ * have a way to find the absolute path to a library. If this method
+ * returns null the library is searched for in the default locations
+ * (the directories listed in the <code>java.library.path</code> system
+ * property).
+ *
+ * @param name the (system specific) name of the requested library
+ * @return the full pathname to the requested library, or null
+ * @see Runtime#loadLibrary(String)
+ * @since 1.2
+ */
+ protected String findLibrary(String name)
+ {
+ return null;
+ }
+
+ /**
+ * Set the default assertion status for classes loaded by this classloader,
+ * used unless overridden by a package or class request.
+ *
+ * @param enabled true to set the default to enabled
+ * @see #setClassAssertionStatus(String, boolean)
+ * @see #setPackageAssertionStatus(String, boolean)
+ * @see #clearAssertionStatus()
+ * @since 1.4
+ */
+ public void setDefaultAssertionStatus(boolean enabled)
+ {
+ defaultAssertionStatus = enabled;
+ }
+
+ /**
+ * Set the default assertion status for packages, used unless overridden
+ * by a class request. This default also covers subpackages, unless they
+ * are also specified. The unnamed package should use null for the name.
+ *
+ * @param name the package (and subpackages) to affect
+ * @param enabled true to set the default to enabled
+ * @see #setDefaultAssertionStatus(boolean)
+ * @see #setClassAssertionStatus(String, boolean)
+ * @see #clearAssertionStatus()
+ * @since 1.4
+ */
+ public synchronized void setPackageAssertionStatus(String name,
+ boolean enabled)
+ {
+ if (packageAssertionStatus == null)
+ packageAssertionStatus
+ = new HashMap(systemPackageAssertionStatus);
+ packageAssertionStatus.put(name, Boolean.valueOf(enabled));
+ }
+
+ /**
+ * Set the default assertion status for a class. This only affects the
+ * status of top-level classes, any other string is harmless.
+ *
+ * @param name the class to affect
+ * @param enabled true to set the default to enabled
+ * @throws NullPointerException if name is null
+ * @see #setDefaultAssertionStatus(boolean)
+ * @see #setPackageAssertionStatus(String, boolean)
+ * @see #clearAssertionStatus()
+ * @since 1.4
+ */
+ public synchronized void setClassAssertionStatus(String name,
+ boolean enabled)
+ {
+ if (classAssertionStatus == null)
+ classAssertionStatus = new HashMap(systemClassAssertionStatus);
+ // The toString() hack catches null, as required.
+ classAssertionStatus.put(name.toString(), Boolean.valueOf(enabled));
+ }
+
+ /**
+ * Resets the default assertion status of this classloader, its packages
+ * and classes, all to false. This allows overriding defaults inherited
+ * from the command line.
+ *
+ * @see #setDefaultAssertionStatus(boolean)
+ * @see #setClassAssertionStatus(String, boolean)
+ * @see #setPackageAssertionStatus(String, boolean)
+ * @since 1.4
+ */
+ public synchronized void clearAssertionStatus()
+ {
+ defaultAssertionStatus = false;
+ packageAssertionStatus = new HashMap();
+ classAssertionStatus = new HashMap();
+ }
+
+ /**
+ * Return true if this loader is either the specified class loader
+ * or an ancestor thereof.
+ * @param loader the class loader to check
+ */
+ final boolean isAncestorOf(ClassLoader loader)
+ {
+ while (loader != null)
+ {
+ if (this == loader)
+ return true;
+ loader = loader.parent;
+ }
+ return false;
+ }
+
+ /**
+ * Before doing anything "dangerous" please call this method to make sure
+ * this class loader instance was properly constructed (and not obtained
+ * by exploiting the finalizer attack)
+ * @see #initialized
+ */
+ private void checkInitialized()
+ {
+ if (! initialized)
+ throw new SecurityException("attempt to use uninitialized class loader");
+ }
+}
diff --git a/libjava/java/lang/ClassNotFoundException.h b/libjava/java/lang/ClassNotFoundException.h
new file mode 100644
index 000000000..c0ab78158
--- /dev/null
+++ b/libjava/java/lang/ClassNotFoundException.h
@@ -0,0 +1,27 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ClassNotFoundException__
+#define __java_lang_ClassNotFoundException__
+
+#pragma interface
+
+#include <java/lang/Exception.h>
+
+class java::lang::ClassNotFoundException : public ::java::lang::Exception
+{
+
+public:
+ ClassNotFoundException();
+ ClassNotFoundException(::java::lang::String *);
+ ClassNotFoundException(::java::lang::String *, ::java::lang::Throwable *);
+ virtual ::java::lang::Throwable * getException();
+ virtual ::java::lang::Throwable * getCause();
+private:
+ static const jlong serialVersionUID = 9176873029745254542LL;
+ ::java::lang::Throwable * __attribute__((aligned(__alignof__( ::java::lang::Exception)))) ex;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ClassNotFoundException__
diff --git a/libjava/java/lang/CloneNotSupportedException.h b/libjava/java/lang/CloneNotSupportedException.h
new file mode 100644
index 000000000..19fa2124a
--- /dev/null
+++ b/libjava/java/lang/CloneNotSupportedException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_CloneNotSupportedException__
+#define __java_lang_CloneNotSupportedException__
+
+#pragma interface
+
+#include <java/lang/Exception.h>
+
+class java::lang::CloneNotSupportedException : public ::java::lang::Exception
+{
+
+public:
+ CloneNotSupportedException();
+ CloneNotSupportedException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 5195511250079656443LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_CloneNotSupportedException__
diff --git a/libjava/java/lang/Cloneable.h b/libjava/java/lang/Cloneable.h
new file mode 100644
index 000000000..ff5db98d0
--- /dev/null
+++ b/libjava/java/lang/Cloneable.h
@@ -0,0 +1,18 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Cloneable__
+#define __java_lang_Cloneable__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Cloneable : public ::java::lang::Object
+{
+
+public:
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_Cloneable__
diff --git a/libjava/java/lang/Comparable.h b/libjava/java/lang/Comparable.h
new file mode 100644
index 000000000..b594e2ddc
--- /dev/null
+++ b/libjava/java/lang/Comparable.h
@@ -0,0 +1,19 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Comparable__
+#define __java_lang_Comparable__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Comparable : public ::java::lang::Object
+{
+
+public:
+ virtual jint compareTo(::java::lang::Object *) = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_Comparable__
diff --git a/libjava/java/lang/Compiler.h b/libjava/java/lang/Compiler.h
new file mode 100644
index 000000000..e21d90300
--- /dev/null
+++ b/libjava/java/lang/Compiler.h
@@ -0,0 +1,24 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Compiler__
+#define __java_lang_Compiler__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Compiler : public ::java::lang::Object
+{
+
+ Compiler();
+public:
+ static jboolean compileClass(::java::lang::Class *);
+ static jboolean compileClasses(::java::lang::String *);
+ static ::java::lang::Object * command(::java::lang::Object *);
+ static void enable();
+ static void disable();
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Compiler__
diff --git a/libjava/java/lang/Deprecated.h b/libjava/java/lang/Deprecated.h
new file mode 100644
index 000000000..6ab34f11a
--- /dev/null
+++ b/libjava/java/lang/Deprecated.h
@@ -0,0 +1,19 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Deprecated__
+#define __java_lang_Deprecated__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Deprecated : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::Class * annotationType() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_Deprecated__
diff --git a/libjava/java/lang/Double.h b/libjava/java/lang/Double.h
new file mode 100644
index 000000000..54eb42b50
--- /dev/null
+++ b/libjava/java/lang/Double.h
@@ -0,0 +1,59 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Double__
+#define __java_lang_Double__
+
+#pragma interface
+
+#include <java/lang/Number.h>
+
+class java::lang::Double : public ::java::lang::Number
+{
+
+public:
+ Double(jdouble);
+ Double(::java::lang::String *);
+ static ::java::lang::String * toString(jdouble);
+ static ::java::lang::String * toHexString(jdouble);
+ static ::java::lang::Double * valueOf(jdouble);
+ static ::java::lang::Double * valueOf(::java::lang::String *);
+ static jdouble parseDouble(::java::lang::String *);
+ static jboolean isNaN(jdouble);
+ static jboolean isInfinite(jdouble);
+ jboolean isNaN();
+ jboolean isInfinite();
+ ::java::lang::String * toString();
+ jbyte byteValue();
+ jshort shortValue();
+ jint intValue();
+ jlong longValue();
+ jfloat floatValue();
+ jdouble doubleValue();
+ jint hashCode();
+ jboolean equals(::java::lang::Object *);
+ static jlong doubleToLongBits(jdouble);
+ static jlong doubleToRawLongBits(jdouble);
+ static jdouble longBitsToDouble(jlong);
+ jint Double$compareTo(::java::lang::Double *);
+ static jint compare(jdouble, jdouble);
+ jint compareTo(::java::lang::Object *);
+private:
+ static const jlong serialVersionUID = -9172774392245257468LL;
+public:
+ static jdouble MAX_VALUE;
+ static jdouble MIN_VALUE;
+ static jdouble NEGATIVE_INFINITY;
+ static jdouble POSITIVE_INFINITY;
+ static jdouble NaN;
+ static const jint SIZE = 64;
+ static ::java::lang::Class * TYPE;
+private:
+ static ::java::lang::Double * ZERO;
+ static ::java::lang::Double * ONE;
+ jdouble __attribute__((aligned(__alignof__( ::java::lang::Number)))) value;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Double__
diff --git a/libjava/java/lang/EcosProcess.h b/libjava/java/lang/EcosProcess.h
new file mode 100644
index 000000000..a0173c30a
--- /dev/null
+++ b/libjava/java/lang/EcosProcess.h
@@ -0,0 +1,27 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_EcosProcess__
+#define __java_lang_EcosProcess__
+
+#pragma interface
+
+#include <java/lang/Process.h>
+#include <gcj/array.h>
+
+
+class java::lang::EcosProcess : public ::java::lang::Process
+{
+
+public:
+ void destroy();
+ jint exitValue();
+ ::java::io::InputStream * getErrorStream();
+ ::java::io::InputStream * getInputStream();
+ ::java::io::OutputStream * getOutputStream();
+ jint waitFor();
+ EcosProcess(JArray< ::java::lang::String * > *, JArray< ::java::lang::String * > *, ::java::io::File *, jboolean);
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_EcosProcess__
diff --git a/libjava/java/lang/EcosProcess.java b/libjava/java/lang/EcosProcess.java
new file mode 100644
index 000000000..79c2f12a5
--- /dev/null
+++ b/libjava/java/lang/EcosProcess.java
@@ -0,0 +1,60 @@
+// EcosProcess.java - Subclass of Process for eCos systems.
+
+/* Copyright (C) 1998, 1999, 2006, 2007 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date May 11, 1999
+ */
+
+// This is entirely internal to our implementation.
+
+final class EcosProcess extends Process
+{
+ // See natEcosProcess.cc to understand why this is native.
+ public native void destroy ();
+
+ public int exitValue ()
+ {
+ return 0;
+ }
+ public InputStream getErrorStream ()
+ {
+ return null;
+ }
+
+ public InputStream getInputStream ()
+ {
+ return null;
+ }
+
+ public OutputStream getOutputStream ()
+ {
+ return null;
+ }
+
+ public int waitFor () throws InterruptedException
+ {
+ return 0;
+ }
+
+ public EcosProcess (String[] progarray, String[] envp, File dir,
+ boolean redirect)
+ throws IOException
+ {
+ throw new IOException ("eCos processes unimplemented");
+ }
+}
diff --git a/libjava/java/lang/Enum.h b/libjava/java/lang/Enum.h
new file mode 100644
index 000000000..15ccb1615
--- /dev/null
+++ b/libjava/java/lang/Enum.h
@@ -0,0 +1,41 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Enum__
+#define __java_lang_Enum__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Enum : public ::java::lang::Object
+{
+
+public: // actually protected
+ Enum(::java::lang::String *, jint);
+public:
+ static ::java::lang::Enum * valueOf(::java::lang::Class *, ::java::lang::String *);
+ virtual jboolean equals(::java::lang::Object *);
+ virtual jint hashCode();
+ virtual ::java::lang::String * toString();
+ virtual jint Enum$compareTo(::java::lang::Enum *);
+public: // actually protected
+ virtual ::java::lang::Object * clone();
+public:
+ virtual ::java::lang::String * name();
+ virtual jint ordinal();
+ virtual ::java::lang::Class * getDeclaringClass();
+public: // actually protected
+ virtual void finalize();
+public:
+ virtual jint compareTo(::java::lang::Object *);
+private:
+ static const jlong serialVersionUID = -4300926546619394005LL;
+public: // actually package-private
+ ::java::lang::String * __attribute__((aligned(__alignof__( ::java::lang::Object)))) name__;
+ jint ordinal__;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Enum__
diff --git a/libjava/java/lang/EnumConstantNotPresentException.h b/libjava/java/lang/EnumConstantNotPresentException.h
new file mode 100644
index 000000000..b3bc11b28
--- /dev/null
+++ b/libjava/java/lang/EnumConstantNotPresentException.h
@@ -0,0 +1,26 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_EnumConstantNotPresentException__
+#define __java_lang_EnumConstantNotPresentException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::EnumConstantNotPresentException : public ::java::lang::RuntimeException
+{
+
+public:
+ EnumConstantNotPresentException(::java::lang::Class *, ::java::lang::String *);
+ virtual ::java::lang::String * constantName();
+ virtual ::java::lang::Class * enumType();
+private:
+ static const jlong serialVersionUID = -6046998521960521108LL;
+ ::java::lang::Class * __attribute__((aligned(__alignof__( ::java::lang::RuntimeException)))) enumType__;
+ ::java::lang::String * constantName__;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_EnumConstantNotPresentException__
diff --git a/libjava/java/lang/Error.h b/libjava/java/lang/Error.h
new file mode 100644
index 000000000..9cb6019b4
--- /dev/null
+++ b/libjava/java/lang/Error.h
@@ -0,0 +1,25 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Error__
+#define __java_lang_Error__
+
+#pragma interface
+
+#include <java/lang/Throwable.h>
+
+class java::lang::Error : public ::java::lang::Throwable
+{
+
+public:
+ Error();
+ Error(::java::lang::String *);
+ Error(::java::lang::String *, ::java::lang::Throwable *);
+ Error(::java::lang::Throwable *);
+private:
+ static const jlong serialVersionUID = 4980196508277280342LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Error__
diff --git a/libjava/java/lang/Exception.h b/libjava/java/lang/Exception.h
new file mode 100644
index 000000000..9f3ab43a5
--- /dev/null
+++ b/libjava/java/lang/Exception.h
@@ -0,0 +1,25 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Exception__
+#define __java_lang_Exception__
+
+#pragma interface
+
+#include <java/lang/Throwable.h>
+
+class java::lang::Exception : public ::java::lang::Throwable
+{
+
+public:
+ Exception();
+ Exception(::java::lang::String *);
+ Exception(::java::lang::String *, ::java::lang::Throwable *);
+ Exception(::java::lang::Throwable *);
+private:
+ static const jlong serialVersionUID = -3387516993124229948LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Exception__
diff --git a/libjava/java/lang/ExceptionInInitializerError.h b/libjava/java/lang/ExceptionInInitializerError.h
new file mode 100644
index 000000000..89fbaee7c
--- /dev/null
+++ b/libjava/java/lang/ExceptionInInitializerError.h
@@ -0,0 +1,28 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ExceptionInInitializerError__
+#define __java_lang_ExceptionInInitializerError__
+
+#pragma interface
+
+#include <java/lang/LinkageError.h>
+
+class java::lang::ExceptionInInitializerError : public ::java::lang::LinkageError
+{
+
+public:
+ ExceptionInInitializerError();
+ ExceptionInInitializerError(::java::lang::String *);
+ ExceptionInInitializerError(::java::lang::Throwable *);
+ virtual ::java::lang::Throwable * getException();
+ virtual ::java::lang::Throwable * getCause();
+public: // actually package-private
+ static const jlong serialVersionUID = 1521711792217232256LL;
+private:
+ ::java::lang::Throwable * __attribute__((aligned(__alignof__( ::java::lang::LinkageError)))) exception;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ExceptionInInitializerError__
diff --git a/libjava/java/lang/Float.h b/libjava/java/lang/Float.h
new file mode 100644
index 000000000..603da6dd1
--- /dev/null
+++ b/libjava/java/lang/Float.h
@@ -0,0 +1,60 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Float__
+#define __java_lang_Float__
+
+#pragma interface
+
+#include <java/lang/Number.h>
+
+class java::lang::Float : public ::java::lang::Number
+{
+
+public:
+ Float(jfloat);
+ Float(jdouble);
+ Float(::java::lang::String *);
+ static ::java::lang::String * toString(jfloat);
+ static ::java::lang::String * toHexString(jfloat);
+ static ::java::lang::Float * valueOf(::java::lang::String *);
+ static ::java::lang::Float * valueOf(jfloat);
+ static jfloat parseFloat(::java::lang::String *);
+ static jboolean isNaN(jfloat);
+ static jboolean isInfinite(jfloat);
+ jboolean isNaN();
+ jboolean isInfinite();
+ ::java::lang::String * toString();
+ jbyte byteValue();
+ jshort shortValue();
+ jint intValue();
+ jlong longValue();
+ jfloat floatValue();
+ jdouble doubleValue();
+ jint hashCode();
+ jboolean equals(::java::lang::Object *);
+ static jint floatToIntBits(jfloat);
+ static jint floatToRawIntBits(jfloat);
+ static jfloat intBitsToFloat(jint);
+ jint Float$compareTo(::java::lang::Float *);
+ static jint compare(jfloat, jfloat);
+ jint compareTo(::java::lang::Object *);
+private:
+ static const jlong serialVersionUID = -2671257302660747028LL;
+public:
+ static jfloat MAX_VALUE;
+ static jfloat MIN_VALUE;
+ static jfloat NEGATIVE_INFINITY;
+ static jfloat POSITIVE_INFINITY;
+ static jfloat NaN;
+ static ::java::lang::Class * TYPE;
+ static const jint SIZE = 32;
+private:
+ static ::java::lang::Float * ZERO;
+ static ::java::lang::Float * ONE;
+ jfloat __attribute__((aligned(__alignof__( ::java::lang::Number)))) value;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Float__
diff --git a/libjava/java/lang/IllegalAccessError.h b/libjava/java/lang/IllegalAccessError.h
new file mode 100644
index 000000000..12b8747c4
--- /dev/null
+++ b/libjava/java/lang/IllegalAccessError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_IllegalAccessError__
+#define __java_lang_IllegalAccessError__
+
+#pragma interface
+
+#include <java/lang/IncompatibleClassChangeError.h>
+
+class java::lang::IllegalAccessError : public ::java::lang::IncompatibleClassChangeError
+{
+
+public:
+ IllegalAccessError();
+ IllegalAccessError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -8988904074992417891LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_IllegalAccessError__
diff --git a/libjava/java/lang/IllegalAccessException.h b/libjava/java/lang/IllegalAccessException.h
new file mode 100644
index 000000000..c09174756
--- /dev/null
+++ b/libjava/java/lang/IllegalAccessException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_IllegalAccessException__
+#define __java_lang_IllegalAccessException__
+
+#pragma interface
+
+#include <java/lang/Exception.h>
+
+class java::lang::IllegalAccessException : public ::java::lang::Exception
+{
+
+public:
+ IllegalAccessException();
+ IllegalAccessException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 6616958222490762034LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_IllegalAccessException__
diff --git a/libjava/java/lang/IllegalArgumentException.h b/libjava/java/lang/IllegalArgumentException.h
new file mode 100644
index 000000000..187e430c1
--- /dev/null
+++ b/libjava/java/lang/IllegalArgumentException.h
@@ -0,0 +1,25 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_IllegalArgumentException__
+#define __java_lang_IllegalArgumentException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::IllegalArgumentException : public ::java::lang::RuntimeException
+{
+
+public:
+ IllegalArgumentException();
+ IllegalArgumentException(::java::lang::String *);
+ IllegalArgumentException(::java::lang::String *, ::java::lang::Throwable *);
+ IllegalArgumentException(::java::lang::Throwable *);
+private:
+ static const jlong serialVersionUID = -5365630128856068164LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_IllegalArgumentException__
diff --git a/libjava/java/lang/IllegalMonitorStateException.h b/libjava/java/lang/IllegalMonitorStateException.h
new file mode 100644
index 000000000..ad9cb5902
--- /dev/null
+++ b/libjava/java/lang/IllegalMonitorStateException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_IllegalMonitorStateException__
+#define __java_lang_IllegalMonitorStateException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::IllegalMonitorStateException : public ::java::lang::RuntimeException
+{
+
+public:
+ IllegalMonitorStateException();
+ IllegalMonitorStateException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 3713306369498869069LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_IllegalMonitorStateException__
diff --git a/libjava/java/lang/IllegalStateException.h b/libjava/java/lang/IllegalStateException.h
new file mode 100644
index 000000000..e79bced81
--- /dev/null
+++ b/libjava/java/lang/IllegalStateException.h
@@ -0,0 +1,25 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_IllegalStateException__
+#define __java_lang_IllegalStateException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::IllegalStateException : public ::java::lang::RuntimeException
+{
+
+public:
+ IllegalStateException();
+ IllegalStateException(::java::lang::String *);
+ IllegalStateException(::java::lang::String *, ::java::lang::Throwable *);
+ IllegalStateException(::java::lang::Throwable *);
+private:
+ static const jlong serialVersionUID = -1848914673093119416LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_IllegalStateException__
diff --git a/libjava/java/lang/IllegalThreadStateException.h b/libjava/java/lang/IllegalThreadStateException.h
new file mode 100644
index 000000000..066eb92cd
--- /dev/null
+++ b/libjava/java/lang/IllegalThreadStateException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_IllegalThreadStateException__
+#define __java_lang_IllegalThreadStateException__
+
+#pragma interface
+
+#include <java/lang/IllegalArgumentException.h>
+
+class java::lang::IllegalThreadStateException : public ::java::lang::IllegalArgumentException
+{
+
+public:
+ IllegalThreadStateException();
+ IllegalThreadStateException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -7626246362397460174LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_IllegalThreadStateException__
diff --git a/libjava/java/lang/IncompatibleClassChangeError.h b/libjava/java/lang/IncompatibleClassChangeError.h
new file mode 100644
index 000000000..ca4099194
--- /dev/null
+++ b/libjava/java/lang/IncompatibleClassChangeError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_IncompatibleClassChangeError__
+#define __java_lang_IncompatibleClassChangeError__
+
+#pragma interface
+
+#include <java/lang/LinkageError.h>
+
+class java::lang::IncompatibleClassChangeError : public ::java::lang::LinkageError
+{
+
+public:
+ IncompatibleClassChangeError();
+ IncompatibleClassChangeError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -4914975503642802119LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_IncompatibleClassChangeError__
diff --git a/libjava/java/lang/IndexOutOfBoundsException.h b/libjava/java/lang/IndexOutOfBoundsException.h
new file mode 100644
index 000000000..4cd4184a7
--- /dev/null
+++ b/libjava/java/lang/IndexOutOfBoundsException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_IndexOutOfBoundsException__
+#define __java_lang_IndexOutOfBoundsException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::IndexOutOfBoundsException : public ::java::lang::RuntimeException
+{
+
+public:
+ IndexOutOfBoundsException();
+ IndexOutOfBoundsException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 234122996006267687LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_IndexOutOfBoundsException__
diff --git a/libjava/java/lang/InheritableThreadLocal.h b/libjava/java/lang/InheritableThreadLocal.h
new file mode 100644
index 000000000..9caf6f3df
--- /dev/null
+++ b/libjava/java/lang/InheritableThreadLocal.h
@@ -0,0 +1,24 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_InheritableThreadLocal__
+#define __java_lang_InheritableThreadLocal__
+
+#pragma interface
+
+#include <java/lang/ThreadLocal.h>
+
+class java::lang::InheritableThreadLocal : public ::java::lang::ThreadLocal
+{
+
+public:
+ InheritableThreadLocal();
+public: // actually protected
+ virtual ::java::lang::Object * childValue(::java::lang::Object *);
+public: // actually package-private
+ static void newChildThread(::java::lang::Thread *);
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_InheritableThreadLocal__
diff --git a/libjava/java/lang/InstantiationError.h b/libjava/java/lang/InstantiationError.h
new file mode 100644
index 000000000..4b817d2b3
--- /dev/null
+++ b/libjava/java/lang/InstantiationError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_InstantiationError__
+#define __java_lang_InstantiationError__
+
+#pragma interface
+
+#include <java/lang/IncompatibleClassChangeError.h>
+
+class java::lang::InstantiationError : public ::java::lang::IncompatibleClassChangeError
+{
+
+public:
+ InstantiationError();
+ InstantiationError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -4885810657349421204LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_InstantiationError__
diff --git a/libjava/java/lang/InstantiationException.h b/libjava/java/lang/InstantiationException.h
new file mode 100644
index 000000000..805ab3c70
--- /dev/null
+++ b/libjava/java/lang/InstantiationException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_InstantiationException__
+#define __java_lang_InstantiationException__
+
+#pragma interface
+
+#include <java/lang/Exception.h>
+
+class java::lang::InstantiationException : public ::java::lang::Exception
+{
+
+public:
+ InstantiationException();
+ InstantiationException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -8441929162975509110LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_InstantiationException__
diff --git a/libjava/java/lang/Integer.h b/libjava/java/lang/Integer.h
new file mode 100644
index 000000000..f1bd11bdb
--- /dev/null
+++ b/libjava/java/lang/Integer.h
@@ -0,0 +1,77 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Integer__
+#define __java_lang_Integer__
+
+#pragma interface
+
+#include <java/lang/Number.h>
+#include <gcj/array.h>
+
+
+class java::lang::Integer : public ::java::lang::Number
+{
+
+public:
+ Integer(jint);
+ Integer(::java::lang::String *);
+private:
+ static jint stringSize(jint, jint);
+public:
+ static ::java::lang::String * toString(jint, jint);
+ static ::java::lang::String * toHexString(jint);
+ static ::java::lang::String * toOctalString(jint);
+ static ::java::lang::String * toBinaryString(jint);
+ static ::java::lang::String * toString(jint);
+ static jint parseInt(::java::lang::String *, jint);
+ static jint parseInt(::java::lang::String *);
+ static ::java::lang::Integer * valueOf(::java::lang::String *, jint);
+ static ::java::lang::Integer * valueOf(::java::lang::String *);
+ static ::java::lang::Integer * valueOf(jint);
+ jbyte byteValue();
+ jshort shortValue();
+ jint intValue();
+ jlong longValue();
+ jfloat floatValue();
+ jdouble doubleValue();
+ ::java::lang::String * toString();
+ jint hashCode();
+ jboolean equals(::java::lang::Object *);
+ static ::java::lang::Integer * getInteger(::java::lang::String *);
+ static ::java::lang::Integer * getInteger(::java::lang::String *, jint);
+ static ::java::lang::Integer * getInteger(::java::lang::String *, ::java::lang::Integer *);
+ static ::java::lang::Integer * decode(::java::lang::String *);
+ jint Integer$compareTo(::java::lang::Integer *);
+ static jint bitCount(jint);
+ static jint rotateLeft(jint, jint);
+ static jint rotateRight(jint, jint);
+ static jint highestOneBit(jint);
+ static jint numberOfLeadingZeros(jint);
+ static jint lowestOneBit(jint);
+ static jint numberOfTrailingZeros(jint);
+ static jint signum(jint);
+ static jint reverseBytes(jint);
+ static jint reverse(jint);
+public: // actually package-private
+ static ::java::lang::String * toUnsignedString(jint, jint);
+ static jint parseInt(::java::lang::String *, jint, jboolean);
+public:
+ jint compareTo(::java::lang::Object *);
+private:
+ static const jlong serialVersionUID = 1360826667806852920LL;
+public:
+ static const jint MIN_VALUE = -2147483647 - 1;
+ static const jint MAX_VALUE = 2147483647;
+ static ::java::lang::Class * TYPE;
+ static const jint SIZE = 32;
+private:
+ static const jint MIN_CACHE = -128;
+ static const jint MAX_CACHE = 127;
+ static JArray< ::java::lang::Integer * > * intCache;
+ jint __attribute__((aligned(__alignof__( ::java::lang::Number)))) value;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Integer__
diff --git a/libjava/java/lang/InternalError.h b/libjava/java/lang/InternalError.h
new file mode 100644
index 000000000..b0477bbe6
--- /dev/null
+++ b/libjava/java/lang/InternalError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_InternalError__
+#define __java_lang_InternalError__
+
+#pragma interface
+
+#include <java/lang/VirtualMachineError.h>
+
+class java::lang::InternalError : public ::java::lang::VirtualMachineError
+{
+
+public:
+ InternalError();
+ InternalError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -9062593416125562365LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_InternalError__
diff --git a/libjava/java/lang/InterruptedException.h b/libjava/java/lang/InterruptedException.h
new file mode 100644
index 000000000..c452de6b5
--- /dev/null
+++ b/libjava/java/lang/InterruptedException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_InterruptedException__
+#define __java_lang_InterruptedException__
+
+#pragma interface
+
+#include <java/lang/Exception.h>
+
+class java::lang::InterruptedException : public ::java::lang::Exception
+{
+
+public:
+ InterruptedException();
+ InterruptedException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 6700697376100628473LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_InterruptedException__
diff --git a/libjava/java/lang/Iterable.h b/libjava/java/lang/Iterable.h
new file mode 100644
index 000000000..3bdb2543b
--- /dev/null
+++ b/libjava/java/lang/Iterable.h
@@ -0,0 +1,19 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Iterable__
+#define __java_lang_Iterable__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Iterable : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::util::Iterator * iterator() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_Iterable__
diff --git a/libjava/java/lang/LinkageError.h b/libjava/java/lang/LinkageError.h
new file mode 100644
index 000000000..4368d8b9f
--- /dev/null
+++ b/libjava/java/lang/LinkageError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_LinkageError__
+#define __java_lang_LinkageError__
+
+#pragma interface
+
+#include <java/lang/Error.h>
+
+class java::lang::LinkageError : public ::java::lang::Error
+{
+
+public:
+ LinkageError();
+ LinkageError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 3579600108157160122LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_LinkageError__
diff --git a/libjava/java/lang/Long.h b/libjava/java/lang/Long.h
new file mode 100644
index 000000000..60c0d2437
--- /dev/null
+++ b/libjava/java/lang/Long.h
@@ -0,0 +1,77 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Long__
+#define __java_lang_Long__
+
+#pragma interface
+
+#include <java/lang/Number.h>
+#include <gcj/array.h>
+
+
+class java::lang::Long : public ::java::lang::Number
+{
+
+public:
+ Long(jlong);
+ Long(::java::lang::String *);
+private:
+ static jint stringSize(jlong, jint);
+public:
+ static ::java::lang::String * toString(jlong, jint);
+ static ::java::lang::String * toHexString(jlong);
+ static ::java::lang::String * toOctalString(jlong);
+ static ::java::lang::String * toBinaryString(jlong);
+ static ::java::lang::String * toString(jlong);
+ static jlong parseLong(::java::lang::String *, jint);
+ static jlong parseLong(::java::lang::String *);
+ static ::java::lang::Long * valueOf(::java::lang::String *, jint);
+ static ::java::lang::Long * valueOf(::java::lang::String *);
+ static ::java::lang::Long * valueOf(jlong);
+ static ::java::lang::Long * decode(::java::lang::String *);
+ jbyte byteValue();
+ jshort shortValue();
+ jint intValue();
+ jlong longValue();
+ jfloat floatValue();
+ jdouble doubleValue();
+ ::java::lang::String * toString();
+ jint hashCode();
+ jboolean equals(::java::lang::Object *);
+ static ::java::lang::Long * getLong(::java::lang::String *);
+ static ::java::lang::Long * getLong(::java::lang::String *, jlong);
+ static ::java::lang::Long * getLong(::java::lang::String *, ::java::lang::Long *);
+ jint Long$compareTo(::java::lang::Long *);
+ static jint bitCount(jlong);
+ static jlong rotateLeft(jlong, jint);
+ static jlong rotateRight(jlong, jint);
+ static jlong highestOneBit(jlong);
+ static jint numberOfLeadingZeros(jlong);
+ static jlong lowestOneBit(jlong);
+ static jint numberOfTrailingZeros(jlong);
+ static jint signum(jlong);
+ static jlong reverseBytes(jlong);
+ static jlong reverse(jlong);
+private:
+ static ::java::lang::String * toUnsignedString(jlong, jint);
+ static jlong parseLong(::java::lang::String *, jint, jboolean);
+public:
+ jint compareTo(::java::lang::Object *);
+private:
+ static const jlong serialVersionUID = 4290774380558885855LL;
+public:
+ static const jlong MIN_VALUE = -9223372036854775807LL - 1;
+ static const jlong MAX_VALUE = 9223372036854775807LL;
+ static ::java::lang::Class * TYPE;
+ static const jint SIZE = 64;
+private:
+ static const jint MIN_CACHE = -128;
+ static const jint MAX_CACHE = 127;
+ static JArray< ::java::lang::Long * > * longCache;
+ jlong __attribute__((aligned(__alignof__( ::java::lang::Number)))) value;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Long__
diff --git a/libjava/java/lang/Math.h b/libjava/java/lang/Math.h
new file mode 100644
index 000000000..32707e9f8
--- /dev/null
+++ b/libjava/java/lang/Math.h
@@ -0,0 +1,68 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Math__
+#define __java_lang_Math__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Math : public ::java::lang::Object
+{
+
+ Math();
+public:
+ static jint abs(jint);
+ static jlong abs(jlong);
+ static jfloat abs(jfloat);
+ static jdouble abs(jdouble);
+ static jint min(jint, jint);
+ static jlong min(jlong, jlong);
+ static jfloat min(jfloat, jfloat);
+ static jdouble min(jdouble, jdouble);
+ static jint max(jint, jint);
+ static jlong max(jlong, jlong);
+ static jfloat max(jfloat, jfloat);
+ static jdouble max(jdouble, jdouble);
+ static jdouble sin(jdouble);
+ static jdouble cos(jdouble);
+ static jdouble tan(jdouble);
+ static jdouble asin(jdouble);
+ static jdouble acos(jdouble);
+ static jdouble atan(jdouble);
+ static jdouble atan2(jdouble, jdouble);
+ static jdouble exp(jdouble);
+ static jdouble log(jdouble);
+ static jdouble sqrt(jdouble);
+ static jdouble pow(jdouble, jdouble);
+ static jdouble IEEEremainder(jdouble, jdouble);
+ static jdouble ceil(jdouble);
+ static jdouble floor(jdouble);
+ static jdouble rint(jdouble);
+ static jint round(jfloat);
+ static jlong round(jdouble);
+ static jdouble random();
+ static jdouble toRadians(jdouble);
+ static jdouble toDegrees(jdouble);
+ static jdouble cbrt(jdouble);
+ static jdouble cosh(jdouble);
+ static jdouble expm1(jdouble);
+ static jdouble hypot(jdouble, jdouble);
+ static jdouble log10(jdouble);
+ static jdouble log1p(jdouble);
+ static jdouble signum(jdouble);
+ static jfloat signum(jfloat);
+ static jdouble sinh(jdouble);
+ static jdouble tanh(jdouble);
+ static jdouble ulp(jdouble);
+ static jfloat ulp(jfloat);
+private:
+ static ::java::util::Random * rand;
+public:
+ static jdouble E;
+ static jdouble PI;
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Math__
diff --git a/libjava/java/lang/Math.java b/libjava/java/lang/Math.java
new file mode 100644
index 000000000..836b8bd86
--- /dev/null
+++ b/libjava/java/lang/Math.java
@@ -0,0 +1,973 @@
+/* java.lang.Math -- common mathematical functions, native allowed
+ Copyright (C) 1998, 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang;
+
+import gnu.classpath.Configuration;
+
+import java.util.Random;
+
+/**
+ * Helper class containing useful mathematical functions and constants.
+ * <P>
+ *
+ * Note that angles are specified in radians. Conversion functions are
+ * provided for your convenience.
+ *
+ * @author Paul Fisher
+ * @author John Keiser
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.0
+ */
+public final class Math
+{
+ /**
+ * Math is non-instantiable
+ */
+ private Math()
+ {
+ }
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javalang");
+ }
+ }
+
+ /**
+ * A random number generator, initialized on first use.
+ */
+ private static Random rand;
+
+ /**
+ * The most accurate approximation to the mathematical constant <em>e</em>:
+ * <code>2.718281828459045</code>. Used in natural log and exp.
+ *
+ * @see #log(double)
+ * @see #exp(double)
+ */
+ public static final double E = 2.718281828459045;
+
+ /**
+ * The most accurate approximation to the mathematical constant <em>pi</em>:
+ * <code>3.141592653589793</code>. This is the ratio of a circle's diameter
+ * to its circumference.
+ */
+ public static final double PI = 3.141592653589793;
+
+ /**
+ * Take the absolute value of the argument.
+ * (Absolute value means make it positive.)
+ * <P>
+ *
+ * Note that the the largest negative value (Integer.MIN_VALUE) cannot
+ * be made positive. In this case, because of the rules of negation in
+ * a computer, MIN_VALUE is what will be returned.
+ * This is a <em>negative</em> value. You have been warned.
+ *
+ * @param i the number to take the absolute value of
+ * @return the absolute value
+ * @see Integer#MIN_VALUE
+ */
+ public static int abs(int i)
+ {
+ return (i < 0) ? -i : i;
+ }
+
+ /**
+ * Take the absolute value of the argument.
+ * (Absolute value means make it positive.)
+ * <P>
+ *
+ * Note that the the largest negative value (Long.MIN_VALUE) cannot
+ * be made positive. In this case, because of the rules of negation in
+ * a computer, MIN_VALUE is what will be returned.
+ * This is a <em>negative</em> value. You have been warned.
+ *
+ * @param l the number to take the absolute value of
+ * @return the absolute value
+ * @see Long#MIN_VALUE
+ */
+ public static long abs(long l)
+ {
+ return (l < 0) ? -l : l;
+ }
+
+ /**
+ * Take the absolute value of the argument.
+ * (Absolute value means make it positive.)
+ * <P>
+ *
+ * This is equivalent, but faster than, calling
+ * <code>Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))</code>.
+ *
+ * @param f the number to take the absolute value of
+ * @return the absolute value
+ */
+ public static float abs(float f)
+ {
+ return (f <= 0) ? 0 - f : f;
+ }
+
+ /**
+ * Take the absolute value of the argument.
+ * (Absolute value means make it positive.)
+ *
+ * This is equivalent, but faster than, calling
+ * <code>Double.longBitsToDouble(Double.doubleToLongBits(a)
+ * &lt;&lt; 1) &gt;&gt;&gt; 1);</code>.
+ *
+ * @param d the number to take the absolute value of
+ * @return the absolute value
+ */
+ public static double abs(double d)
+ {
+ return (d <= 0) ? 0 - d : d;
+ }
+
+ /**
+ * Return whichever argument is smaller.
+ *
+ * @param a the first number
+ * @param b a second number
+ * @return the smaller of the two numbers
+ */
+ public static int min(int a, int b)
+ {
+ return (a < b) ? a : b;
+ }
+
+ /**
+ * Return whichever argument is smaller.
+ *
+ * @param a the first number
+ * @param b a second number
+ * @return the smaller of the two numbers
+ */
+ public static long min(long a, long b)
+ {
+ return (a < b) ? a : b;
+ }
+
+ /**
+ * Return whichever argument is smaller. If either argument is NaN, the
+ * result is NaN, and when comparing 0 and -0, -0 is always smaller.
+ *
+ * @param a the first number
+ * @param b a second number
+ * @return the smaller of the two numbers
+ */
+ public static float min(float a, float b)
+ {
+ // this check for NaN, from JLS 15.21.1, saves a method call
+ if (a != a)
+ return a;
+ // no need to check if b is NaN; < will work correctly
+ // recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special
+ if (a == 0 && b == 0)
+ return -(-a - b);
+ return (a < b) ? a : b;
+ }
+
+ /**
+ * Return whichever argument is smaller. If either argument is NaN, the
+ * result is NaN, and when comparing 0 and -0, -0 is always smaller.
+ *
+ * @param a the first number
+ * @param b a second number
+ * @return the smaller of the two numbers
+ */
+ public static double min(double a, double b)
+ {
+ // this check for NaN, from JLS 15.21.1, saves a method call
+ if (a != a)
+ return a;
+ // no need to check if b is NaN; < will work correctly
+ // recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special
+ if (a == 0 && b == 0)
+ return -(-a - b);
+ return (a < b) ? a : b;
+ }
+
+ /**
+ * Return whichever argument is larger.
+ *
+ * @param a the first number
+ * @param b a second number
+ * @return the larger of the two numbers
+ */
+ public static int max(int a, int b)
+ {
+ return (a > b) ? a : b;
+ }
+
+ /**
+ * Return whichever argument is larger.
+ *
+ * @param a the first number
+ * @param b a second number
+ * @return the larger of the two numbers
+ */
+ public static long max(long a, long b)
+ {
+ return (a > b) ? a : b;
+ }
+
+ /**
+ * Return whichever argument is larger. If either argument is NaN, the
+ * result is NaN, and when comparing 0 and -0, 0 is always larger.
+ *
+ * @param a the first number
+ * @param b a second number
+ * @return the larger of the two numbers
+ */
+ public static float max(float a, float b)
+ {
+ // this check for NaN, from JLS 15.21.1, saves a method call
+ if (a != a)
+ return a;
+ // no need to check if b is NaN; > will work correctly
+ // recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special
+ if (a == 0 && b == 0)
+ return a - -b;
+ return (a > b) ? a : b;
+ }
+
+ /**
+ * Return whichever argument is larger. If either argument is NaN, the
+ * result is NaN, and when comparing 0 and -0, 0 is always larger.
+ *
+ * @param a the first number
+ * @param b a second number
+ * @return the larger of the two numbers
+ */
+ public static double max(double a, double b)
+ {
+ // this check for NaN, from JLS 15.21.1, saves a method call
+ if (a != a)
+ return a;
+ // no need to check if b is NaN; > will work correctly
+ // recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special
+ if (a == 0 && b == 0)
+ return a - -b;
+ return (a > b) ? a : b;
+ }
+
+ /**
+ * The trigonometric function <em>sin</em>. The sine of NaN or infinity is
+ * NaN, and the sine of 0 retains its sign. This is accurate within 1 ulp,
+ * and is semi-monotonic.
+ *
+ * @param a the angle (in radians)
+ * @return sin(a)
+ */
+ public static native double sin(double a);
+
+ /**
+ * The trigonometric function <em>cos</em>. The cosine of NaN or infinity is
+ * NaN. This is accurate within 1 ulp, and is semi-monotonic.
+ *
+ * @param a the angle (in radians)
+ * @return cos(a)
+ */
+ public static native double cos(double a);
+
+ /**
+ * The trigonometric function <em>tan</em>. The tangent of NaN or infinity
+ * is NaN, and the tangent of 0 retains its sign. This is accurate within 1
+ * ulp, and is semi-monotonic.
+ *
+ * @param a the angle (in radians)
+ * @return tan(a)
+ */
+ public static native double tan(double a);
+
+ /**
+ * The trigonometric function <em>arcsin</em>. The range of angles returned
+ * is -pi/2 to pi/2 radians (-90 to 90 degrees). If the argument is NaN or
+ * its absolute value is beyond 1, the result is NaN; and the arcsine of
+ * 0 retains its sign. This is accurate within 1 ulp, and is semi-monotonic.
+ *
+ * @param a the sin to turn back into an angle
+ * @return arcsin(a)
+ */
+ public static native double asin(double a);
+
+ /**
+ * The trigonometric function <em>arccos</em>. The range of angles returned
+ * is 0 to pi radians (0 to 180 degrees). If the argument is NaN or
+ * its absolute value is beyond 1, the result is NaN. This is accurate
+ * within 1 ulp, and is semi-monotonic.
+ *
+ * @param a the cos to turn back into an angle
+ * @return arccos(a)
+ */
+ public static native double acos(double a);
+
+ /**
+ * The trigonometric function <em>arcsin</em>. The range of angles returned
+ * is -pi/2 to pi/2 radians (-90 to 90 degrees). If the argument is NaN, the
+ * result is NaN; and the arctangent of 0 retains its sign. This is accurate
+ * within 1 ulp, and is semi-monotonic.
+ *
+ * @param a the tan to turn back into an angle
+ * @return arcsin(a)
+ * @see #atan2(double, double)
+ */
+ public static native double atan(double a);
+
+ /**
+ * A special version of the trigonometric function <em>arctan</em>, for
+ * converting rectangular coordinates <em>(x, y)</em> to polar
+ * <em>(r, theta)</em>. This computes the arctangent of x/y in the range
+ * of -pi to pi radians (-180 to 180 degrees). Special cases:<ul>
+ * <li>If either argument is NaN, the result is NaN.</li>
+ * <li>If the first argument is positive zero and the second argument is
+ * positive, or the first argument is positive and finite and the second
+ * argument is positive infinity, then the result is positive zero.</li>
+ * <li>If the first argument is negative zero and the second argument is
+ * positive, or the first argument is negative and finite and the second
+ * argument is positive infinity, then the result is negative zero.</li>
+ * <li>If the first argument is positive zero and the second argument is
+ * negative, or the first argument is positive and finite and the second
+ * argument is negative infinity, then the result is the double value
+ * closest to pi.</li>
+ * <li>If the first argument is negative zero and the second argument is
+ * negative, or the first argument is negative and finite and the second
+ * argument is negative infinity, then the result is the double value
+ * closest to -pi.</li>
+ * <li>If the first argument is positive and the second argument is
+ * positive zero or negative zero, or the first argument is positive
+ * infinity and the second argument is finite, then the result is the
+ * double value closest to pi/2.</li>
+ * <li>If the first argument is negative and the second argument is
+ * positive zero or negative zero, or the first argument is negative
+ * infinity and the second argument is finite, then the result is the
+ * double value closest to -pi/2.</li>
+ * <li>If both arguments are positive infinity, then the result is the
+ * double value closest to pi/4.</li>
+ * <li>If the first argument is positive infinity and the second argument
+ * is negative infinity, then the result is the double value closest to
+ * 3*pi/4.</li>
+ * <li>If the first argument is negative infinity and the second argument
+ * is positive infinity, then the result is the double value closest to
+ * -pi/4.</li>
+ * <li>If both arguments are negative infinity, then the result is the
+ * double value closest to -3*pi/4.</li>
+ *
+ * </ul><p>This is accurate within 2 ulps, and is semi-monotonic. To get r,
+ * use sqrt(x*x+y*y).
+ *
+ * @param y the y position
+ * @param x the x position
+ * @return <em>theta</em> in the conversion of (x, y) to (r, theta)
+ * @see #atan(double)
+ */
+ public static native double atan2(double y, double x);
+
+ /**
+ * Take <em>e</em><sup>a</sup>. The opposite of <code>log()</code>. If the
+ * argument is NaN, the result is NaN; if the argument is positive infinity,
+ * the result is positive infinity; and if the argument is negative
+ * infinity, the result is positive zero. This is accurate within 1 ulp,
+ * and is semi-monotonic.
+ *
+ * @param a the number to raise to the power
+ * @return the number raised to the power of <em>e</em>
+ * @see #log(double)
+ * @see #pow(double, double)
+ */
+ public static native double exp(double a);
+
+ /**
+ * Take ln(a) (the natural log). The opposite of <code>exp()</code>. If the
+ * argument is NaN or negative, the result is NaN; if the argument is
+ * positive infinity, the result is positive infinity; and if the argument
+ * is either zero, the result is negative infinity. This is accurate within
+ * 1 ulp, and is semi-monotonic.
+ *
+ * <p>Note that the way to get log<sub>b</sub>(a) is to do this:
+ * <code>ln(a) / ln(b)</code>.
+ *
+ * @param a the number to take the natural log of
+ * @return the natural log of <code>a</code>
+ * @see #exp(double)
+ */
+ public static native double log(double a);
+
+ /**
+ * Take a square root. If the argument is NaN or negative, the result is
+ * NaN; if the argument is positive infinity, the result is positive
+ * infinity; and if the result is either zero, the result is the same.
+ * This is accurate within the limits of doubles.
+ *
+ * <p>For other roots, use pow(a, 1 / rootNumber).
+ *
+ * @param a the numeric argument
+ * @return the square root of the argument
+ * @see #pow(double, double)
+ */
+ public static native double sqrt(double a);
+
+ /**
+ * Raise a number to a power. Special cases:<ul>
+ * <li>If the second argument is positive or negative zero, then the result
+ * is 1.0.</li>
+ * <li>If the second argument is 1.0, then the result is the same as the
+ * first argument.</li>
+ * <li>If the second argument is NaN, then the result is NaN.</li>
+ * <li>If the first argument is NaN and the second argument is nonzero,
+ * then the result is NaN.</li>
+ * <li>If the absolute value of the first argument is greater than 1 and
+ * the second argument is positive infinity, or the absolute value of the
+ * first argument is less than 1 and the second argument is negative
+ * infinity, then the result is positive infinity.</li>
+ * <li>If the absolute value of the first argument is greater than 1 and
+ * the second argument is negative infinity, or the absolute value of the
+ * first argument is less than 1 and the second argument is positive
+ * infinity, then the result is positive zero.</li>
+ * <li>If the absolute value of the first argument equals 1 and the second
+ * argument is infinite, then the result is NaN.</li>
+ * <li>If the first argument is positive zero and the second argument is
+ * greater than zero, or the first argument is positive infinity and the
+ * second argument is less than zero, then the result is positive zero.</li>
+ * <li>If the first argument is positive zero and the second argument is
+ * less than zero, or the first argument is positive infinity and the
+ * second argument is greater than zero, then the result is positive
+ * infinity.</li>
+ * <li>If the first argument is negative zero and the second argument is
+ * greater than zero but not a finite odd integer, or the first argument is
+ * negative infinity and the second argument is less than zero but not a
+ * finite odd integer, then the result is positive zero.</li>
+ * <li>If the first argument is negative zero and the second argument is a
+ * positive finite odd integer, or the first argument is negative infinity
+ * and the second argument is a negative finite odd integer, then the result
+ * is negative zero.</li>
+ * <li>If the first argument is negative zero and the second argument is
+ * less than zero but not a finite odd integer, or the first argument is
+ * negative infinity and the second argument is greater than zero but not a
+ * finite odd integer, then the result is positive infinity.</li>
+ * <li>If the first argument is negative zero and the second argument is a
+ * negative finite odd integer, or the first argument is negative infinity
+ * and the second argument is a positive finite odd integer, then the result
+ * is negative infinity.</li>
+ * <li>If the first argument is less than zero and the second argument is a
+ * finite even integer, then the result is equal to the result of raising
+ * the absolute value of the first argument to the power of the second
+ * argument.</li>
+ * <li>If the first argument is less than zero and the second argument is a
+ * finite odd integer, then the result is equal to the negative of the
+ * result of raising the absolute value of the first argument to the power
+ * of the second argument.</li>
+ * <li>If the first argument is finite and less than zero and the second
+ * argument is finite and not an integer, then the result is NaN.</li>
+ * <li>If both arguments are integers, then the result is exactly equal to
+ * the mathematical result of raising the first argument to the power of
+ * the second argument if that result can in fact be represented exactly as
+ * a double value.</li>
+ *
+ * </ul><p>(In the foregoing descriptions, a floating-point value is
+ * considered to be an integer if and only if it is a fixed point of the
+ * method {@link #ceil(double)} or, equivalently, a fixed point of the
+ * method {@link #floor(double)}. A value is a fixed point of a one-argument
+ * method if and only if the result of applying the method to the value is
+ * equal to the value.) This is accurate within 1 ulp, and is semi-monotonic.
+ *
+ * @param a the number to raise
+ * @param b the power to raise it to
+ * @return a<sup>b</sup>
+ */
+ public static native double pow(double a, double b);
+
+ /**
+ * Get the IEEE 754 floating point remainder on two numbers. This is the
+ * value of <code>x - y * <em>n</em></code>, where <em>n</em> is the closest
+ * double to <code>x / y</code> (ties go to the even n); for a zero
+ * remainder, the sign is that of <code>x</code>. If either argument is NaN,
+ * the first argument is infinite, or the second argument is zero, the result
+ * is NaN; if x is finite but y is infinite, the result is x. This is
+ * accurate within the limits of doubles.
+ *
+ * @param x the dividend (the top half)
+ * @param y the divisor (the bottom half)
+ * @return the IEEE 754-defined floating point remainder of x/y
+ * @see #rint(double)
+ */
+ public static native double IEEEremainder(double x, double y);
+
+ /**
+ * Take the nearest integer that is that is greater than or equal to the
+ * argument. If the argument is NaN, infinite, or zero, the result is the
+ * same; if the argument is between -1 and 0, the result is negative zero.
+ * Note that <code>Math.ceil(x) == -Math.floor(-x)</code>.
+ *
+ * @param a the value to act upon
+ * @return the nearest integer &gt;= <code>a</code>
+ */
+ public static native double ceil(double a);
+
+ /**
+ * Take the nearest integer that is that is less than or equal to the
+ * argument. If the argument is NaN, infinite, or zero, the result is the
+ * same. Note that <code>Math.ceil(x) == -Math.floor(-x)</code>.
+ *
+ * @param a the value to act upon
+ * @return the nearest integer &lt;= <code>a</code>
+ */
+ public static native double floor(double a);
+
+ /**
+ * Take the nearest integer to the argument. If it is exactly between
+ * two integers, the even integer is taken. If the argument is NaN,
+ * infinite, or zero, the result is the same.
+ *
+ * @param a the value to act upon
+ * @return the nearest integer to <code>a</code>
+ */
+ public static native double rint(double a);
+
+ /**
+ * Take the nearest integer to the argument. This is equivalent to
+ * <code>(int) Math.floor(a + 0.5f)</code>. If the argument is NaN, the result
+ * is 0; otherwise if the argument is outside the range of int, the result
+ * will be Integer.MIN_VALUE or Integer.MAX_VALUE, as appropriate.
+ *
+ * @param a the argument to round
+ * @return the nearest integer to the argument
+ * @see Integer#MIN_VALUE
+ * @see Integer#MAX_VALUE
+ */
+ public static int round(float a)
+ {
+ // this check for NaN, from JLS 15.21.1, saves a method call
+ if (a != a)
+ return 0;
+ return (int) floor(a + 0.5f);
+ }
+
+ /**
+ * Take the nearest long to the argument. This is equivalent to
+ * <code>(long) Math.floor(a + 0.5)</code>. If the argument is NaN, the
+ * result is 0; otherwise if the argument is outside the range of long, the
+ * result will be Long.MIN_VALUE or Long.MAX_VALUE, as appropriate.
+ *
+ * @param a the argument to round
+ * @return the nearest long to the argument
+ * @see Long#MIN_VALUE
+ * @see Long#MAX_VALUE
+ */
+ public static long round(double a)
+ {
+ // this check for NaN, from JLS 15.21.1, saves a method call
+ if (a != a)
+ return 0;
+ return (long) floor(a + 0.5d);
+ }
+
+ /**
+ * Get a random number. This behaves like Random.nextDouble(), seeded by
+ * System.currentTimeMillis() when first called. In other words, the number
+ * is from a pseudorandom sequence, and lies in the range [+0.0, 1.0).
+ * This random sequence is only used by this method, and is threadsafe,
+ * although you may want your own random number generator if it is shared
+ * among threads.
+ *
+ * @return a random number
+ * @see Random#nextDouble()
+ * @see System#currentTimeMillis()
+ */
+ public static synchronized double random()
+ {
+ if (rand == null)
+ rand = new Random();
+ return rand.nextDouble();
+ }
+
+ /**
+ * Convert from degrees to radians. The formula for this is
+ * radians = degrees * (pi/180); however it is not always exact given the
+ * limitations of floating point numbers.
+ *
+ * @param degrees an angle in degrees
+ * @return the angle in radians
+ * @since 1.2
+ */
+ public static double toRadians(double degrees)
+ {
+ return (degrees * PI) / 180;
+ }
+
+ /**
+ * Convert from radians to degrees. The formula for this is
+ * degrees = radians * (180/pi); however it is not always exact given the
+ * limitations of floating point numbers.
+ *
+ * @param rads an angle in radians
+ * @return the angle in degrees
+ * @since 1.2
+ */
+ public static double toDegrees(double rads)
+ {
+ return (rads * 180) / PI;
+ }
+
+ /**
+ * <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 native double cbrt(double a);
+
+ /**
+ * <p>
+ * Returns the hyperbolic cosine of the given value. For a value,
+ * <code>x</code>, the hyperbolic cosine is <code>(e<sup>x</sup> +
+ * e<sup>-x</sup>)/2</code>
+ * with <code>e</code> being <a href="#E">Euler's number</a>. The returned
+ * result 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 native double cosh(double a);
+
+ /**
+ * <p>
+ * Returns <code>e<sup>a</sup> - 1. For values close to 0, the
+ * result of <code>expm1(a) + 1</code> tend to be much closer to the
+ * exact result than simply <code>exp(x)</code>. The result 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 native double expm1(double a);
+
+ /**
+ * <p>
+ * Returns the hypotenuse, <code>a<sup>2</sup> + b<sup>2</sup></code>,
+ * without intermediate overflow or underflow. The returned result 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 native double hypot(double a, double 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.
+ * </p>
+ * <p>
+ * Arguments of either <code>NaN</code> or less than zero return
+ * <code>NaN</code>. An argument of positive infinity returns positive
+ * infinity. Negative infinity is returned if either positive or negative
+ * zero is supplied. Where the argument is the result of
+ * <code>10<sup>n</sup</code>, then <code>n</code> is returned.
+ * </p>
+ *
+ * @param a the numeric argument.
+ * @return the base 10 logarithm of <code>a</code>.
+ * @since 1.5
+ */
+ public static native double log10(double a);
+
+ /**
+ * <p>
+ * Returns the natural logarithm resulting from the sum of the argument,
+ * <code>a</code> and 1. For values close to 0, the
+ * result of <code>log1p(a)</code> tend to be much closer to the
+ * exact result than simply <code>log(1.0+a)</code>. The returned
+ * result is within 1 ulp of the exact result, and the results are
+ * semi-monotonic.
+ * </p>
+ * <p>
+ * Arguments of either <code>NaN</code> or less than -1 return
+ * <code>NaN</code>. An argument of positive infinity or zero
+ * returns the original argument. Negative infinity is returned from an
+ * argument of -1.
+ * </p>
+ *
+ * @param a the numeric argument.
+ * @return the natural logarithm of <code>a</code> + 1.
+ * @since 1.5
+ */
+ public static native double log1p(double a);
+
+ /**
+ * <p>
+ * Returns the sign of the argument as follows:
+ * </p>
+ * <ul>
+ * <li>If <code>a</code> is greater than zero, the result is 1.0.</li>
+ * <li>If <code>a</code> is less than zero, the result is -1.0.</li>
+ * <li>If <code>a</code> is <code>NaN</code>, the result is <code>NaN</code>.
+ * <li>If <code>a</code> is positive or negative zero, the result is the
+ * same.</li>
+ * </ul>
+ *
+ * @param a the numeric argument.
+ * @return the sign of the argument.
+ * @since 1.5.
+ */
+ public static double signum(double a)
+ {
+ if (Double.isNaN(a))
+ return Double.NaN;
+ if (a > 0)
+ return 1.0;
+ if (a < 0)
+ return -1.0;
+ return a;
+ }
+
+ /**
+ * <p>
+ * Returns the sign of the argument as follows:
+ * </p>
+ * <ul>
+ * <li>If <code>a</code> is greater than zero, the result is 1.0f.</li>
+ * <li>If <code>a</code> is less than zero, the result is -1.0f.</li>
+ * <li>If <code>a</code> is <code>NaN</code>, the result is <code>NaN</code>.
+ * <li>If <code>a</code> is positive or negative zero, the result is the
+ * same.</li>
+ * </ul>
+ *
+ * @param a the numeric argument.
+ * @return the sign of the argument.
+ * @since 1.5.
+ */
+ public static float signum(float a)
+ {
+ if (Float.isNaN(a))
+ return Float.NaN;
+ if (a > 0)
+ return 1.0f;
+ if (a < 0)
+ 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 native double sinh(double a);
+
+ /**
+ * <p>
+ * Returns the hyperbolic tangent of the given value. For a value,
+ * <code>x</code>, the hyperbolic tangent is <code>(e<sup>x</sup> -
+ * e<sup>-x</sup>)/(e<sup>x</sup> + e<sup>-x</sup>)</code>
+ * (i.e. <code>sinh(a)/cosh(a)</code>)
+ * with <code>e</code> being <a href="#E">Euler's number</a>. The returned
+ * result 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 native double tanh(double 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,
+ * ulp(x) == ulp(-x). If the argument is a NaN, then NaN is returned.
+ * If the argument is an infinity, then +Inf is returned. If the
+ * argument is zero (either positive or negative), then
+ * {@link Double#MIN_VALUE} is returned.
+ * @param d the double whose ulp should be returned
+ * @return the difference between the argument and the next larger double
+ * @since 1.5
+ */
+ public static double ulp(double d)
+ {
+ if (Double.isNaN(d))
+ return d;
+ if (Double.isInfinite(d))
+ return Double.POSITIVE_INFINITY;
+ // This handles both +0.0 and -0.0.
+ if (d == 0.0)
+ return Double.MIN_VALUE;
+ long bits = Double.doubleToLongBits(d);
+ final int mantissaBits = 52;
+ final int exponentBits = 11;
+ final long mantMask = (1L << mantissaBits) - 1;
+ long mantissa = bits & mantMask;
+ final long expMask = (1L << exponentBits) - 1;
+ long exponent = (bits >>> mantissaBits) & expMask;
+
+ // Denormal number, so the answer is easy.
+ if (exponent == 0)
+ {
+ long result = (exponent << mantissaBits) | 1L;
+ return Double.longBitsToDouble(result);
+ }
+
+ // Conceptually we want to have '1' as the mantissa. Then we would
+ // shift the mantissa over to make a normal number. If this underflows
+ // the exponent, we will make a denormal result.
+ long newExponent = exponent - mantissaBits;
+ long newMantissa;
+ if (newExponent > 0)
+ newMantissa = 0;
+ else
+ {
+ newMantissa = 1L << -(newExponent - 1);
+ newExponent = 0;
+ }
+ return Double.longBitsToDouble((newExponent << mantissaBits) | newMantissa);
+ }
+
+ /**
+ * Return the ulp for the given float argument. The ulp is the
+ * difference between the argument and the next larger float. Note
+ * that the sign of the float argument is ignored, that is,
+ * ulp(x) == ulp(-x). If the argument is a NaN, then NaN is returned.
+ * If the argument is an infinity, then +Inf is returned. If the
+ * argument is zero (either positive or negative), then
+ * {@link Float#MIN_VALUE} is returned.
+ * @param f the float whose ulp should be returned
+ * @return the difference between the argument and the next larger float
+ * @since 1.5
+ */
+ public static float ulp(float f)
+ {
+ if (Float.isNaN(f))
+ return f;
+ if (Float.isInfinite(f))
+ return Float.POSITIVE_INFINITY;
+ // This handles both +0.0 and -0.0.
+ if (f == 0.0)
+ return Float.MIN_VALUE;
+ int bits = Float.floatToIntBits(f);
+ final int mantissaBits = 23;
+ final int exponentBits = 8;
+ final int mantMask = (1 << mantissaBits) - 1;
+ int mantissa = bits & mantMask;
+ final int expMask = (1 << exponentBits) - 1;
+ int exponent = (bits >>> mantissaBits) & expMask;
+
+ // Denormal number, so the answer is easy.
+ if (exponent == 0)
+ {
+ int result = (exponent << mantissaBits) | 1;
+ return Float.intBitsToFloat(result);
+ }
+
+ // Conceptually we want to have '1' as the mantissa. Then we would
+ // shift the mantissa over to make a normal number. If this underflows
+ // the exponent, we will make a denormal result.
+ int newExponent = exponent - mantissaBits;
+ int newMantissa;
+ if (newExponent > 0)
+ newMantissa = 0;
+ else
+ {
+ newMantissa = 1 << -(newExponent - 1);
+ newExponent = 0;
+ }
+ return Float.intBitsToFloat((newExponent << mantissaBits) | newMantissa);
+ }
+}
diff --git a/libjava/java/lang/NegativeArraySizeException.h b/libjava/java/lang/NegativeArraySizeException.h
new file mode 100644
index 000000000..e05f7c515
--- /dev/null
+++ b/libjava/java/lang/NegativeArraySizeException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_NegativeArraySizeException__
+#define __java_lang_NegativeArraySizeException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::NegativeArraySizeException : public ::java::lang::RuntimeException
+{
+
+public:
+ NegativeArraySizeException();
+ NegativeArraySizeException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -8960118058596991861LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_NegativeArraySizeException__
diff --git a/libjava/java/lang/NoClassDefFoundError.h b/libjava/java/lang/NoClassDefFoundError.h
new file mode 100644
index 000000000..90790a7b9
--- /dev/null
+++ b/libjava/java/lang/NoClassDefFoundError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_NoClassDefFoundError__
+#define __java_lang_NoClassDefFoundError__
+
+#pragma interface
+
+#include <java/lang/LinkageError.h>
+
+class java::lang::NoClassDefFoundError : public ::java::lang::LinkageError
+{
+
+public:
+ NoClassDefFoundError();
+ NoClassDefFoundError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 9095859863287012458LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_NoClassDefFoundError__
diff --git a/libjava/java/lang/NoSuchFieldError.h b/libjava/java/lang/NoSuchFieldError.h
new file mode 100644
index 000000000..65f444e83
--- /dev/null
+++ b/libjava/java/lang/NoSuchFieldError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_NoSuchFieldError__
+#define __java_lang_NoSuchFieldError__
+
+#pragma interface
+
+#include <java/lang/IncompatibleClassChangeError.h>
+
+class java::lang::NoSuchFieldError : public ::java::lang::IncompatibleClassChangeError
+{
+
+public:
+ NoSuchFieldError();
+ NoSuchFieldError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -3456430195886129035LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_NoSuchFieldError__
diff --git a/libjava/java/lang/NoSuchFieldException.h b/libjava/java/lang/NoSuchFieldException.h
new file mode 100644
index 000000000..36fe841ed
--- /dev/null
+++ b/libjava/java/lang/NoSuchFieldException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_NoSuchFieldException__
+#define __java_lang_NoSuchFieldException__
+
+#pragma interface
+
+#include <java/lang/Exception.h>
+
+class java::lang::NoSuchFieldException : public ::java::lang::Exception
+{
+
+public:
+ NoSuchFieldException();
+ NoSuchFieldException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -6143714805279938260LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_NoSuchFieldException__
diff --git a/libjava/java/lang/NoSuchMethodError.h b/libjava/java/lang/NoSuchMethodError.h
new file mode 100644
index 000000000..5db0a040e
--- /dev/null
+++ b/libjava/java/lang/NoSuchMethodError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_NoSuchMethodError__
+#define __java_lang_NoSuchMethodError__
+
+#pragma interface
+
+#include <java/lang/IncompatibleClassChangeError.h>
+
+class java::lang::NoSuchMethodError : public ::java::lang::IncompatibleClassChangeError
+{
+
+public:
+ NoSuchMethodError();
+ NoSuchMethodError(::java::lang::String *);
+public: // actually package-private
+ static const jlong serialVersionUID = -3765521442372831335LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_NoSuchMethodError__
diff --git a/libjava/java/lang/NoSuchMethodException.h b/libjava/java/lang/NoSuchMethodException.h
new file mode 100644
index 000000000..dc905d67f
--- /dev/null
+++ b/libjava/java/lang/NoSuchMethodException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_NoSuchMethodException__
+#define __java_lang_NoSuchMethodException__
+
+#pragma interface
+
+#include <java/lang/Exception.h>
+
+class java::lang::NoSuchMethodException : public ::java::lang::Exception
+{
+
+public:
+ NoSuchMethodException();
+ NoSuchMethodException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 5034388446362600923LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_NoSuchMethodException__
diff --git a/libjava/java/lang/NullPointerException.h b/libjava/java/lang/NullPointerException.h
new file mode 100644
index 000000000..4af582cf4
--- /dev/null
+++ b/libjava/java/lang/NullPointerException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_NullPointerException__
+#define __java_lang_NullPointerException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::NullPointerException : public ::java::lang::RuntimeException
+{
+
+public:
+ NullPointerException();
+ NullPointerException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 5162710183389028792LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_NullPointerException__
diff --git a/libjava/java/lang/Number.h b/libjava/java/lang/Number.h
new file mode 100644
index 000000000..65ba92019
--- /dev/null
+++ b/libjava/java/lang/Number.h
@@ -0,0 +1,32 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Number__
+#define __java_lang_Number__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::Number : public ::java::lang::Object
+{
+
+public:
+ Number();
+ virtual jint intValue() = 0;
+ virtual jlong longValue() = 0;
+ virtual jfloat floatValue() = 0;
+ virtual jdouble doubleValue() = 0;
+ virtual jbyte byteValue();
+ virtual jshort shortValue();
+private:
+ static const jlong serialVersionUID = -8742448824652078965LL;
+public: // actually package-private
+ static JArray< jchar > * digits;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Number__
diff --git a/libjava/java/lang/NumberFormatException.h b/libjava/java/lang/NumberFormatException.h
new file mode 100644
index 000000000..34bd4d678
--- /dev/null
+++ b/libjava/java/lang/NumberFormatException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_NumberFormatException__
+#define __java_lang_NumberFormatException__
+
+#pragma interface
+
+#include <java/lang/IllegalArgumentException.h>
+
+class java::lang::NumberFormatException : public ::java::lang::IllegalArgumentException
+{
+
+public:
+ NumberFormatException();
+ NumberFormatException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -2848938806368998894LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_NumberFormatException__
diff --git a/libjava/java/lang/Object.h b/libjava/java/lang/Object.h
new file mode 100644
index 000000000..54fd447d1
--- /dev/null
+++ b/libjava/java/lang/Object.h
@@ -0,0 +1,91 @@
+// Object.h - Header file for java.lang.Object. -*- c++ -*-
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2004, 2005 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#ifndef __JAVA_LANG_OBJECT_H__
+#define __JAVA_LANG_OBJECT_H__
+
+#pragma interface
+
+#include <gcj/javaprims.h>
+
+extern "Java"
+{
+// This class is mainly here as a kludge to get G++ to allocate two
+// extra entries in each vtable.
+struct _JvObjectPrefix
+{
+protected:
+ // New ABI Compatibility Dummy, #1 and 2.
+ virtual void nacd_1 (void) {}; // This slot really contains the Class pointer.
+ // For IA64, the GC descriptor goes into the second word of the nacd1 descr.
+# ifndef __ia64__
+ virtual void nacd_2 (void) {}; // Actually the GC bitmap marking descriptor.
+# endif
+};
+}
+
+// Forward declarations for friends of java::lang::Object
+void _Jv_MonitorEnter (jobject obj);
+void _Jv_MonitorExit (jobject obj);
+void _Jv_InitializeSyncMutex (void);
+void _Jv_FinalizeObject (jobject obj);
+bool _Jv_ObjectCheckMonitor (jobject obj);
+
+class java::lang::Object : public _JvObjectPrefix
+{
+protected:
+ virtual void finalize (void);
+public:
+ // Order must match order in Object.java.
+ jclass getClass (void);
+ virtual jint hashCode (void);
+ void notify (void);
+ void notifyAll (void);
+ void wait (jlong timeout, jint nanos);
+ virtual jboolean equals (jobject obj);
+ Object (void);
+ virtual jstring toString (void);
+ void wait (void);
+ void wait (jlong timeout);
+
+ friend void ::_Jv_MonitorEnter (jobject obj);
+ friend void ::_Jv_MonitorExit (jobject obj);
+ friend void ::_Jv_InitializeSyncMutex (void);
+ friend void ::_Jv_FinalizeObject (jobject obj);
+ friend bool ::_Jv_ObjectCheckMonitor (jobject obj);
+
+#ifdef JV_MARKOBJ_DECL
+ friend JV_MARKOBJ_DECL;
+#endif
+#ifdef JV_MARKARRAY_DECL
+ friend JV_MARKARRAY_DECL;
+#endif
+
+ static java::lang::Class class$;
+
+protected:
+ virtual jobject clone (void);
+
+private:
+ // This does not actually refer to a Java object. Instead it is a
+ // placeholder for a piece of internal data (the synchronization
+ // information).
+# ifndef JV_HASH_SYNCHRONIZATION
+ jobject sync_info;
+# endif
+
+ // Initialize the sync_info field. Not called with JV_HASH_SYNCHRONIZATION.
+ void sync_init (void);
+
+public:
+ virtual void throwNoSuchMethodError (void);
+};
+
+#endif /* __JAVA_LANG_OBJECT_H__ */
diff --git a/libjava/java/lang/Object.java b/libjava/java/lang/Object.java
new file mode 100644
index 000000000..740a7c78e
--- /dev/null
+++ b/libjava/java/lang/Object.java
@@ -0,0 +1,519 @@
+/* java.lang.Object - The universal superclass in Java
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2007
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang;
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * plus gcj compiler sources (to determine object layout)
+ * Status: Complete to version 1.1
+ */
+
+/**
+ * Object is the ultimate superclass of every class
+ * (excepting interfaces). When you define a class that
+ * does not extend any other class, it implicitly extends
+ * java.lang.Object. Also, an anonymous class based on
+ * an interface will extend Object.
+ *
+ * <p>It provides general-purpose methods that every single
+ * Object, regardless of race, sex or creed, implements.
+ * All of the public methods may be invoked on arrays or
+ * interfaces. The protected methods <code>clone</code>
+ * and <code>finalize</code> are not accessible on arrays
+ * or interfaces, but all array types have a public version
+ * of <code>clone</code> which is accessible.
+ *
+ * @author John Keiser
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Tom Tromey (tromey@cygnus.com)
+ */
+public class Object
+{
+ /**
+ * Called on an object by the Virtual Machine at most once,
+ * at some point after the Object is determined unreachable
+ * but before it is destroyed. You would think that this
+ * means it eventually is called on every Object, but this is
+ * not necessarily the case. If execution terminates
+ * abnormally, garbage collection does not always happen.
+ * Thus you cannot rely on this method to always work.
+ * For finer control over garbage collection, use references
+ * from the {@link java.lang.ref} package.
+ *
+ * <p>Virtual Machines are free to not call this method if
+ * they can determine that it does nothing important; for
+ * example, if your class extends Object and overrides
+ * finalize to do simply <code>super.finalize()</code>.
+ *
+ * <p>finalize() will be called by a {@link Thread} that has no
+ * locks on any Objects, and may be called concurrently.
+ * There are no guarantees on the order in which multiple
+ * objects are finalized. This means that finalize() is
+ * usually unsuited for performing actions that must be
+ * thread-safe, and that your implementation must be
+ * use defensive programming if it is to always work.
+ *
+ * <p>If an Exception is thrown from finalize() during garbage
+ * collection, it will be patently ignored and the Object will
+ * still be destroyed.
+ *
+ * <p>It is allowed, although not typical, for user code to call
+ * finalize() directly. User invocation does not affect whether
+ * automatic invocation will occur. It is also permitted,
+ * although not recommended, for a finalize() method to "revive"
+ * an object by making it reachable from normal code again.
+ *
+ * <p>Unlike constructors, finalize() does not get called
+ * for an object's superclass unless the implementation
+ * specifically calls <code>super.finalize()</code>.
+ *
+ * <p>The default implementation does nothing.
+ *
+ * @throws Throwable permits a subclass to throw anything in an
+ * overridden version; but the default throws nothing
+ * @see System#gc()
+ * @see System#runFinalizersOnExit(boolean)
+ * @see java.lang.ref
+ */
+ // This must come first. See _JvObjectPrefix in Object.h.
+ protected void finalize () throws Throwable
+ {
+ }
+
+ /**
+ * Returns the runtime {@link Class} of this Object.
+ *
+ * <p>The class object can also be obtained without a runtime
+ * instance by using the class literal, as in:
+ * <code>Foo.class</code>. Notice that the class literal
+ * also works on primitive types, making it useful for
+ * reflection purposes.
+ *
+ * @return the class of this Object
+ */
+ public final native Class<? extends Object> getClass();
+
+ /**
+ * Get a value that represents this Object, as uniquely as
+ * possible within the confines of an int.
+ *
+ * <p>There are some requirements on this method which
+ * subclasses must follow:<br>
+ *
+ * <ul>
+ * <li>Semantic equality implies identical hashcodes. In other
+ * words, if <code>a.equals(b)</code> is true, then
+ * <code>a.hashCode() == b.hashCode()</code> must be as well.
+ * However, the reverse is not necessarily true, and two
+ * objects may have the same hashcode without being equal.</li>
+ * <li>It must be consistent. Whichever value o.hashCode()
+ * returns on the first invocation must be the value
+ * returned on all later invocations as long as the object
+ * exists. Notice, however, that the result of hashCode may
+ * change between separate executions of a Virtual Machine,
+ * because it is not invoked on the same object.</li>
+ * </ul>
+ *
+ * <p>Notice that since <code>hashCode</code> is used in
+ * {@link java.util.Hashtable} and other hashing classes,
+ * a poor implementation will degrade the performance of hashing
+ * (so don't blindly implement it as returning a constant!). Also,
+ * if calculating the hash is time-consuming, a class may consider
+ * caching the results.
+ *
+ * <p>The default implementation returns
+ * <code>System.identityHashCode(this)</code>
+ *
+ * @return the hash code for this Object
+ * @see #equals(Object)
+ * @see System#identityHashCode(Object)
+ */
+ public native int hashCode();
+
+ /**
+ * Wakes up one of the {@link Thread}s that has called
+ * <code>wait</code> on this Object. Only the owner
+ * of a lock on this Object may call this method. This lock
+ * is obtained by a <code>synchronized</code> method or statement.
+ *
+ * <p>The Thread to wake up is chosen arbitrarily. The
+ * awakened thread is not guaranteed to be the next thread
+ * to actually obtain the lock on this object.
+ *
+ * <p>This thread still holds a lock on the object, so it is
+ * typical to release the lock by exiting the synchronized
+ * code, calling wait(), or calling {@link Thread#sleep()}, so
+ * that the newly awakened thread can actually resume. The
+ * awakened thread will most likely be awakened with an
+ * {@link InterruptedException}, but that is not guaranteed.
+ *
+ * @throws IllegalMonitorStateException if this Thread
+ * does not own the lock on the Object
+ * @see #notifyAll()
+ * @see #wait()
+ * @see #wait(long)
+ * @see #wait(long, int)
+ * @see Thread
+ */
+ public final native void notify();
+
+ /**
+ * Wakes up all of the {@link Thread}s that have called
+ * <code>wait</code> on this Object. Only the owner
+ * of a lock on this Object may call this method. This lock
+ * is obtained by a <code>synchronized</code> method or statement.
+ *
+ * <p>There are no guarantees as to which thread will next
+ * obtain the lock on the object.
+ *
+ * <p>This thread still holds a lock on the object, so it is
+ * typical to release the lock by exiting the synchronized
+ * code, calling wait(), or calling {@link Thread#sleep()}, so
+ * that one of the newly awakened threads can actually resume.
+ * The resuming thread will most likely be awakened with an
+ * {@link InterruptedException}, but that is not guaranteed.
+ *
+ * @throws IllegalMonitorStateException if this Thread
+ * does not own the lock on the Object
+ * @see #notify()
+ * @see #wait()
+ * @see #wait(long)
+ * @see #wait(long, int)
+ * @see Thread
+ */
+ public final native void notifyAll();
+
+ /**
+ * Waits a specified amount of time (or indefinitely if
+ * the time specified is 0) for someone to call notify()
+ * or notifyAll() on this Object, waking up this Thread.
+ *
+ * <p>The Thread that calls wait must have a lock on this Object,
+ * obtained by a <code>synchronized</code> method or statement.
+ * After calling wait, the thread loses the lock on this
+ * object until the method completes (abruptly or normally),
+ * at which time it regains the lock. All locks held on
+ * other objects remain in force, even though the thread is
+ * inactive. Therefore, caution must be used to avoid deadlock.
+ *
+ * <p>Usually, this call will complete normally if the time
+ * expires, or abruptly with {@link InterruptedException}
+ * if another thread called notify, but neither result
+ * is guaranteed.
+ *
+ * <p>The waiting period is nowhere near as precise as
+ * nanoseconds; considering that even wait(int) is inaccurate,
+ * how much can you expect? But on supporting
+ * implementations, this offers somewhat more granularity
+ * than milliseconds.
+ *
+ * @param ms the number of milliseconds to wait (1,000
+ * milliseconds = 1 second)
+ * @param ns the number of nanoseconds to wait over and
+ * above ms (1,000,000 nanoseconds = 1 millisecond)
+ * @throws IllegalArgumentException if ms &lt; 0 or ns is not
+ * in the range 0 to 999,999
+ * @throws IllegalMonitorStateException if this Thread
+ * does not own a lock on this Object
+ * @throws InterruptedException if some other Thread
+ * interrupts this Thread
+ * @see #notify()
+ * @see #notifyAll()
+ * @see #wait()
+ * @see #wait(long)
+ * @see Thread
+ */
+ public final native void wait(long timeout, int nanos)
+ throws InterruptedException;
+
+ /**
+ * Determine whether this Object is semantically equal
+ * to another Object.
+ *
+ * <p>There are some fairly strict requirements on this
+ * method which subclasses must follow:<br>
+ * <ul>
+ * <li>It must be transitive. If <code>a.equals(b)</code> and
+ * <code>b.equals(c)</code>, then <code>a.equals(c)</code>
+ * must be true as well.</li>
+ * <li>It must be symmetric. <code>a.equals(b)</code> and
+ * <code>b.equals(a)</code> must have the same value.</li>
+ * <li>It must be reflexive. <code>a.equals(a)</code> must
+ * always be true.</li>
+ * <li>It must be consistent. Whichever value a.equals(b)
+ * returns on the first invocation must be the value
+ * returned on all later invocations.</li>
+ * <li><code>a.equals(null)</code> must be false.</li>
+ * <li>It must be consistent with hashCode(). That is,
+ * <code>a.equals(b)</code> must imply
+ * <code>a.hashCode() == b.hashCode()</code>.
+ * The reverse is not true; two objects that are not
+ * equal may have the same hashcode, but that has
+ * the potential to harm hashing performance.</li>
+ * </ul>
+ *
+ * <p>This is typically overridden to throw a {@link ClassCastException}
+ * if the argument is not comparable to the class performing
+ * the comparison, but that is not a requirement. It is legal
+ * for <code>a.equals(b)</code> to be true even though
+ * <code>a.getClass() != b.getClass()</code>. Also, it
+ * is typical to never cause a {@link NullPointerException}.
+ *
+ * <p>In general, the Collections API ({@link java.util}) use the
+ * <code>equals</code> method rather than the <code>==</code>
+ * operator to compare objects. However, {@link java.util.IdentityHashMap}
+ * is an exception to this rule, for its own good reasons.
+ *
+ * <p>The default implementation returns <code>this == o</code>.
+ *
+ * @param obj the Object to compare to
+ * @return whether this Object is semantically equal to another
+ * @see #hashCode()
+ */
+ public boolean equals(Object obj)
+ {
+ return this == obj;
+ }
+
+ /**
+ * The basic constructor. Object is special, because it has no
+ * superclass, so there is no call to super().
+ *
+ * @throws OutOfMemoryError Technically, this constructor never
+ * throws an OutOfMemoryError, because the memory has
+ * already been allocated by this point. But as all
+ * instance creation expressions eventually trace back
+ * to this constructor, and creating an object allocates
+ * memory, we list that possibility here.
+ */
+ public Object()
+ {
+ }
+
+ /**
+ * Convert this Object to a human-readable String.
+ * There are no limits placed on how long this String
+ * should be or what it should contain. We suggest you
+ * make it as intuitive as possible to be able to place
+ * it into {@link java.io.PrintStream#println() System.out.println()}
+ * and such.
+ *
+ * <p>It is typical, but not required, to ensure that this method
+ * never completes abruptly with a {@link RuntimeException}.
+ *
+ * <p>This method will be called when performing string
+ * concatenation with this object. If the result is
+ * <code>null</code>, string concatenation will instead
+ * use <code>"null"</code>.
+ *
+ * <p>The default implementation returns
+ * <code>getClass().getName() + "@" +
+ * Integer.toHexString(hashCode())</code>.
+ *
+ * @return the String representing this Object, which may be null
+ * @throws OutOfMemoryError The default implementation creates a new
+ * String object, therefore it must allocate memory
+ * @see #getClass()
+ * @see #hashCode()
+ * @see Class#getName()
+ * @see Integer#toHexString(int)
+ */
+ public String toString()
+ {
+ return getClass().getName() + '@' + Integer.toHexString(hashCode());
+ }
+
+ /**
+ * Waits indefinitely for notify() or notifyAll() to be
+ * called on the Object in question. Implementation is
+ * identical to wait(0).
+ *
+ * <p>The Thread that calls wait must have a lock on this Object,
+ * obtained by a <code>synchronized</code> method or statement.
+ * After calling wait, the thread loses the lock on this
+ * object until the method completes (abruptly or normally),
+ * at which time it regains the lock. All locks held on
+ * other objects remain in force, even though the thread is
+ * inactive. Therefore, caution must be used to avoid deadlock.
+ *
+ * <p>While it is typical that this method will complete abruptly
+ * with an {@link InterruptedException}, it is not guaranteed. So,
+ * it is typical to call wait inside an infinite loop:<br>
+ *
+ * <pre>
+ * try
+ * {
+ * while (true)
+ * lock.wait();
+ * }
+ * catch (InterruptedException e)
+ * {
+ * }
+ * </pre>
+ *
+ * @throws IllegalMonitorStateException if this Thread
+ * does not own a lock on this Object
+ * @throws InterruptedException if some other Thread
+ * interrupts this Thread
+ * @see #notify()
+ * @see #notifyAll()
+ * @see #wait(long)
+ * @see #wait(long, int)
+ * @see Thread
+ */
+ public final void wait() throws InterruptedException
+ {
+ wait(0, 0);
+ }
+
+ /**
+ * Waits a specified amount of time (or indefinitely if
+ * the time specified is 0) for someone to call notify()
+ * or notifyAll() on this Object, waking up this Thread.
+ *
+ * <p>The Thread that calls wait must have a lock on this Object,
+ * obtained by a <code>synchronized</code> method or statement.
+ * After calling wait, the thread loses the lock on this
+ * object until the method completes (abruptly or normally),
+ * at which time it regains the lock. All locks held on
+ * other objects remain in force, even though the thread is
+ * inactive. Therefore, caution must be used to avoid deadlock.
+ *
+ * <p>Usually, this call will complete normally if the time
+ * expires, or abruptly with {@link InterruptedException}
+ * if another thread called notify, but neither result
+ * is guaranteed.
+ *
+ * <p>The waiting period is only *roughly* the amount of time
+ * you requested. It cannot be exact because of the overhead
+ * of the call itself. Most Virtual Machiness treat the
+ * argument as a lower limit on the time spent waiting, but
+ * even that is not guaranteed. Besides, some other thread
+ * may hold the lock on the object when the time expires, so
+ * the current thread may still have to wait to reobtain the
+ * lock.
+ *
+ * @param timeout the minimum number of milliseconds to wait (1000
+ * milliseconds = 1 second), or 0 for an indefinite wait
+ * @throws IllegalArgumentException if ms &lt; 0
+ * @throws IllegalMonitorStateException if this Thread
+ * does not own a lock on this Object
+ * @throws InterruptedException if some other Thread
+ * interrupts this Thread
+ * @see #notify()
+ * @see #notifyAll()
+ * @see #wait()
+ * @see #wait(long, int)
+ * @see Thread
+ */
+ public final void wait(long timeout) throws InterruptedException
+ {
+ wait(timeout, 0);
+ }
+
+ /**
+ * This method may be called to create a new copy of the
+ * Object. The typical behavior is as follows:<br>
+ * <ul>
+ * <li><code>o == o.clone()</code> is false</li>
+ * <li><code>o.getClass() == o.clone().getClass()</code>
+ * is true</li>
+ * <li><code>o.equals(o)</code> is true</li>
+ * </ul>
+ *
+ * <p>However, these are not strict requirements, and may
+ * be violated if necessary. Of the three requirements, the
+ * last is the most commonly violated, particularly if the
+ * subclass does not override {@link #equals(Object)}.
+ *
+ * <p>If the Object you call clone() on does not implement
+ * {@link Cloneable} (which is a placeholder interface), then
+ * a CloneNotSupportedException is thrown. Notice that
+ * Object does not implement Cloneable; this method exists
+ * as a convenience for subclasses that do.
+ *
+ * <p>Object's implementation of clone allocates space for the
+ * new Object using the correct class, without calling any
+ * constructors, and then fills in all of the new field values
+ * with the old field values. Thus, it is a shallow copy.
+ * However, subclasses are permitted to make a deep copy.
+ *
+ * <p>All array types implement Cloneable, and override
+ * this method as follows (it should never fail):<br>
+ * <pre>
+ * public Object clone()
+ * {
+ * try
+ * {
+ * super.clone();
+ * }
+ * catch (CloneNotSupportedException e)
+ * {
+ * throw new InternalError(e.getMessage());
+ * }
+ * }
+ * </pre>
+ *
+ * @return a copy of the Object
+ * @throws CloneNotSupportedException If this Object does not
+ * implement Cloneable
+ * @throws OutOfMemoryError Since cloning involves memory allocation,
+ * even though it may bypass constructors, you might run
+ * out of memory
+ * @see Cloneable
+ */
+ protected native Object clone() throws CloneNotSupportedException;
+
+ // This initializes the sync_info member. It is here for
+ // completeness (some day we'll be able to auto-generate Object.h).
+ private final native void sync_init();
+
+ // If we fail to find a method at class loading time we put the
+ // vtable index of this method in its place: any attempt to call
+ // that method will result in an error.
+ void throwNoSuchMethodError()
+ {
+ throw new NoSuchMethodError("in " + getClass());
+ }
+
+ // Note that we don't mention the sync_info field here. If we do,
+ // jc1 will not work correctly.
+}
diff --git a/libjava/java/lang/OutOfMemoryError.h b/libjava/java/lang/OutOfMemoryError.h
new file mode 100644
index 000000000..7fac1f5a0
--- /dev/null
+++ b/libjava/java/lang/OutOfMemoryError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_OutOfMemoryError__
+#define __java_lang_OutOfMemoryError__
+
+#pragma interface
+
+#include <java/lang/VirtualMachineError.h>
+
+class java::lang::OutOfMemoryError : public ::java::lang::VirtualMachineError
+{
+
+public:
+ OutOfMemoryError();
+ OutOfMemoryError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 8228564086184010517LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_OutOfMemoryError__
diff --git a/libjava/java/lang/Override.h b/libjava/java/lang/Override.h
new file mode 100644
index 000000000..e6424ee6a
--- /dev/null
+++ b/libjava/java/lang/Override.h
@@ -0,0 +1,19 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Override__
+#define __java_lang_Override__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Override : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::Class * annotationType() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_Override__
diff --git a/libjava/java/lang/Package.h b/libjava/java/lang/Package.h
new file mode 100644
index 000000000..6d12d9f36
--- /dev/null
+++ b/libjava/java/lang/Package.h
@@ -0,0 +1,62 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Package__
+#define __java_lang_Package__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+extern "Java"
+{
+ namespace java
+ {
+ namespace net
+ {
+ class URL;
+ }
+ }
+}
+
+class java::lang::Package : public ::java::lang::Object
+{
+
+public: // actually package-private
+ Package(::java::lang::String *, ::java::lang::String *, ::java::lang::String *, ::java::lang::String *, ::java::lang::String *, ::java::lang::String *, ::java::lang::String *, ::java::net::URL *);
+ Package(::java::lang::String *, ::java::lang::String *, ::java::lang::String *, ::java::lang::String *, ::java::lang::String *, ::java::lang::String *, ::java::lang::String *, ::java::net::URL *, ::java::lang::ClassLoader *);
+public:
+ virtual ::java::lang::String * getName();
+ virtual ::java::lang::String * getSpecificationTitle();
+ virtual ::java::lang::String * getSpecificationVersion();
+ virtual ::java::lang::String * getSpecificationVendor();
+ virtual ::java::lang::String * getImplementationTitle();
+ virtual ::java::lang::String * getImplementationVersion();
+ virtual ::java::lang::String * getImplementationVendor();
+ virtual jboolean isSealed();
+ virtual jboolean isSealed(::java::net::URL *);
+ virtual jboolean isCompatibleWith(::java::lang::String *);
+ static ::java::lang::Package * getPackage(::java::lang::String *);
+ static JArray< ::java::lang::Package * > * getPackages();
+ virtual jint hashCode();
+ virtual ::java::lang::String * toString();
+ virtual ::java::lang::annotation::Annotation * getAnnotation(::java::lang::Class *);
+ virtual JArray< ::java::lang::annotation::Annotation * > * getAnnotations();
+ virtual JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotations();
+ virtual jboolean isAnnotationPresent(::java::lang::Class *);
+private:
+ ::java::lang::String * __attribute__((aligned(__alignof__( ::java::lang::Object)))) name;
+ ::java::lang::String * implTitle;
+ ::java::lang::String * implVendor;
+ ::java::lang::String * implVersion;
+ ::java::lang::String * specTitle;
+ ::java::lang::String * specVendor;
+ ::java::lang::String * specVersion;
+ ::java::net::URL * sealed;
+ ::java::lang::ClassLoader * loader;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Package__
diff --git a/libjava/java/lang/PosixProcess$EOFInputStream.h b/libjava/java/lang/PosixProcess$EOFInputStream.h
new file mode 100644
index 000000000..bda16533a
--- /dev/null
+++ b/libjava/java/lang/PosixProcess$EOFInputStream.h
@@ -0,0 +1,24 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_PosixProcess$EOFInputStream__
+#define __java_lang_PosixProcess$EOFInputStream__
+
+#pragma interface
+
+#include <java/io/InputStream.h>
+
+class java::lang::PosixProcess$EOFInputStream : public ::java::io::InputStream
+{
+
+public: // actually package-private
+ PosixProcess$EOFInputStream();
+public:
+ virtual jint read();
+public: // actually package-private
+ static ::java::lang::PosixProcess$EOFInputStream * instance;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_PosixProcess$EOFInputStream__
diff --git a/libjava/java/lang/PosixProcess$ProcessManager.h b/libjava/java/lang/PosixProcess$ProcessManager.h
new file mode 100644
index 000000000..4b3b62e13
--- /dev/null
+++ b/libjava/java/lang/PosixProcess$ProcessManager.h
@@ -0,0 +1,45 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_PosixProcess$ProcessManager__
+#define __java_lang_PosixProcess$ProcessManager__
+
+#pragma interface
+
+#include <java/lang/Thread.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ class RawDataManaged;
+ }
+ }
+}
+
+class java::lang::PosixProcess$ProcessManager : public ::java::lang::Thread
+{
+
+public: // actually package-private
+ PosixProcess$ProcessManager();
+ void addToLiveProcesses(::java::lang::PosixProcess *);
+ void startExecuting(::java::lang::PosixProcess *);
+ void waitUntilReady();
+public:
+ void run();
+private:
+ void init();
+ void waitForSignal();
+ jboolean reap(::java::lang::PosixProcess *);
+ void signalReaper();
+ ::java::util::LinkedList * __attribute__((aligned(__alignof__( ::java::lang::Thread)))) queue;
+ ::java::util::LinkedList * liveProcesses;
+ jboolean ready;
+public: // actually package-private
+ static ::gnu::gcj::RawDataManaged * nativeData;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_PosixProcess$ProcessManager__
diff --git a/libjava/java/lang/PosixProcess.h b/libjava/java/lang/PosixProcess.h
new file mode 100644
index 000000000..3254f5224
--- /dev/null
+++ b/libjava/java/lang/PosixProcess.h
@@ -0,0 +1,62 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_PosixProcess__
+#define __java_lang_PosixProcess__
+
+#pragma interface
+
+#include <java/lang/Process.h>
+#include <gcj/array.h>
+
+
+class java::lang::PosixProcess : public ::java::lang::Process
+{
+
+public:
+ void destroy();
+private:
+ void nativeDestroy();
+public:
+ jint exitValue();
+public: // actually package-private
+ void processTerminationCleanup();
+public:
+ ::java::io::InputStream * getErrorStream();
+ ::java::io::InputStream * getInputStream();
+ ::java::io::OutputStream * getOutputStream();
+ jint waitFor();
+public: // actually package-private
+ void spawn(::java::lang::PosixProcess$ProcessManager *);
+private:
+ void nativeSpawn();
+public: // actually package-private
+ PosixProcess(JArray< ::java::lang::String * > *, JArray< ::java::lang::String * > *, ::java::io::File *, jboolean);
+ static ::java::lang::Object * access$0();
+ static void access$1(::java::lang::PosixProcess$ProcessManager *);
+private:
+ JArray< ::java::lang::String * > * __attribute__((aligned(__alignof__( ::java::lang::Process)))) progarray;
+ JArray< ::java::lang::String * > * envp;
+ ::java::io::File * dir;
+ jboolean redirect;
+ ::java::lang::Throwable * exception;
+public: // actually package-private
+ jlong pid;
+ static const jint STATE_WAITING_TO_START = 0;
+ static const jint STATE_RUNNING = 1;
+ static const jint STATE_TERMINATED = 2;
+ jint state;
+ jint status;
+private:
+ ::java::io::InputStream * errorStream;
+ ::java::io::InputStream * inputStream;
+ ::java::io::OutputStream * outputStream;
+ ::java::io::InputStream * returnedErrorStream;
+ ::java::io::InputStream * returnedInputStream;
+ static ::java::lang::Object * queueLock;
+ static ::java::lang::PosixProcess$ProcessManager * processManager;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_PosixProcess__
diff --git a/libjava/java/lang/PosixProcess.java b/libjava/java/lang/PosixProcess.java
new file mode 100644
index 000000000..dd59e7b93
--- /dev/null
+++ b/libjava/java/lang/PosixProcess.java
@@ -0,0 +1,470 @@
+// PosixProcess.java - Subclass of Process for POSIX systems.
+/* Copyright (C) 1998, 1999, 2004, 2006, 2007 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import gnu.gcj.RawDataManaged;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date May 3, 1999
+ * @author David Daney <ddaney@avtrex.com> Rewrote using
+ * ProcessManager
+ */
+final class PosixProcess extends Process
+{
+ static final class ProcessManager extends Thread
+ {
+ /**
+ * A list of {@link PosixProcess PosixProcesses} to be
+ * started. The queueLock object is used as the lock Object
+ * for all process related operations. To avoid dead lock
+ * ensure queueLock is obtained before PosixProcess.
+ */
+ private LinkedList<PosixProcess> queue = new LinkedList<PosixProcess>();
+ private LinkedList<PosixProcess> liveProcesses =
+ new LinkedList<PosixProcess>();
+ private boolean ready = false;
+
+ static RawDataManaged nativeData;
+
+ ProcessManager()
+ {
+ // Use package private Thread constructor to place us in the
+ // root ThreadGroup with no InheritableThreadLocal. If the
+ // InheritableThreadLocals were allowed to initialize, they could
+ // cause a Runtime.exec() to be called causing infinite
+ // recursion.
+ super("ProcessManager", true);
+ // Don't keep the (main) process from exiting on our account.
+ this.setDaemon(true);
+ }
+
+ /**
+ * Add a process to the list of running processes. This must only
+ * be called with the queueLock held.
+ *
+ * @param p The PosixProcess.
+ */
+ void addToLiveProcesses(PosixProcess p)
+ {
+ liveProcesses.add(p);
+ }
+
+ /**
+ * Queue up the PosixProcess and awake the ProcessManager.
+ * The ProcessManager will start the PosixProcess from its
+ * thread so it can be reaped when it terminates.
+ *
+ * @param p The PosixProcess.
+ */
+ void startExecuting(PosixProcess p)
+ {
+ synchronized (queueLock)
+ {
+ queue.add(p);
+ signalReaper(); // If blocked in waitForSignal().
+ queueLock.notifyAll(); // If blocked in wait();
+ }
+ }
+
+ /**
+ * Block until the ProcessManager thread is ready to accept
+ * commands.
+ */
+ void waitUntilReady()
+ {
+ synchronized (this)
+ {
+ try
+ {
+ while (! ready)
+ wait();
+ }
+ catch (InterruptedException ie)
+ {
+ // Ignore.
+ }
+ }
+ }
+
+ /**
+ * Main Process starting/reaping loop.
+ */
+ public void run()
+ {
+ init();
+ // Now ready to accept requests.
+ synchronized (this)
+ {
+ ready = true;
+ this.notifyAll();
+ }
+
+ for (;;)
+ {
+ try
+ {
+ synchronized (queueLock)
+ {
+ Iterator<PosixProcess> processIterator =
+ liveProcesses.iterator();
+ while (processIterator.hasNext())
+ {
+ boolean reaped = reap(processIterator.next());
+ if (reaped)
+ processIterator.remove();
+ }
+ if (liveProcesses.size() == 0 && queue.size() == 0)
+ {
+ // This reaper thread could exit, but we keep it
+ // alive for a while in case someone wants to
+ // start more Processes.
+ try
+ {
+ queueLock.wait(1000L);
+ if (queue.size() == 0)
+ {
+ processManager = null;
+ return; // Timed out.
+ }
+ }
+ catch (InterruptedException ie)
+ {
+ // Ignore and exit the thread.
+ return;
+ }
+ }
+ while (queue.size() > 0)
+ {
+ PosixProcess p = queue.remove(0);
+ p.spawn(this);
+ }
+ }
+
+ // Wait for a SIGCHLD from either an exiting process or
+ // the startExecuting() method. This is done outside of
+ // the synchronized block to allow other threads to
+ // enter and submit more jobs.
+ waitForSignal();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace(System.err);
+ }
+ }
+ }
+
+ /**
+ * Setup native signal handlers and other housekeeping things.
+ */
+ private native void init();
+
+ /**
+ * Block waiting for SIGCHLD.
+ *
+ */
+ private native void waitForSignal();
+
+ /**
+ * Try to reap the specified child without blocking.
+ *
+ * @param p the process to try to reap.
+ *
+ * @return true if the process terminated.
+ *
+ */
+ private native boolean reap(PosixProcess p);
+
+ /**
+ * Send SIGCHLD to the reaper thread.
+ */
+ private native void signalReaper();
+ }
+
+ public void destroy()
+ {
+ // Synchronized on the queueLock. This ensures that the reaper
+ // thread cannot be doing a wait() on the child.
+ // Otherwise there would be a race where the OS could
+ // create a process with the same pid between the wait()
+ // and the update of the state which would cause a kill to
+ // the wrong process.
+ synchronized (queueLock)
+ {
+ synchronized (this)
+ {
+ // If there is no ProcessManager we cannot kill.
+ if (state != STATE_TERMINATED)
+ {
+ if (processManager == null)
+ throw new InternalError();
+ nativeDestroy();
+ }
+ }
+ }
+ }
+
+ private native void nativeDestroy();
+
+ public int exitValue()
+ {
+ synchronized (this)
+ {
+ if (state != STATE_TERMINATED)
+ throw new IllegalThreadStateException("Process has not exited");
+ }
+ return status;
+ }
+
+ /**
+ * Called by native code when process exits.
+ *
+ * Already synchronized (this). Close any streams that we can to
+ * conserve file descriptors.
+ *
+ * The outputStream can be closed as any future writes will
+ * generate an IOException due to EPIPE.
+ *
+ * The inputStream and errorStream can only be closed if the user
+ * has not obtained a reference to them AND they have no bytes
+ * available. Since the process has terminated they will never have
+ * any more data available and can safely be replaced by
+ * EOFInputStreams.
+ */
+ void processTerminationCleanup()
+ {
+ try
+ {
+ outputStream.close();
+ }
+ catch (IOException ioe)
+ {
+ // Ignore.
+ }
+ try
+ {
+ if (returnedErrorStream == null && errorStream.available() == 0)
+ {
+ errorStream.close();
+ errorStream = null;
+ }
+ }
+ catch (IOException ioe)
+ {
+ // Ignore.
+ }
+ try
+ {
+ if (returnedInputStream == null && inputStream.available() == 0)
+ {
+ inputStream.close();
+ inputStream = null;
+ }
+ }
+ catch (IOException ioe)
+ {
+ // Ignore.
+ }
+ }
+
+ public synchronized InputStream getErrorStream()
+ {
+ if (returnedErrorStream != null)
+ return returnedErrorStream;
+
+ if (errorStream == null)
+ returnedErrorStream = EOFInputStream.instance;
+ else
+ returnedErrorStream = errorStream;
+
+ return returnedErrorStream;
+ }
+
+ public synchronized InputStream getInputStream()
+ {
+ if (returnedInputStream != null)
+ return returnedInputStream;
+
+ if (inputStream == null)
+ returnedInputStream = EOFInputStream.instance;
+ else
+ returnedInputStream = inputStream;
+
+ return returnedInputStream;
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return outputStream;
+ }
+
+ public int waitFor() throws InterruptedException
+ {
+ synchronized (this)
+ {
+ while (state != STATE_TERMINATED)
+ wait();
+ }
+ return status;
+ }
+
+ /**
+ * Start this process running. This should only be called by the
+ * ProcessManager with the queueLock held.
+ *
+ * @param pm The ProcessManager that made the call.
+ */
+ void spawn(ProcessManager pm)
+ {
+ synchronized (this)
+ {
+ // Do the fork/exec magic.
+ nativeSpawn();
+ // There is no race with reap() in the pidToProcess map
+ // because this is always called from the same thread
+ // doing the reaping.
+ pm.addToLiveProcesses(this);
+ state = STATE_RUNNING;
+ // Notify anybody waiting on state change.
+ this.notifyAll();
+ }
+ }
+
+ /**
+ * Do the fork and exec.
+ */
+ private native void nativeSpawn();
+
+ PosixProcess(String[] progarray, String[] envp, File dir, boolean redirect)
+ throws IOException
+ {
+ // Check to ensure there is something to run, and avoid
+ // dereferencing null pointers in native code.
+ if (progarray[0] == null)
+ throw new NullPointerException();
+
+ this.progarray = progarray;
+ this.envp = envp;
+ this.dir = dir;
+ this.redirect = redirect;
+
+ // Start a ProcessManager if there is not one already running.
+ synchronized (queueLock)
+ {
+ if (processManager == null)
+ {
+ processManager = new ProcessManager();
+ processManager.start();
+ processManager.waitUntilReady();
+ }
+
+ // Queue this PosixProcess for starting by the ProcessManager.
+ processManager.startExecuting(this);
+ }
+
+ // Wait until ProcessManager has started us.
+ synchronized (this)
+ {
+ while (state == STATE_WAITING_TO_START)
+ {
+ try
+ {
+ wait();
+ }
+ catch (InterruptedException ie)
+ {
+ // FIXME: What to do when interrupted while blocking in a constructor?
+ // Ignore.
+ }
+ }
+ }
+
+ // If there was a problem, re-throw it.
+ if (exception != null)
+ {
+ if (exception instanceof IOException)
+ {
+ IOException ioe = new IOException(exception.toString());
+ ioe.initCause(exception);
+ throw ioe;
+ }
+
+ // Not an IOException. Something bad happened.
+ InternalError ie = new InternalError(exception.toString());
+ ie.initCause(exception);
+ throw ie;
+ }
+
+ // If we get here, all is well, the Process has started.
+ }
+
+ private String[] progarray;
+ private String[] envp;
+ private File dir;
+ private boolean redirect;
+
+ /** Set by the ProcessManager on problems starting. */
+ private Throwable exception;
+
+ /** The process id. This is cast to a pid_t on the native side. */
+ long pid;
+
+ // FIXME: Why doesn't the friend declaration in PosixProcess.h
+ // allow PosixProcess$ProcessManager native code access these
+ // when they are private?
+
+ /** Before the process is forked. */
+ static final int STATE_WAITING_TO_START = 0;
+
+ /** After the fork. */
+ static final int STATE_RUNNING = 1;
+
+ /** After exit code has been collected. */
+ static final int STATE_TERMINATED = 2;
+
+ /** One of STATE_WAITING_TO_START, STATE_RUNNING, STATE_TERMINATED. */
+ int state;
+
+ /** The exit status, if the child has exited. */
+ int status;
+
+ /** The streams. */
+ private InputStream errorStream;
+ private InputStream inputStream;
+ private OutputStream outputStream;
+
+ /** InputStreams obtained by the user. Not null indicates that the
+ * user has obtained the stream.
+ */
+ private InputStream returnedErrorStream;
+ private InputStream returnedInputStream;
+
+ /**
+ * Lock Object for all processManager related locking.
+ */
+ private static Object queueLock = new Object();
+ private static ProcessManager processManager;
+
+ static class EOFInputStream extends InputStream
+ {
+ static EOFInputStream instance = new EOFInputStream();
+ public int read()
+ {
+ return -1;
+ }
+ }
+}
diff --git a/libjava/java/lang/Process.h b/libjava/java/lang/Process.h
new file mode 100644
index 000000000..f363feb50
--- /dev/null
+++ b/libjava/java/lang/Process.h
@@ -0,0 +1,25 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Process__
+#define __java_lang_Process__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Process : public ::java::lang::Object
+{
+
+public:
+ Process();
+ virtual ::java::io::OutputStream * getOutputStream() = 0;
+ virtual ::java::io::InputStream * getInputStream() = 0;
+ virtual ::java::io::InputStream * getErrorStream() = 0;
+ virtual jint waitFor() = 0;
+ virtual jint exitValue() = 0;
+ virtual void destroy() = 0;
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Process__
diff --git a/libjava/java/lang/ProcessBuilder.h b/libjava/java/lang/ProcessBuilder.h
new file mode 100644
index 000000000..fd6029df0
--- /dev/null
+++ b/libjava/java/lang/ProcessBuilder.h
@@ -0,0 +1,37 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ProcessBuilder__
+#define __java_lang_ProcessBuilder__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::ProcessBuilder : public ::java::lang::Object
+{
+
+public:
+ ProcessBuilder(::java::util::List *);
+ ProcessBuilder(JArray< ::java::lang::String * > *);
+ ::java::util::List * command();
+ ::java::lang::ProcessBuilder * command(::java::util::List *);
+ ::java::lang::ProcessBuilder * command(JArray< ::java::lang::String * > *);
+ ::java::io::File * directory();
+ ::java::lang::ProcessBuilder * directory(::java::io::File *);
+ ::java::util::Map * environment();
+ jboolean redirectErrorStream();
+ ::java::lang::ProcessBuilder * redirectErrorStream(jboolean);
+ ::java::lang::Process * start();
+private:
+ ::java::io::File * __attribute__((aligned(__alignof__( ::java::lang::Object)))) directory__;
+ ::java::util::List * command__;
+ ::java::util::Map * environment__;
+ jboolean redirect;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ProcessBuilder__
diff --git a/libjava/java/lang/Readable.h b/libjava/java/lang/Readable.h
new file mode 100644
index 000000000..d8e7d2185
--- /dev/null
+++ b/libjava/java/lang/Readable.h
@@ -0,0 +1,29 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Readable__
+#define __java_lang_Readable__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+extern "Java"
+{
+ namespace java
+ {
+ namespace nio
+ {
+ class CharBuffer;
+ }
+ }
+}
+
+class java::lang::Readable : public ::java::lang::Object
+{
+
+public:
+ virtual jint read(::java::nio::CharBuffer *) = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_Readable__
diff --git a/libjava/java/lang/Runnable.h b/libjava/java/lang/Runnable.h
new file mode 100644
index 000000000..ba5985cbf
--- /dev/null
+++ b/libjava/java/lang/Runnable.h
@@ -0,0 +1,19 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Runnable__
+#define __java_lang_Runnable__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Runnable : public ::java::lang::Object
+{
+
+public:
+ virtual void run() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_Runnable__
diff --git a/libjava/java/lang/Runtime.h b/libjava/java/lang/Runtime.h
new file mode 100644
index 000000000..4679cc0b1
--- /dev/null
+++ b/libjava/java/lang/Runtime.h
@@ -0,0 +1,69 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Runtime__
+#define __java_lang_Runtime__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::Runtime : public ::java::lang::Object
+{
+
+ Runtime();
+public:
+ static ::java::lang::Runtime * getRuntime();
+ virtual void exit(jint);
+public: // actually package-private
+ static void exitNoChecksAccessor(jint);
+private:
+ void exitNoChecks(jint);
+public: // actually package-private
+ virtual jboolean runShutdownHooks();
+public:
+ virtual void addShutdownHook(::java::lang::Thread *);
+ virtual jboolean removeShutdownHook(::java::lang::Thread *);
+ virtual void halt(jint);
+ static void runFinalizersOnExit(jboolean);
+ virtual ::java::lang::Process * exec(::java::lang::String *);
+ virtual ::java::lang::Process * exec(::java::lang::String *, JArray< ::java::lang::String * > *);
+ virtual ::java::lang::Process * exec(::java::lang::String *, JArray< ::java::lang::String * > *, ::java::io::File *);
+ virtual ::java::lang::Process * exec(JArray< ::java::lang::String * > *);
+ virtual ::java::lang::Process * exec(JArray< ::java::lang::String * > *, JArray< ::java::lang::String * > *);
+ virtual ::java::lang::Process * exec(JArray< ::java::lang::String * > *, JArray< ::java::lang::String * > *, ::java::io::File *);
+ virtual jint availableProcessors();
+ virtual jlong freeMemory();
+ virtual jlong totalMemory();
+ virtual jlong maxMemory();
+ virtual void gc();
+ virtual void runFinalization();
+ virtual void traceInstructions(jboolean);
+ virtual void traceMethodCalls(jboolean);
+ virtual void load(::java::lang::String *);
+ virtual void loadLibrary(::java::lang::String *);
+ virtual ::java::io::InputStream * getLocalizedInputStream(::java::io::InputStream *);
+ virtual ::java::io::OutputStream * getLocalizedOutputStream(::java::io::OutputStream *);
+public: // actually package-private
+ virtual void exitInternal(jint);
+ virtual void _load(::java::lang::String *, jboolean);
+ virtual jboolean loadLibraryInternal(::java::lang::String *);
+private:
+ static void init();
+ void runFinalizationForExit();
+public: // actually package-private
+ static ::java::lang::String * nativeGetLibname(::java::lang::String *, ::java::lang::String *);
+ virtual ::java::lang::Process * execInternal(JArray< ::java::lang::String * > *, JArray< ::java::lang::String * > *, ::java::io::File *);
+private:
+ JArray< ::java::lang::String * > * __attribute__((aligned(__alignof__( ::java::lang::Object)))) libpath;
+ ::java::lang::Thread * exitSequence;
+ ::java::util::Set * shutdownHooks;
+ jboolean finalizeOnExit;
+ static ::java::lang::Runtime * current;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Runtime__
diff --git a/libjava/java/lang/Runtime.java b/libjava/java/lang/Runtime.java
new file mode 100644
index 000000000..3466f19f2
--- /dev/null
+++ b/libjava/java/lang/Runtime.java
@@ -0,0 +1,747 @@
+/* Runtime.java -- access to the VM process
+ Copyright (C) 1998, 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.classpath.SystemProperties;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * Runtime represents the Virtual Machine.
+ *
+ * @author John Keiser
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Jeroen Frijters
+ */
+// No idea why this class isn't final, since you can't build a subclass!
+public class Runtime
+{
+ /**
+ * The library path, to search when loading libraries. We can also safely use
+ * this as a lock for synchronization.
+ */
+ private final String[] libpath;
+
+ static
+ {
+ init();
+ }
+
+ /**
+ * The thread that started the exit sequence. Access to this field must
+ * be thread-safe; lock on libpath to avoid deadlock with user code.
+ * <code>runFinalization()</code> may want to look at this to see if ALL
+ * finalizers should be run, because the virtual machine is about to halt.
+ */
+ private Thread exitSequence;
+
+ /**
+ * All shutdown hooks. This is initialized lazily, and set to null once all
+ * shutdown hooks have run. Access to this field must be thread-safe; lock
+ * on libpath to avoid deadlock with user code.
+ */
+ private Set shutdownHooks;
+
+ /** True if we should finalize on exit. */
+ private boolean finalizeOnExit;
+
+ /**
+ * The one and only runtime instance.
+ */
+ private static final Runtime current = new Runtime();
+
+ /**
+ * Not instantiable by a user, this should only create one instance.
+ */
+ private Runtime()
+ {
+ if (current != null)
+ throw new InternalError("Attempt to recreate Runtime");
+
+ // We don't use libpath in the libgcj implementation. We still
+ // set it to something to allow the various synchronizations to
+ // work.
+ libpath = new String[0];
+ }
+
+ /**
+ * Get the current Runtime object for this JVM. This is necessary to access
+ * the many instance methods of this class.
+ *
+ * @return the current Runtime object
+ */
+ public static Runtime getRuntime()
+ {
+ return current;
+ }
+
+ /**
+ * Exit the Java runtime. This method will either throw a SecurityException
+ * or it will never return. The status code is returned to the system; often
+ * a non-zero status code indicates an abnormal exit. Of course, there is a
+ * security check, <code>checkExit(status)</code>.
+ *
+ * <p>First, all shutdown hooks are run, in unspecified order, and
+ * concurrently. Next, if finalization on exit has been enabled, all pending
+ * finalizers are run. Finally, the system calls <code>halt</code>.</p>
+ *
+ * <p>If this is run a second time after shutdown has already started, there
+ * are two actions. If shutdown hooks are still executing, it blocks
+ * indefinitely. Otherwise, if the status is nonzero it halts immediately;
+ * if it is zero, it blocks indefinitely. This is typically called by
+ * <code>System.exit</code>.</p>
+ *
+ * @param status the status to exit with
+ * @throws SecurityException if permission is denied
+ * @see #addShutdownHook(Thread)
+ * @see #runFinalizersOnExit(boolean)
+ * @see #runFinalization()
+ * @see #halt(int)
+ */
+ public void exit(int status)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkExit(status);
+ exitNoChecks(status);
+ }
+
+ // Accessor to avoid adding a vtable slot.
+ static void exitNoChecksAccessor(int status)
+ {
+ current.exitNoChecks(status);
+ }
+
+ // Private since we can't add a vtable slot in 4.1.x.
+ private void exitNoChecks(int status)
+ {
+ if (runShutdownHooks())
+ exitInternal(status);
+
+ // Someone else already called runShutdownHooks().
+ // Make sure we are not/no longer in the shutdownHooks set.
+ // And wait till the thread that is calling runShutdownHooks() finishes.
+ synchronized (libpath)
+ {
+ if (shutdownHooks != null)
+ {
+ shutdownHooks.remove(Thread.currentThread());
+ // Interrupt the exit sequence thread, in case it was waiting
+ // inside a join on our thread.
+ exitSequence.interrupt();
+ // Shutdown hooks are still running, so we clear status to
+ // make sure we don't halt.
+ status = 0;
+ }
+ }
+
+ // If exit() is called again after the shutdown hooks have run, but
+ // while finalization for exit is going on and the status is non-zero
+ // we halt immediately.
+ if (status != 0)
+ exitInternal(status);
+
+ while (true)
+ try
+ {
+ exitSequence.join();
+ }
+ catch (InterruptedException e)
+ {
+ // Ignore, we've suspended indefinitely to let all shutdown
+ // hooks complete, and to let any non-zero exits through, because
+ // this is a duplicate call to exit(0).
+ }
+ }
+
+ /**
+ * On first invocation, run all the shutdown hooks and return true.
+ * Any subsequent invocations will simply return false.
+ * Note that it is package accessible so that VMRuntime can call it
+ * when VM exit is not triggered by a call to Runtime.exit().
+ *
+ * @return was the current thread the first one to call this method?
+ */
+ boolean runShutdownHooks()
+ {
+ boolean first = false;
+ synchronized (libpath) // Synch on libpath, not this, to avoid deadlock.
+ {
+ if (exitSequence == null)
+ {
+ first = true;
+ exitSequence = Thread.currentThread();
+ if (shutdownHooks != null)
+ {
+ Iterator i = shutdownHooks.iterator();
+ while (i.hasNext()) // Start all shutdown hooks.
+ try
+ {
+ ((Thread) i.next()).start();
+ }
+ catch (IllegalThreadStateException e)
+ {
+ i.remove();
+ }
+ }
+ }
+ }
+ if (first)
+ {
+ if (shutdownHooks != null)
+ {
+ // Check progress of all shutdown hooks. As a hook completes,
+ // remove it from the set. If a hook calls exit, it removes
+ // itself from the set, then waits indefinitely on the
+ // exitSequence thread. Once the set is empty, set it to null to
+ // signal all finalizer threads that halt may be called.
+ while (true)
+ {
+ Thread[] hooks;
+ synchronized (libpath)
+ {
+ hooks = new Thread[shutdownHooks.size()];
+ shutdownHooks.toArray(hooks);
+ }
+ if (hooks.length == 0)
+ break;
+ for (int i = 0; i < hooks.length; i++)
+ {
+ try
+ {
+ synchronized (libpath)
+ {
+ if (!shutdownHooks.contains(hooks[i]))
+ continue;
+ }
+ hooks[i].join();
+ synchronized (libpath)
+ {
+ shutdownHooks.remove(hooks[i]);
+ }
+ }
+ catch (InterruptedException x)
+ {
+ // continue waiting on the next thread
+ }
+ }
+ }
+ synchronized (libpath)
+ {
+ shutdownHooks = null;
+ }
+ }
+ // Run finalization on all finalizable objects (even if they are
+ // still reachable).
+ runFinalizationForExit();
+ }
+ return first;
+ }
+
+ /**
+ * Register a new shutdown hook. This is invoked when the program exits
+ * normally (because all non-daemon threads ended, or because
+ * <code>System.exit</code> was invoked), or when the user terminates
+ * the virtual machine (such as by typing ^C, or logging off). There is
+ * a security check to add hooks,
+ * <code>RuntimePermission("shutdownHooks")</code>.
+ *
+ * <p>The hook must be an initialized, but unstarted Thread. The threads
+ * are run concurrently, and started in an arbitrary order; and user
+ * threads or daemons may still be running. Once shutdown hooks have
+ * started, they must all complete, or else you must use <code>halt</code>,
+ * to actually finish the shutdown sequence. Attempts to modify hooks
+ * after shutdown has started result in IllegalStateExceptions.</p>
+ *
+ * <p>It is imperative that you code shutdown hooks defensively, as you
+ * do not want to deadlock, and have no idea what other hooks will be
+ * running concurrently. It is also a good idea to finish quickly, as the
+ * virtual machine really wants to shut down!</p>
+ *
+ * <p>There are no guarantees that such hooks will run, as there are ways
+ * to forcibly kill a process. But in such a drastic case, shutdown hooks
+ * would do little for you in the first place.</p>
+ *
+ * @param hook an initialized, unstarted Thread
+ * @throws IllegalArgumentException if the hook is already registered or run
+ * @throws IllegalStateException if the virtual machine is already in
+ * the shutdown sequence
+ * @throws SecurityException if permission is denied
+ * @since 1.3
+ * @see #removeShutdownHook(Thread)
+ * @see #exit(int)
+ * @see #halt(int)
+ */
+ public void addShutdownHook(Thread hook)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("shutdownHooks"));
+ if (hook.isAlive() || hook.getThreadGroup() == null)
+ throw new IllegalArgumentException("The hook thread " + hook + " must not have been already run or started");
+ synchronized (libpath)
+ {
+ if (exitSequence != null)
+ throw new IllegalStateException("The Virtual Machine is exiting. It is not possible anymore to add any hooks");
+ if (shutdownHooks == null)
+ shutdownHooks = new HashSet(); // Lazy initialization.
+ if (! shutdownHooks.add(hook))
+ throw new IllegalArgumentException(hook.toString() + " had already been inserted");
+ }
+ }
+
+ /**
+ * De-register a shutdown hook. As when you registered it, there is a
+ * security check to remove hooks,
+ * <code>RuntimePermission("shutdownHooks")</code>.
+ *
+ * @param hook the hook to remove
+ * @return true if the hook was successfully removed, false if it was not
+ * registered in the first place
+ * @throws IllegalStateException if the virtual machine is already in
+ * the shutdown sequence
+ * @throws SecurityException if permission is denied
+ * @since 1.3
+ * @see #addShutdownHook(Thread)
+ * @see #exit(int)
+ * @see #halt(int)
+ */
+ public boolean removeShutdownHook(Thread hook)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("shutdownHooks"));
+ synchronized (libpath)
+ {
+ if (exitSequence != null)
+ throw new IllegalStateException();
+ if (shutdownHooks != null)
+ return shutdownHooks.remove(hook);
+ }
+ return false;
+ }
+
+ /**
+ * Forcibly terminate the virtual machine. This call never returns. It is
+ * much more severe than <code>exit</code>, as it bypasses all shutdown
+ * hooks and initializers. Use caution in calling this! Of course, there is
+ * a security check, <code>checkExit(status)</code>.
+ *
+ * @param status the status to exit with
+ * @throws SecurityException if permission is denied
+ * @since 1.3
+ * @see #exit(int)
+ * @see #addShutdownHook(Thread)
+ */
+ public void halt(int status)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkExit(status);
+ exitInternal(status);
+ }
+
+ /**
+ * Tell the VM to run the finalize() method on every single Object before
+ * it exits. Note that the JVM may still exit abnormally and not perform
+ * this, so you still don't have a guarantee. And besides that, this is
+ * inherently unsafe in multi-threaded code, as it may result in deadlock
+ * as multiple threads compete to manipulate objects. This value defaults to
+ * <code>false</code>. There is a security check, <code>checkExit(0)</code>.
+ *
+ * @param finalizeOnExit whether to finalize all Objects on exit
+ * @throws SecurityException if permission is denied
+ * @see #exit(int)
+ * @see #gc()
+ * @since 1.1
+ * @deprecated never rely on finalizers to do a clean, thread-safe,
+ * mop-up from your code
+ */
+ public static void runFinalizersOnExit(boolean finalizeOnExit)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkExit(0);
+ current.finalizeOnExit = finalizeOnExit;
+ }
+
+ /**
+ * Create a new subprocess with the specified command line. Calls
+ * <code>exec(cmdline, null, null)</code>. A security check is performed,
+ * <code>checkExec</code>.
+ *
+ * @param cmdline the command to call
+ * @return the Process object
+ * @throws SecurityException if permission is denied
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if cmdline is null
+ * @throws IndexOutOfBoundsException if cmdline is ""
+ */
+ public Process exec(String cmdline) throws IOException
+ {
+ return exec(cmdline, null, null);
+ }
+
+ /**
+ * Create a new subprocess with the specified command line and environment.
+ * If the environment is null, the process inherits the environment of
+ * this process. Calls <code>exec(cmdline, env, null)</code>. A security
+ * check is performed, <code>checkExec</code>.
+ *
+ * @param cmdline the command to call
+ * @param env the environment to use, in the format name=value
+ * @return the Process object
+ * @throws SecurityException if permission is denied
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if cmdline is null, or env has null entries
+ * @throws IndexOutOfBoundsException if cmdline is ""
+ */
+ public Process exec(String cmdline, String[] env) throws IOException
+ {
+ return exec(cmdline, env, null);
+ }
+
+ /**
+ * Create a new subprocess with the specified command line, environment, and
+ * working directory. If the environment is null, the process inherits the
+ * environment of this process. If the directory is null, the process uses
+ * the current working directory. This splits cmdline into an array, using
+ * the default StringTokenizer, then calls
+ * <code>exec(cmdArray, env, dir)</code>. A security check is performed,
+ * <code>checkExec</code>.
+ *
+ * @param cmdline the command to call
+ * @param env the environment to use, in the format name=value
+ * @param dir the working directory to use
+ * @return the Process object
+ * @throws SecurityException if permission is denied
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if cmdline is null, or env has null entries
+ * @throws IndexOutOfBoundsException if cmdline is ""
+ * @since 1.3
+ */
+ public Process exec(String cmdline, String[] env, File dir)
+ throws IOException
+ {
+ StringTokenizer t = new StringTokenizer(cmdline);
+ String[] cmd = new String[t.countTokens()];
+ for (int i = 0; i < cmd.length; i++)
+ cmd[i] = t.nextToken();
+ return exec(cmd, env, dir);
+ }
+
+ /**
+ * Create a new subprocess with the specified command line, already
+ * tokenized. Calls <code>exec(cmd, null, null)</code>. A security check
+ * is performed, <code>checkExec</code>.
+ *
+ * @param cmd the command to call
+ * @return the Process object
+ * @throws SecurityException if permission is denied
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if cmd is null, or has null entries
+ * @throws IndexOutOfBoundsException if cmd is length 0
+ */
+ public Process exec(String[] cmd) throws IOException
+ {
+ return exec(cmd, null, null);
+ }
+
+ /**
+ * Create a new subprocess with the specified command line, already
+ * tokenized, and specified environment. If the environment is null, the
+ * process inherits the environment of this process. Calls
+ * <code>exec(cmd, env, null)</code>. A security check is performed,
+ * <code>checkExec</code>.
+ *
+ * @param cmd the command to call
+ * @param env the environment to use, in the format name=value
+ * @return the Process object
+ * @throws SecurityException if permission is denied
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if cmd is null, or cmd or env has null
+ * entries
+ * @throws IndexOutOfBoundsException if cmd is length 0
+ */
+ public Process exec(String[] cmd, String[] env) throws IOException
+ {
+ return exec(cmd, env, null);
+ }
+
+ /**
+ * Create a new subprocess with the specified command line, already
+ * tokenized, and the specified environment and working directory. If the
+ * environment is null, the process inherits the environment of this
+ * process. If the directory is null, the process uses the current working
+ * directory. A security check is performed, <code>checkExec</code>.
+ *
+ * @param cmd the command to call
+ * @param env the environment to use, in the format name=value
+ * @param dir the working directory to use
+ * @return the Process object
+ * @throws SecurityException if permission is denied
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if cmd is null, or cmd or env has null
+ * entries
+ * @throws IndexOutOfBoundsException if cmd is length 0
+ * @since 1.3
+ */
+ public Process exec(String[] cmd, String[] env, File dir)
+ throws IOException
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkExec(cmd[0]);
+ return execInternal(cmd, env, dir);
+ }
+
+ /**
+ * Returns the number of available processors currently available to the
+ * virtual machine. This number may change over time; so a multi-processor
+ * program want to poll this to determine maximal resource usage.
+ *
+ * @return the number of processors available, at least 1
+ */
+ public native int availableProcessors();
+
+ /**
+ * Find out how much memory is still free for allocating Objects on the heap.
+ *
+ * @return the number of bytes of free memory for more Objects
+ */
+ public native long freeMemory();
+
+ /**
+ * Find out how much memory total is available on the heap for allocating
+ * Objects.
+ *
+ * @return the total number of bytes of memory for Objects
+ */
+ public native long totalMemory();
+
+ /**
+ * Returns the maximum amount of memory the virtual machine can attempt to
+ * use. This may be <code>Long.MAX_VALUE</code> if there is no inherent
+ * limit (or if you really do have a 8 exabyte memory!).
+ *
+ * @return the maximum number of bytes the virtual machine will attempt
+ * to allocate
+ */
+ public native long maxMemory();
+
+ /**
+ * Run the garbage collector. This method is more of a suggestion than
+ * anything. All this method guarantees is that the garbage collector will
+ * have "done its best" by the time it returns. Notice that garbage
+ * collection takes place even without calling this method.
+ */
+ public native void gc();
+
+ /**
+ * Run finalization on all Objects that are waiting to be finalized. Again,
+ * a suggestion, though a stronger one than {@link #gc()}. This calls the
+ * <code>finalize</code> method of all objects waiting to be collected.
+ *
+ * @see #finalize()
+ */
+ public native void runFinalization();
+
+ /**
+ * Tell the VM to trace every bytecode instruction that executes (print out
+ * a trace of it). No guarantees are made as to where it will be printed,
+ * and the VM is allowed to ignore this request.
+ *
+ * @param on whether to turn instruction tracing on
+ */
+ public native void traceInstructions(boolean on);
+
+ /**
+ * Tell the VM to trace every method call that executes (print out a trace
+ * of it). No guarantees are made as to where it will be printed, and the
+ * VM is allowed to ignore this request.
+ *
+ * @param on whether to turn method tracing on
+ */
+ public native void traceMethodCalls(boolean on);
+
+ /**
+ * Load a native library using the system-dependent filename. This is similar
+ * to loadLibrary, except the only name mangling done is inserting "_g"
+ * before the final ".so" if the VM was invoked by the name "java_g". There
+ * may be a security check, of <code>checkLink</code>.
+ *
+ * @param filename the file to load
+ * @throws SecurityException if permission is denied
+ * @throws UnsatisfiedLinkError if the library is not found
+ */
+ public void load(String filename)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkLink(filename);
+ _load(filename, false);
+ }
+
+ /**
+ * Load a native library using a system-independent "short name" for the
+ * library. It will be transformed to a correct filename in a
+ * system-dependent manner (for example, in Windows, "mylib" will be turned
+ * into "mylib.dll"). This is done as follows: if the context that called
+ * load has a ClassLoader cl, then <code>cl.findLibrary(libpath)</code> is
+ * used to convert the name. If that result was null, or there was no class
+ * loader, this searches each directory of the system property
+ * <code>java.library.path</code> for a file named
+ * <code>System.mapLibraryName(libname)</code>. There may be a security
+ * check, of <code>checkLink</code>.
+ *
+ * @param libname the library to load
+ *
+ * @throws SecurityException if permission is denied
+ * @throws UnsatisfiedLinkError if the library is not found
+ *
+ * @see System#mapLibraryName(String)
+ * @see ClassLoader#findLibrary(String)
+ */
+ public void loadLibrary(String libname)
+ {
+ // This is different from the Classpath implementation, but I
+ // believe it is more correct.
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkLink(libname);
+ _load(libname, true);
+ }
+
+ /**
+ * Return a localized version of this InputStream, meaning all characters
+ * are localized before they come out the other end.
+ *
+ * @param in the stream to localize
+ * @return the localized stream
+ * @deprecated <code>InputStreamReader</code> is the preferred way to read
+ * local encodings
+ */
+ public InputStream getLocalizedInputStream(InputStream in)
+ {
+ return in;
+ }
+
+ /**
+ * Return a localized version of this OutputStream, meaning all characters
+ * are localized before they are sent to the other end.
+ *
+ * @param out the stream to localize
+ * @return the localized stream
+ * @deprecated <code>OutputStreamWriter</code> is the preferred way to write
+ * local encodings
+ */
+ public OutputStream getLocalizedOutputStream(OutputStream out)
+ {
+ return out;
+ }
+
+ /**
+ * Native method that actually shuts down the virtual machine.
+ *
+ * @param status the status to end the process with
+ */
+ native void exitInternal(int status);
+
+ /**
+ * Load a file. If it has already been loaded, do nothing. The name has
+ * already been mapped to a true filename.
+ *
+ * @param filename the file to load
+ * @param do_search True if we should search the load path for the file
+ */
+ native void _load(String filename, boolean do_search);
+
+ /**
+ *This is a helper function for the ClassLoader which can load
+ * compiled libraries. Returns true if library (which is just the
+ * base name -- path searching is done by this function) was loaded,
+ * false otherwise.
+ */
+ native boolean loadLibraryInternal(String libname);
+
+ /**
+ * A helper for Runtime static initializer which does some internal native
+ * initialization.
+ */
+ private static native void init ();
+
+ /**
+ * Run finalizers when exiting.
+ */
+ private native void runFinalizationForExit();
+
+ /**
+ * Map a system-independent "short name" to the full file name, and append
+ * it to the path.
+ * XXX This method is being replaced by System.mapLibraryName.
+ *
+ * @param pathname the path
+ * @param libname the short version of the library name
+ * @return the full filename
+ */
+ static native String nativeGetLibname(String pathname, String libname);
+
+ /**
+ * Execute a process. The command line has already been tokenized, and
+ * the environment should contain name=value mappings. If directory is null,
+ * use the current working directory; otherwise start the process in that
+ * directory.
+ *
+ * @param cmd the non-null command tokens
+ * @param env the non-null environment setup
+ * @param dir the directory to use, may be null
+ * @return the newly created process
+ * @throws NullPointerException if cmd or env have null elements
+ * @throws IOException if the exec fails
+ */
+ native Process execInternal(String[] cmd, String[] env, File dir)
+ throws IOException;
+} // class Runtime
diff --git a/libjava/java/lang/RuntimeException.h b/libjava/java/lang/RuntimeException.h
new file mode 100644
index 000000000..0bce089c7
--- /dev/null
+++ b/libjava/java/lang/RuntimeException.h
@@ -0,0 +1,25 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_RuntimeException__
+#define __java_lang_RuntimeException__
+
+#pragma interface
+
+#include <java/lang/Exception.h>
+
+class java::lang::RuntimeException : public ::java::lang::Exception
+{
+
+public:
+ RuntimeException();
+ RuntimeException(::java::lang::String *);
+ RuntimeException(::java::lang::String *, ::java::lang::Throwable *);
+ RuntimeException(::java::lang::Throwable *);
+private:
+ static const jlong serialVersionUID = -7034897190745766939LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_RuntimeException__
diff --git a/libjava/java/lang/RuntimePermission.h b/libjava/java/lang/RuntimePermission.h
new file mode 100644
index 000000000..8b4817545
--- /dev/null
+++ b/libjava/java/lang/RuntimePermission.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_RuntimePermission__
+#define __java_lang_RuntimePermission__
+
+#pragma interface
+
+#include <java/security/BasicPermission.h>
+
+class java::lang::RuntimePermission : public ::java::security::BasicPermission
+{
+
+public:
+ RuntimePermission(::java::lang::String *);
+ RuntimePermission(::java::lang::String *, ::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 7399184964622342223LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_RuntimePermission__
diff --git a/libjava/java/lang/SecurityException.h b/libjava/java/lang/SecurityException.h
new file mode 100644
index 000000000..3b19ba203
--- /dev/null
+++ b/libjava/java/lang/SecurityException.h
@@ -0,0 +1,25 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_SecurityException__
+#define __java_lang_SecurityException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::SecurityException : public ::java::lang::RuntimeException
+{
+
+public:
+ SecurityException();
+ SecurityException(::java::lang::String *);
+ SecurityException(::java::lang::String *, ::java::lang::Throwable *);
+ SecurityException(::java::lang::Throwable *);
+private:
+ static const jlong serialVersionUID = 6878364983674394167LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_SecurityException__
diff --git a/libjava/java/lang/SecurityManager$1.h b/libjava/java/lang/SecurityManager$1.h
new file mode 100644
index 000000000..4e5787541
--- /dev/null
+++ b/libjava/java/lang/SecurityManager$1.h
@@ -0,0 +1,26 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_SecurityManager$1__
+#define __java_lang_SecurityManager$1__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::SecurityManager$1 : public ::java::lang::Object
+{
+
+public: // actually package-private
+ SecurityManager$1(::java::lang::SecurityManager *, ::java::lang::String *);
+public:
+ virtual ::java::lang::Object * run();
+public: // actually package-private
+ ::java::lang::SecurityManager * __attribute__((aligned(__alignof__( ::java::lang::Object)))) this$0;
+private:
+ ::java::lang::String * val$restriction;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_SecurityManager$1__
diff --git a/libjava/java/lang/SecurityManager.h b/libjava/java/lang/SecurityManager.h
new file mode 100644
index 000000000..8abaa6a7e
--- /dev/null
+++ b/libjava/java/lang/SecurityManager.h
@@ -0,0 +1,84 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_SecurityManager__
+#define __java_lang_SecurityManager__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+extern "Java"
+{
+ namespace java
+ {
+ namespace net
+ {
+ class InetAddress;
+ }
+ namespace security
+ {
+ class Permission;
+ }
+ }
+}
+
+class java::lang::SecurityManager : public ::java::lang::Object
+{
+
+public:
+ SecurityManager();
+ virtual jboolean getInCheck();
+public: // actually protected
+ virtual JArray< ::java::lang::Class * > * getClassContext();
+ virtual ::java::lang::ClassLoader * currentClassLoader();
+ virtual ::java::lang::Class * currentLoadedClass();
+ virtual jint classDepth(::java::lang::String *);
+ virtual jint classLoaderDepth();
+ virtual jboolean inClass(::java::lang::String *);
+ virtual jboolean inClassLoader();
+public:
+ virtual ::java::lang::Object * getSecurityContext();
+ virtual void checkPermission(::java::security::Permission *);
+ virtual void checkPermission(::java::security::Permission *, ::java::lang::Object *);
+ virtual void checkCreateClassLoader();
+ virtual void checkAccess(::java::lang::Thread *);
+ virtual void checkAccess(::java::lang::ThreadGroup *);
+ virtual void checkExit(jint);
+ virtual void checkExec(::java::lang::String *);
+ virtual void checkLink(::java::lang::String *);
+ virtual void checkRead(::java::io::FileDescriptor *);
+ virtual void checkRead(::java::lang::String *);
+ virtual void checkRead(::java::lang::String *, ::java::lang::Object *);
+ virtual void checkWrite(::java::io::FileDescriptor *);
+ virtual void checkWrite(::java::lang::String *);
+ virtual void checkDelete(::java::lang::String *);
+ virtual void checkConnect(::java::lang::String *, jint);
+ virtual void checkConnect(::java::lang::String *, jint, ::java::lang::Object *);
+ virtual void checkListen(jint);
+ virtual void checkAccept(::java::lang::String *, jint);
+ virtual void checkMulticast(::java::net::InetAddress *);
+ virtual void checkMulticast(::java::net::InetAddress *, jbyte);
+ virtual void checkPropertiesAccess();
+ virtual void checkPropertyAccess(::java::lang::String *);
+ virtual jboolean checkTopLevelWindow(::java::lang::Object *);
+ virtual void checkPrintJobAccess();
+ virtual void checkSystemClipboardAccess();
+ virtual void checkAwtEventQueueAccess();
+ virtual void checkPackageAccess(::java::lang::String *);
+ virtual void checkPackageDefinition(::java::lang::String *);
+ virtual void checkSetFactory();
+ virtual void checkMemberAccess(::java::lang::Class *, jint);
+ virtual void checkSecurityAccess(::java::lang::String *);
+ virtual ::java::lang::ThreadGroup * getThreadGroup();
+public: // actually package-private
+ virtual void checkPackageList(::java::lang::String *, ::java::lang::String *, ::java::lang::String *);
+ static ::java::lang::SecurityManager * volatile current;
+public: // actually protected
+ jboolean __attribute__((aligned(__alignof__( ::java::lang::Object)))) inCheck;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_SecurityManager__
diff --git a/libjava/java/lang/Short.h b/libjava/java/lang/Short.h
new file mode 100644
index 000000000..4858db52f
--- /dev/null
+++ b/libjava/java/lang/Short.h
@@ -0,0 +1,54 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Short__
+#define __java_lang_Short__
+
+#pragma interface
+
+#include <java/lang/Number.h>
+#include <gcj/array.h>
+
+
+class java::lang::Short : public ::java::lang::Number
+{
+
+public:
+ Short(jshort);
+ Short(::java::lang::String *);
+ static ::java::lang::String * toString(jshort);
+ static jshort parseShort(::java::lang::String *);
+ static jshort parseShort(::java::lang::String *, jint);
+ static ::java::lang::Short * valueOf(::java::lang::String *, jint);
+ static ::java::lang::Short * valueOf(::java::lang::String *);
+ static ::java::lang::Short * valueOf(jshort);
+ static ::java::lang::Short * decode(::java::lang::String *);
+ jbyte byteValue();
+ jshort shortValue();
+ jint intValue();
+ jlong longValue();
+ jfloat floatValue();
+ jdouble doubleValue();
+ ::java::lang::String * toString();
+ jint hashCode();
+ jboolean equals(::java::lang::Object *);
+ jint Short$compareTo(::java::lang::Short *);
+ static jshort reverseBytes(jshort);
+ jint compareTo(::java::lang::Object *);
+private:
+ static const jlong serialVersionUID = 7515723908773894738LL;
+public:
+ static const jshort MIN_VALUE = -32768;
+ static const jshort MAX_VALUE = 32767;
+ static ::java::lang::Class * TYPE;
+ static const jint SIZE = 16;
+private:
+ static const jint MIN_CACHE = -128;
+ static const jint MAX_CACHE = 127;
+ static JArray< ::java::lang::Short * > * shortCache;
+ jshort __attribute__((aligned(__alignof__( ::java::lang::Number)))) value;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Short__
diff --git a/libjava/java/lang/StackOverflowError.h b/libjava/java/lang/StackOverflowError.h
new file mode 100644
index 000000000..6d1e06f65
--- /dev/null
+++ b/libjava/java/lang/StackOverflowError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_StackOverflowError__
+#define __java_lang_StackOverflowError__
+
+#pragma interface
+
+#include <java/lang/VirtualMachineError.h>
+
+class java::lang::StackOverflowError : public ::java::lang::VirtualMachineError
+{
+
+public:
+ StackOverflowError();
+ StackOverflowError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 8609175038441759607LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_StackOverflowError__
diff --git a/libjava/java/lang/StackTraceElement.h b/libjava/java/lang/StackTraceElement.h
new file mode 100644
index 000000000..7adf3dc31
--- /dev/null
+++ b/libjava/java/lang/StackTraceElement.h
@@ -0,0 +1,39 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_StackTraceElement__
+#define __java_lang_StackTraceElement__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::StackTraceElement : public ::java::lang::Object
+{
+
+public: // actually package-private
+ StackTraceElement(::java::lang::String *, jint, ::java::lang::String *, ::java::lang::String *, jboolean);
+public:
+ StackTraceElement(::java::lang::String *, ::java::lang::String *, ::java::lang::String *, jint);
+ ::java::lang::String * getFileName();
+ jint getLineNumber();
+ ::java::lang::String * getClassName();
+ ::java::lang::String * getMethodName();
+ jboolean isNativeMethod();
+ ::java::lang::String * toString();
+ jboolean equals(::java::lang::Object *);
+ jint hashCode();
+private:
+ static jboolean equals(::java::lang::Object *, ::java::lang::Object *);
+ static jint hashCode(::java::lang::Object *);
+ static const jlong serialVersionUID = 6992337162326171013LL;
+ ::java::lang::String * __attribute__((aligned(__alignof__( ::java::lang::Object)))) fileName;
+ jint lineNumber;
+ ::java::lang::String * declaringClass;
+ ::java::lang::String * methodName;
+ jboolean isNative;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_StackTraceElement__
diff --git a/libjava/java/lang/StrictMath.h b/libjava/java/lang/StrictMath.h
new file mode 100644
index 000000000..d37d5d668
--- /dev/null
+++ b/libjava/java/lang/StrictMath.h
@@ -0,0 +1,203 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_StrictMath__
+#define __java_lang_StrictMath__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::StrictMath : public ::java::lang::Object
+{
+
+ StrictMath();
+public:
+ static jint abs(jint);
+ static jlong abs(jlong);
+ static jfloat abs(jfloat);
+ static jdouble abs(jdouble);
+ static jint min(jint, jint);
+ static jlong min(jlong, jlong);
+ static jfloat min(jfloat, jfloat);
+ static jdouble min(jdouble, jdouble);
+ static jint max(jint, jint);
+ static jlong max(jlong, jlong);
+ static jfloat max(jfloat, jfloat);
+ static jdouble max(jdouble, jdouble);
+ static jdouble sin(jdouble);
+ static jdouble cos(jdouble);
+ static jdouble tan(jdouble);
+ static jdouble asin(jdouble);
+ static jdouble acos(jdouble);
+ static jdouble atan(jdouble);
+ static jdouble atan2(jdouble, jdouble);
+ static jdouble sinh(jdouble);
+ static jdouble cosh(jdouble);
+ static jdouble tanh(jdouble);
+private:
+ static jlong getLowDWord(jlong);
+ static jlong getHighDWord(jlong);
+ static jdouble buildDouble(jlong, jlong);
+public:
+ static jdouble cbrt(jdouble);
+ static jdouble exp(jdouble);
+ static jdouble expm1(jdouble);
+ static jdouble log(jdouble);
+ static jdouble sqrt(jdouble);
+ static jdouble pow(jdouble, jdouble);
+ static jdouble IEEEremainder(jdouble, jdouble);
+ static jdouble ceil(jdouble);
+ static jdouble floor(jdouble);
+ static jdouble rint(jdouble);
+ static jint round(jfloat);
+ static jlong round(jdouble);
+ static jdouble random();
+ static jdouble toRadians(jdouble);
+ static jdouble toDegrees(jdouble);
+private:
+ static jint remPiOver2(jdouble, JArray< jdouble > *);
+ static jint remPiOver2(JArray< jdouble > *, JArray< jdouble > *, jint, jint);
+ static jdouble scale(jdouble, jint);
+ static jdouble sin(jdouble, jdouble);
+ static jdouble cos(jdouble, jdouble);
+ static jdouble tan(jdouble, jdouble, jboolean);
+public:
+ static jdouble signum(jdouble);
+ static jfloat signum(jfloat);
+ static jdouble ulp(jdouble);
+ static jfloat ulp(jfloat);
+private:
+ static ::java::util::Random * rand;
+public:
+ static jdouble E;
+ static jdouble PI;
+private:
+ static jdouble TWO_16;
+ static jdouble TWO_20;
+ static jdouble TWO_24;
+ static jdouble TWO_27;
+ static jdouble TWO_28;
+ static jdouble TWO_29;
+ static jdouble TWO_31;
+ static jdouble TWO_49;
+ static jdouble TWO_52;
+ static jdouble TWO_54;
+ static jdouble TWO_57;
+ static jdouble TWO_60;
+ static jdouble TWO_64;
+ static jdouble TWO_66;
+ static jdouble TWO_1023;
+ static JArray< jint > * TWO_OVER_PI;
+ static JArray< jdouble > * PI_OVER_TWO;
+ static jdouble PI_L;
+ static jdouble PIO2_1;
+ static jdouble PIO2_1L;
+ static jdouble PIO2_2;
+ static jdouble PIO2_2L;
+ static jdouble PIO2_3;
+ static jdouble PIO2_3L;
+ static jdouble SQRT_1_5;
+ static jdouble SQRT_2;
+ static jdouble SQRT_3;
+ static jdouble EXP_LIMIT_H;
+ static jdouble EXP_LIMIT_L;
+ static jdouble CP;
+ static jdouble CP_H;
+ static jdouble CP_L;
+ static jdouble LN2;
+ static jdouble LN2_H;
+ static jdouble LN2_L;
+ static jdouble INV_LN2;
+ static jdouble INV_LN2_H;
+ static jdouble INV_LN2_L;
+ static jdouble LG1;
+ static jdouble LG2;
+ static jdouble LG3;
+ static jdouble LG4;
+ static jdouble LG5;
+ static jdouble LG6;
+ static jdouble LG7;
+ static jdouble L1;
+ static jdouble L2;
+ static jdouble L3;
+ static jdouble L4;
+ static jdouble L5;
+ static jdouble L6;
+ static jdouble P1;
+ static jdouble P2;
+ static jdouble P3;
+ static jdouble P4;
+ static jdouble P5;
+ static jdouble DP_H;
+ static jdouble DP_L;
+ static jdouble OVT;
+ static jdouble S1;
+ static jdouble S2;
+ static jdouble S3;
+ static jdouble S4;
+ static jdouble S5;
+ static jdouble S6;
+ static jdouble C1;
+ static jdouble C2;
+ static jdouble C3;
+ static jdouble C4;
+ static jdouble C5;
+ static jdouble C6;
+ static jdouble T0;
+ static jdouble T1;
+ static jdouble T2;
+ static jdouble T3;
+ static jdouble T4;
+ static jdouble T5;
+ static jdouble T6;
+ static jdouble T7;
+ static jdouble T8;
+ static jdouble T9;
+ static jdouble T10;
+ static jdouble T11;
+ static jdouble T12;
+ static jdouble PS0;
+ static jdouble PS1;
+ static jdouble PS2;
+ static jdouble PS3;
+ static jdouble PS4;
+ static jdouble PS5;
+ static jdouble QS1;
+ static jdouble QS2;
+ static jdouble QS3;
+ static jdouble QS4;
+ static jdouble ATAN_0_5H;
+ static jdouble ATAN_0_5L;
+ static jdouble ATAN_1_5H;
+ static jdouble ATAN_1_5L;
+ static jdouble AT0;
+ static jdouble AT1;
+ static jdouble AT2;
+ static jdouble AT3;
+ static jdouble AT4;
+ static jdouble AT5;
+ static jdouble AT6;
+ static jdouble AT7;
+ static jdouble AT8;
+ static jdouble AT9;
+ static jdouble AT10;
+ static const jint CBRT_B1 = 715094163;
+ static const jint CBRT_B2 = 696219795;
+ static jdouble CBRT_C;
+ static jdouble CBRT_D;
+ static jdouble CBRT_E;
+ static jdouble CBRT_F;
+ static jdouble CBRT_G;
+ static jdouble EXPM1_Q1;
+ static jdouble EXPM1_Q2;
+ static jdouble EXPM1_Q3;
+ static jdouble EXPM1_Q4;
+ static jdouble EXPM1_Q5;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_StrictMath__
diff --git a/libjava/java/lang/String$CaseInsensitiveComparator.h b/libjava/java/lang/String$CaseInsensitiveComparator.h
new file mode 100644
index 000000000..8a1b121bc
--- /dev/null
+++ b/libjava/java/lang/String$CaseInsensitiveComparator.h
@@ -0,0 +1,25 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_String$CaseInsensitiveComparator__
+#define __java_lang_String$CaseInsensitiveComparator__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::String$CaseInsensitiveComparator : public ::java::lang::Object
+{
+
+public: // actually package-private
+ String$CaseInsensitiveComparator();
+public:
+ jint String$CaseInsensitiveComparator$compare(::java::lang::String *, ::java::lang::String *);
+ jint compare(::java::lang::Object *, ::java::lang::Object *);
+private:
+ static const jlong serialVersionUID = 8575799808933029326LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_String$CaseInsensitiveComparator__
diff --git a/libjava/java/lang/String.h b/libjava/java/lang/String.h
new file mode 100644
index 000000000..32e0ccdfa
--- /dev/null
+++ b/libjava/java/lang/String.h
@@ -0,0 +1,148 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_String__
+#define __java_lang_String__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class StringBuffer;
+ }
+ }
+ }
+}
+
+jchar* _Jv_GetStringChars (jstring str);
+jstring* _Jv_StringFindSlot (jchar*, jint, jint);
+jstring* _Jv_StringGetSlot (jstring);
+jstring _Jv_NewStringUtf8Const (_Jv_Utf8Const* str);
+jstring _Jv_NewStringLatin1 (const char*, jsize);
+jstring _Jv_AllocString (jsize);
+
+class java::lang::String : public ::java::lang::Object
+{
+
+public:
+ String();
+ String(::java::lang::String *);
+ String(JArray< jchar > *);
+ String(JArray< jchar > *, jint, jint);
+ String(JArray< jbyte > *, jint, jint, jint);
+ String(JArray< jbyte > *, jint);
+ String(JArray< jbyte > *, jint, jint, ::java::lang::String *);
+ String(JArray< jbyte > *, ::java::lang::String *);
+ String(JArray< jbyte > *, jint, jint);
+ String(JArray< jbyte > *);
+ String(::java::lang::StringBuffer *);
+ String(::java::lang::StringBuilder *);
+public: // actually package-private
+ String(JArray< jchar > *, jint, jint, jboolean);
+ String(::gnu::gcj::runtime::StringBuffer *);
+public:
+ jint length();
+ jchar charAt(jint);
+ jint codePointAt(jint);
+ jint codePointBefore(jint);
+ void getChars(jint, jint, JArray< jchar > *, jint);
+ void getBytes(jint, jint, JArray< jbyte > *, jint);
+ JArray< jbyte > * getBytes(::java::lang::String *);
+ JArray< jbyte > * getBytes();
+ jboolean equals(::java::lang::Object *);
+ jboolean contentEquals(::java::lang::StringBuffer *);
+ jboolean contentEquals(::java::lang::CharSequence *);
+ jboolean equalsIgnoreCase(::java::lang::String *);
+ jint String$compareTo(::java::lang::String *);
+private:
+ jint nativeCompareTo(::java::lang::String *);
+public:
+ jint compareToIgnoreCase(::java::lang::String *);
+ jboolean regionMatches(jint, ::java::lang::String *, jint, jint);
+ jboolean regionMatches(jboolean, jint, ::java::lang::String *, jint, jint);
+ jboolean startsWith(::java::lang::String *, jint);
+ jboolean startsWith(::java::lang::String *);
+ jboolean endsWith(::java::lang::String *);
+ jint hashCode();
+ jint indexOf(jint);
+ jint indexOf(jint, jint);
+ jint lastIndexOf(jint);
+ jint lastIndexOf(jint, jint);
+ jint indexOf(::java::lang::String *);
+ jint indexOf(::java::lang::String *, jint);
+ jint lastIndexOf(::java::lang::String *);
+ jint lastIndexOf(::java::lang::String *, jint);
+ ::java::lang::String * substring(jint);
+ ::java::lang::String * substring(jint, jint);
+ ::java::lang::CharSequence * subSequence(jint, jint);
+ ::java::lang::String * concat(::java::lang::String *);
+ ::java::lang::String * replace(jchar, jchar);
+ jboolean matches(::java::lang::String *);
+ ::java::lang::String * replaceFirst(::java::lang::String *, ::java::lang::String *);
+ ::java::lang::String * replaceAll(::java::lang::String *, ::java::lang::String *);
+ JArray< ::java::lang::String * > * split(::java::lang::String *, jint);
+ JArray< ::java::lang::String * > * split(::java::lang::String *);
+ ::java::lang::String * toLowerCase(::java::util::Locale *);
+ ::java::lang::String * toLowerCase();
+ ::java::lang::String * toUpperCase(::java::util::Locale *);
+ ::java::lang::String * toUpperCase();
+ ::java::lang::String * trim();
+ ::java::lang::String * toString();
+ JArray< jchar > * toCharArray();
+ static ::java::lang::String * valueOf(::java::lang::Object *);
+ static ::java::lang::String * valueOf(JArray< jchar > *);
+ static ::java::lang::String * valueOf(JArray< jchar > *, jint, jint);
+ static ::java::lang::String * copyValueOf(JArray< jchar > *, jint, jint);
+ static ::java::lang::String * copyValueOf(JArray< jchar > *);
+ static ::java::lang::String * valueOf(jboolean);
+ static ::java::lang::String * valueOf(jchar);
+ static ::java::lang::String * valueOf(jint);
+ static ::java::lang::String * valueOf(jlong);
+ static ::java::lang::String * valueOf(jfloat);
+ static ::java::lang::String * valueOf(jdouble);
+ static ::java::lang::String * format(::java::util::Locale *, ::java::lang::String *, JArray< ::java::lang::Object * > *);
+ static ::java::lang::String * format(::java::lang::String *, JArray< ::java::lang::Object * > *);
+ ::java::lang::String * intern();
+ jint codePointCount(jint, jint);
+ jboolean contains(::java::lang::CharSequence *);
+ ::java::lang::String * replace(::java::lang::CharSequence *, ::java::lang::CharSequence *);
+ jint offsetByCodePoints(jint, jint);
+ jboolean isEmpty();
+private:
+ static ::java::lang::String * toString(JArray< jchar > *, jint, jint);
+ void init(JArray< jchar > *, jint, jint, jboolean);
+ void init(JArray< jbyte > *, jint, jint, jint);
+ void init(JArray< jbyte > *, jint, jint, ::java::lang::String *);
+ void init(::gnu::gcj::runtime::StringBuffer *);
+public:
+ jint compareTo(::java::lang::Object *);
+private:
+ static const jlong serialVersionUID = -6849794470754667710LL;
+ ::java::lang::Object * __attribute__((aligned(__alignof__( ::java::lang::Object)))) data;
+ jint boffset;
+public: // actually package-private
+ jint count;
+private:
+ jint cachedHashCode;
+public:
+ static ::java::util::Comparator * CASE_INSENSITIVE_ORDER;
+ static ::java::lang::Class class$;
+
+ friend jchar* ::_Jv_GetStringChars (jstring str);
+ friend jstring* ::_Jv_StringFindSlot (jchar*, jint, jint);
+ friend jstring* ::_Jv_StringGetSlot (jstring);
+ friend jstring (::_Jv_NewStringUtf8Const) (_Jv_Utf8Const* str);
+ friend jstring (::_Jv_NewStringLatin1) (const char*, jsize);
+ friend jstring (::_Jv_AllocString) (jsize);
+};
+
+#endif // __java_lang_String__
diff --git a/libjava/java/lang/String.java b/libjava/java/lang/String.java
new file mode 100644
index 000000000..b9ce3c016
--- /dev/null
+++ b/libjava/java/lang/String.java
@@ -0,0 +1,1457 @@
+/* String.java -- immutable character sequences; the object of string literals
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang;
+
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.util.Comparator;
+import java.text.Collator;
+import java.util.Formatter;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * Strings represent an immutable set of characters. All String literals
+ * are instances of this class, and two string literals with the same contents
+ * refer to the same String object.
+ *
+ * <p>This class also includes a number of methods for manipulating the
+ * contents of strings (of course, creating a new object if there are any
+ * changes, as String is immutable). Case mapping relies on Unicode 3.0.0
+ * standards, where some character sequences have a different number of
+ * characters in the uppercase version than the lower case.
+ *
+ * <p>Strings are special, in that they are the only object with an overloaded
+ * operator. When you use '+' with at least one String argument, both
+ * arguments have String conversion performed on them, and another String (not
+ * guaranteed to be unique) results.
+ *
+ * <p>String is special-cased when doing data serialization - rather than
+ * listing the fields of this class, a String object is converted to a string
+ * literal in the object stream.
+ *
+ * @author Paul N. Fisher
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Per Bothner (bothner@cygnus.com)
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public final class String
+ implements Serializable, Comparable<String>, CharSequence
+{
+ // WARNING: String is a CORE class in the bootstrap cycle. See the comments
+ // in vm/reference/java/lang/Runtime for implications of this fact.
+
+ /**
+ * This is probably not necessary because this class is special cased already
+ * but it will avoid showing up as a discrepancy when comparing SUIDs.
+ */
+ private static final long serialVersionUID = -6849794470754667710L;
+
+ /**
+ * This is the object that holds the characters that make up the
+ * String. It might be a char[], or it could be String. It could
+ * even be `this'. The actual characters can't be located using
+ * pure Java code.
+ * @see #boffset
+ */
+ private Object data;
+
+ /**
+ * This is a <emph>byte</emph> offset of the actual characters from
+ * the start of the character-holding object. Don't use this field
+ * in Java code.
+ */
+ private int boffset;
+
+ /**
+ * Holds the number of characters in value. Package visible for use
+ * by trusted code.
+ */
+ int count;
+
+ /**
+ * Caches the result of hashCode(). If this value is zero, the hashcode
+ * is considered uncached (even if 0 is the correct hash value).
+ */
+ private int cachedHashCode;
+
+ /**
+ * An implementation for {@link #CASE_INSENSITIVE_ORDER}.
+ * This must be {@link Serializable}. The class name is dictated by
+ * compatibility with Sun's JDK.
+ */
+ private static final class CaseInsensitiveComparator
+ implements Comparator<String>, Serializable
+ {
+ /**
+ * Compatible with JDK 1.2.
+ */
+ private static final long serialVersionUID = 8575799808933029326L;
+
+ /**
+ * The default private constructor generates unnecessary overhead.
+ */
+ CaseInsensitiveComparator() {}
+
+ /**
+ * Compares to Strings, using
+ * <code>String.compareToIgnoreCase(String)</code>.
+ *
+ * @param o1 the first string
+ * @param o2 the second string
+ * @return &lt; 0, 0, or &gt; 0 depending on the case-insensitive
+ * comparison of the two strings.
+ * @throws NullPointerException if either argument is null
+ * @throws ClassCastException if either argument is not a String
+ * @see #compareToIgnoreCase(String)
+ */
+ public int compare(String o1, String o2)
+ {
+ return o1.compareToIgnoreCase(o2);
+ }
+ } // class CaseInsensitiveComparator
+
+ /**
+ * A Comparator that uses <code>String.compareToIgnoreCase(String)</code>.
+ * This comparator is {@link Serializable}. Note that it ignores Locale,
+ * for that, you want a Collator.
+ *
+ * @see Collator#compare(String, String)
+ * @since 1.2
+ */
+ public static final Comparator<String> CASE_INSENSITIVE_ORDER
+ = new CaseInsensitiveComparator();
+
+ /**
+ * Creates an empty String (length 0). Unless you really need a new object,
+ * consider using <code>""</code> instead.
+ */
+ public String()
+ {
+ data = "".data;
+ boffset = 0;
+ count = 0;
+ }
+
+ /**
+ * Copies the contents of a String to a new String. Since Strings are
+ * immutable, only a shallow copy is performed.
+ *
+ * @param str String to copy
+ * @throws NullPointerException if value is null
+ */
+ public String(String str)
+ {
+ data = str.data;
+ boffset = str.boffset;
+ count = str.count;
+ cachedHashCode = str.cachedHashCode;
+ }
+
+ /**
+ * Creates a new String using the character sequence of the char array.
+ * Subsequent changes to data do not affect the String.
+ *
+ * @param data char array to copy
+ * @throws NullPointerException if data is null
+ */
+ public String(char[] data)
+ {
+ init(data, 0, data.length, false);
+ }
+
+ /**
+ * Creates a new String using the character sequence of a subarray of
+ * characters. The string starts at offset, and copies count chars.
+ * Subsequent changes to data do not affect the String.
+ *
+ * @param data char array to copy
+ * @param offset position (base 0) to start copying out of data
+ * @param count the number of characters from data to copy
+ * @throws NullPointerException if data is null
+ * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
+ * || offset + count &lt; 0 (overflow)
+ * || offset + count &gt; data.length)
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public String(char[] data, int offset, int count)
+ {
+ init(data, offset, count, false);
+ }
+
+ /**
+ * Creates a new String using an 8-bit array of integer values, starting at
+ * an offset, and copying up to the count. Each character c, using
+ * corresponding byte b, is created in the new String as if by performing:
+ *
+ * <pre>
+ * c = (char) (((hibyte &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
+ * </pre>
+ *
+ * @param ascii array of integer values
+ * @param hibyte top byte of each Unicode character
+ * @param offset position (base 0) to start copying out of ascii
+ * @param count the number of characters from ascii to copy
+ * @throws NullPointerException if ascii is null
+ * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
+ * || offset + count &lt; 0 (overflow)
+ * || offset + count &gt; ascii.length)
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ * @see #String(byte[])
+ * @see #String(byte[], String)
+ * @see #String(byte[], int, int)
+ * @see #String(byte[], int, int, String)
+ * @deprecated use {@link #String(byte[], int, int, String)} to perform
+ * correct encoding
+ */
+ public String(byte[] ascii, int hibyte, int offset, int count)
+ {
+ init(ascii, hibyte, offset, count);
+ }
+
+ /**
+ * Creates a new String using an 8-bit array of integer values. Each
+ * character c, using corresponding byte b, is created in the new String
+ * as if by performing:
+ *
+ * <pre>
+ * c = (char) (((hibyte &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
+ * </pre>
+ *
+ * @param ascii array of integer values
+ * @param hibyte top byte of each Unicode character
+ * @throws NullPointerException if ascii is null
+ * @see #String(byte[])
+ * @see #String(byte[], String)
+ * @see #String(byte[], int, int)
+ * @see #String(byte[], int, int, String)
+ * @see #String(byte[], int, int, int)
+ * @deprecated use {@link #String(byte[], String)} to perform
+ * correct encoding
+ */
+ public String(byte[] ascii, int hibyte)
+ {
+ init(ascii, hibyte, 0, ascii.length);
+ }
+
+ /**
+ * Creates a new String using the portion of the byte array starting at the
+ * offset and ending at offset + count. Uses the specified encoding type
+ * to decode the byte array, so the resulting string may be longer or
+ * shorter than the byte array. For more decoding control, use
+ * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
+ * see {@link java.nio.charset.Charset}. The behavior is not specified if
+ * the decoder encounters invalid characters; this implementation throws
+ * an Error.
+ *
+ * @param data byte array to copy
+ * @param offset the offset to start at
+ * @param count the number of bytes in the array to use
+ * @param encoding the name of the encoding to use
+ * @throws NullPointerException if data or encoding is null
+ * @throws IndexOutOfBoundsException if offset or count is incorrect
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ * @throws UnsupportedEncodingException if encoding is not found
+ * @throws Error if the decoding fails
+ * @since 1.1
+ */
+ public String(byte[] data, int offset, int count, String encoding)
+ throws UnsupportedEncodingException
+ {
+ init (data, offset, count, encoding);
+ }
+
+ /**
+ * Creates a new String using the byte array. Uses the specified encoding
+ * type to decode the byte array, so the resulting string may be longer or
+ * shorter than the byte array. For more decoding control, use
+ * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
+ * see {@link java.nio.charset.Charset}. The behavior is not specified if
+ * the decoder encounters invalid characters; this implementation throws
+ * an Error.
+ *
+ * @param data byte array to copy
+ * @param encoding the name of the encoding to use
+ * @throws NullPointerException if data or encoding is null
+ * @throws UnsupportedEncodingException if encoding is not found
+ * @throws Error if the decoding fails
+ * @see #String(byte[], int, int, String)
+ * @since 1.1
+ */
+ public String(byte[] data, String encoding)
+ throws UnsupportedEncodingException
+ {
+ this(data, 0, data.length, encoding);
+ }
+
+ /**
+ * Creates a new String using the portion of the byte array starting at the
+ * offset and ending at offset + count. Uses the encoding of the platform's
+ * default charset, so the resulting string may be longer or shorter than
+ * the byte array. For more decoding control, use
+ * {@link java.nio.charset.CharsetDecoder}. The behavior is not specified
+ * if the decoder encounters invalid characters; this implementation throws
+ * an Error.
+ *
+ * @param data byte array to copy
+ * @param offset the offset to start at
+ * @param count the number of bytes in the array to use
+ * @throws NullPointerException if data is null
+ * @throws IndexOutOfBoundsException if offset or count is incorrect
+ * @throws Error if the decoding fails
+ * @see #String(byte[], int, int, String)
+ * @since 1.1
+ */
+ public String(byte[] data, int offset, int count)
+ {
+ try
+ {
+ init (data, offset, count,
+ System.getProperty("file.encoding", "8859_1"));
+ }
+ catch (UnsupportedEncodingException x1)
+ {
+ // Maybe the default encoding is bad.
+ try
+ {
+ init (data, offset, count, "8859_1");
+ }
+ catch (UnsupportedEncodingException x2)
+ {
+ // We know this can't happen.
+ }
+ }
+ }
+
+ /**
+ * Creates a new String using the byte array. Uses the encoding of the
+ * platform's default charset, so the resulting string may be longer or
+ * shorter than the byte array. For more decoding control, use
+ * {@link java.nio.charset.CharsetDecoder}. The behavior is not specified
+ * if the decoder encounters invalid characters; this implementation throws
+ * an Error.
+ *
+ * @param data byte array to copy
+ * @throws NullPointerException if data is null
+ * @throws Error if the decoding fails
+ * @see #String(byte[], int, int)
+ * @see #String(byte[], int, int, String)
+ * @since 1.1
+ */
+ public String(byte[] data)
+ {
+ this(data, 0, data.length);
+ }
+
+ /**
+ * Creates a new String using the character sequence represented by
+ * the StringBuffer. Subsequent changes to buf do not affect the String.
+ *
+ * @param buffer StringBuffer to copy
+ * @throws NullPointerException if buffer is null
+ */
+ public String(StringBuffer buffer)
+ {
+ synchronized (buffer)
+ {
+ // Share unless buffer is 3/4 empty.
+ boolean should_copy = ((buffer.count << 2) < buffer.value.length);
+ if (! should_copy)
+ buffer.shared = true;
+ init (buffer.value, 0, buffer.count, ! should_copy);
+ }
+ }
+
+ /**
+ * Creates a new String using the character sequence represented by
+ * the StringBuilder. Subsequent changes to buf do not affect the String.
+ *
+ * @param buffer StringBuilder to copy
+ * @throws NullPointerException if buffer is null
+ */
+ public String(StringBuilder buffer)
+ {
+ this(buffer.value, 0, buffer.count);
+ }
+
+ /**
+ * Special constructor which can share an array when safe to do so.
+ *
+ * @param data the characters to copy
+ * @param offset the location to start from
+ * @param count the number of characters to use
+ * @param dont_copy true if the array is trusted, and need not be copied
+ * @throws NullPointerException if chars is null
+ * @throws StringIndexOutOfBoundsException if bounds check fails
+ */
+ String(char[] data, int offset, int count, boolean dont_copy)
+ {
+ init(data, offset, count, dont_copy);
+ }
+
+ // This is used by gnu.gcj.runtime.StringBuffer, so it must have
+ // package-private protection. It is accessed via CNI and so avoids
+ // ordinary protection mechanisms.
+ String(gnu.gcj.runtime.StringBuffer buffer)
+ {
+ // No need to synchronize or mark the buffer, since we know it is
+ // only used once.
+ init (buffer);
+ }
+
+ /**
+ * Returns the number of characters contained in this String.
+ *
+ * @return the length of this String
+ */
+ public int length()
+ {
+ return count;
+ }
+
+ /**
+ * Returns the character located at the specified index within this String.
+ *
+ * @param index position of character to return (base 0)
+ * @return character located at position index
+ * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= length()
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public native char charAt(int index);
+
+ /**
+ * Get the code point at the specified index. This is like #charAt(int),
+ * but if the character is the start of a surrogate pair, and the
+ * following character completes the pair, then the corresponding
+ * supplementary code point is returned.
+ * @param index the index of the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public synchronized int codePointAt(int index)
+ {
+ // Use the CharSequence overload as we get better range checking
+ // this way.
+ return Character.codePointAt(this, index);
+ }
+
+ /**
+ * Get the code point before the specified index. This is like
+ * #codePointAt(int), but checks the characters at <code>index-1</code> and
+ * <code>index-2</code> to see if they form a supplementary code point.
+ * @param index the index just past the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ * @since 1.5
+ */
+ public synchronized int codePointBefore(int index)
+ {
+ // Use the CharSequence overload as we get better range checking
+ // this way.
+ return Character.codePointBefore(this, index);
+ }
+
+ /**
+ * Copies characters from this String starting at a specified start index,
+ * ending at a specified stop index, to a character array starting at
+ * a specified destination begin index.
+ *
+ * @param srcBegin index to begin copying characters from this String
+ * @param srcEnd index after the last character to be copied from this String
+ * @param dst character array which this String is copied into
+ * @param dstBegin index to start writing characters into dst
+ * @throws NullPointerException if dst is null
+ * @throws IndexOutOfBoundsException if any indices are out of bounds
+ * (while unspecified, source problems cause a
+ * StringIndexOutOfBoundsException, and dst problems cause an
+ * ArrayIndexOutOfBoundsException)
+ */
+ public native void getChars(int srcBegin, int srcEnd,
+ char[] dst, int dstBegin);
+
+ /**
+ * Copies the low byte of each character from this String starting at a
+ * specified start index, ending at a specified stop index, to a byte array
+ * starting at a specified destination begin index.
+ *
+ * @param srcBegin index to being copying characters from this String
+ * @param srcEnd index after the last character to be copied from this String
+ * @param dst byte array which each low byte of this String is copied into
+ * @param dstBegin index to start writing characters into dst
+ * @throws NullPointerException if dst is null and copy length is non-zero
+ * @throws IndexOutOfBoundsException if any indices are out of bounds
+ * (while unspecified, source problems cause a
+ * StringIndexOutOfBoundsException, and dst problems cause an
+ * ArrayIndexOutOfBoundsException)
+ * @see #getBytes()
+ * @see #getBytes(String)
+ * @deprecated use {@link #getBytes()}, which uses a char to byte encoder
+ */
+ public native void getBytes(int srcBegin, int srcEnd,
+ byte[] dst, int dstBegin);
+
+ /**
+ * Converts the Unicode characters in this String to a byte array. Uses the
+ * specified encoding method, so the result may be longer or shorter than
+ * the String. For more encoding control, use
+ * {@link java.nio.charset.CharsetEncoder}, and for valid character sets,
+ * see {@link java.nio.charset.Charset}. The behavior is not specified if
+ * the encoder encounters a problem; this implementation returns null.
+ *
+ * @param enc encoding name
+ * @return the resulting byte array, or null on a problem
+ * @throws NullPointerException if enc is null
+ * @throws UnsupportedEncodingException if encoding is not supported
+ * @since 1.1
+ */
+ public native byte[] getBytes(String enc)
+ throws UnsupportedEncodingException;
+
+ /**
+ * Converts the Unicode characters in this String to a byte array. Uses the
+ * encoding of the platform's default charset, so the result may be longer
+ * or shorter than the String. For more encoding control, use
+ * {@link java.nio.charset.CharsetEncoder}. The behavior is not specified if
+ * the encoder encounters a problem; this implementation returns null.
+ *
+ * @return the resulting byte array, or null on a problem
+ * @since 1.1
+ */
+ public byte[] getBytes()
+ {
+ try
+ {
+ return getBytes (System.getProperty("file.encoding", "8859_1"));
+ }
+ catch (UnsupportedEncodingException x)
+ {
+ // This probably shouldn't happen, but could if file.encoding
+ // is somehow changed to a value we don't understand.
+ try
+ {
+ return getBytes ("8859_1");
+ }
+ catch (UnsupportedEncodingException x2)
+ {
+ // This really shouldn't happen, because the 8859_1
+ // encoding should always be available.
+ throw new InternalError ("couldn't find 8859_1 encoder");
+ }
+ }
+ }
+
+ /**
+ * Predicate which compares anObject to this. This is true only for Strings
+ * with the same character sequence.
+ *
+ * @param anObject the object to compare
+ * @return true if anObject is semantically equal to this
+ * @see #compareTo(String)
+ * @see #equalsIgnoreCase(String)
+ */
+ public native boolean equals(Object anObject);
+
+ /**
+ * Compares the given StringBuffer to this String. This is true if the
+ * StringBuffer has the same content as this String at this moment.
+ *
+ * @param buffer the StringBuffer to compare to
+ * @return true if StringBuffer has the same character sequence
+ * @throws NullPointerException if the given StringBuffer is null
+ * @since 1.4
+ */
+ public native boolean contentEquals(StringBuffer buffer);
+
+ /**
+ * Compares the given CharSequence to this String. This is true if
+ * the CharSequence has the same content as this String at this
+ * moment.
+ *
+ * @param seq the CharSequence to compare to
+ * @return true if CharSequence has the same character sequence
+ * @throws NullPointerException if the given CharSequence is null
+ * @since 1.5
+ */
+ public native boolean contentEquals(CharSequence seq);
+
+ /**
+ * Compares a String to this String, ignoring case. This does not handle
+ * multi-character capitalization exceptions; instead the comparison is
+ * made on a character-by-character basis, and is true if:<br><ul>
+ * <li><code>c1 == c2</code></li>
+ * <li><code>Character.toUpperCase(c1)
+ * == Character.toUpperCase(c2)</code></li>
+ * <li><code>Character.toLowerCase(c1)
+ * == Character.toLowerCase(c2)</code></li>
+ * </ul>
+ *
+ * @param anotherString String to compare to this String
+ * @return true if anotherString is equal, ignoring case
+ * @see #equals(Object)
+ * @see Character#toUpperCase(char)
+ * @see Character#toLowerCase(char)
+ */
+ public native boolean equalsIgnoreCase(String anotherString);
+
+ /**
+ * Compares this String and another String (case sensitive,
+ * lexicographically). The result is less than 0 if this string sorts
+ * before the other, 0 if they are equal, and greater than 0 otherwise.
+ * After any common starting sequence is skipped, the result is
+ * <code>this.charAt(k) - anotherString.charAt(k)</code> if both strings
+ * have characters remaining, or
+ * <code>this.length() - anotherString.length()</code> if one string is
+ * a subsequence of the other.
+ *
+ * @param anotherString the String to compare against
+ * @return the comparison
+ * @throws NullPointerException if anotherString is null
+ */
+ public int compareTo(String anotherString)
+ {
+ return nativeCompareTo(anotherString);
+ }
+
+ /**
+ * The native implementation of compareTo(). Must be named different
+ * since cni doesn't understand the bridge method generated from
+ * the compareTo() method because of the Comparable<String> interface.
+ */
+ private native int nativeCompareTo(String anotherString);
+
+ /**
+ * Compares this String and another String (case insensitive). This
+ * comparison is <em>similar</em> to equalsIgnoreCase, in that it ignores
+ * locale and multi-characater capitalization, and compares characters
+ * after performing
+ * <code>Character.toLowerCase(Character.toUpperCase(c))</code> on each
+ * character of the string. This is unsatisfactory for locale-based
+ * comparison, in which case you should use {@link java.text.Collator}.
+ *
+ * @param str the string to compare against
+ * @return the comparison
+ * @see Collator#compare(String, String)
+ * @since 1.2
+ */
+ public int compareToIgnoreCase(String str)
+ {
+ return this.toUpperCase().toLowerCase().compareTo(
+ str.toUpperCase().toLowerCase());
+ }
+
+ /**
+ * Predicate which determines if this String matches another String
+ * starting at a specified offset for each String and continuing
+ * for a specified length. Indices out of bounds are harmless, and give
+ * a false result.
+ *
+ * @param toffset index to start comparison at for this String
+ * @param other String to compare region to this String
+ * @param ooffset index to start comparison at for other
+ * @param len number of characters to compare
+ * @return true if regions match (case sensitive)
+ * @throws NullPointerException if other is null
+ */
+ public native boolean regionMatches(int toffset,
+ String other, int ooffset, int len);
+
+ /**
+ * Predicate which determines if this String matches another String
+ * starting at a specified offset for each String and continuing
+ * for a specified length, optionally ignoring case. Indices out of bounds
+ * are harmless, and give a false result. Case comparisons are based on
+ * <code>Character.toLowerCase()</code> and
+ * <code>Character.toUpperCase()</code>, not on multi-character
+ * capitalization expansions.
+ *
+ * @param ignoreCase true if case should be ignored in comparision
+ * @param toffset index to start comparison at for this String
+ * @param other String to compare region to this String
+ * @param ooffset index to start comparison at for other
+ * @param len number of characters to compare
+ * @return true if regions match, false otherwise
+ * @throws NullPointerException if other is null
+ */
+ public native boolean regionMatches(boolean ignoreCase, int toffset,
+ String other, int ooffset, int len);
+
+ /**
+ * Predicate which determines if this String contains the given prefix,
+ * beginning comparison at toffset. The result is false if toffset is
+ * negative or greater than this.length(), otherwise it is the same as
+ * <code>this.substring(toffset).startsWith(prefix)</code>.
+ *
+ * @param prefix String to compare
+ * @param toffset offset for this String where comparison starts
+ * @return true if this String starts with prefix
+ * @throws NullPointerException if prefix is null
+ * @see #regionMatches(boolean, int, String, int, int)
+ */
+ public native boolean startsWith(String prefix, int toffset);
+
+ /**
+ * Predicate which determines if this String starts with a given prefix.
+ * If the prefix is an empty String, true is returned.
+ *
+ * @param prefix String to compare
+ * @return true if this String starts with the prefix
+ * @throws NullPointerException if prefix is null
+ * @see #startsWith(String, int)
+ */
+ public boolean startsWith(String prefix)
+ {
+ return startsWith (prefix, 0);
+ }
+
+ /**
+ * Predicate which determines if this String ends with a given suffix.
+ * If the suffix is an empty String, true is returned.
+ *
+ * @param suffix String to compare
+ * @return true if this String ends with the suffix
+ * @throws NullPointerException if suffix is null
+ * @see #regionMatches(boolean, int, String, int, int)
+ */
+ public boolean endsWith(String suffix)
+ {
+ return regionMatches (this.count - suffix.count, suffix, 0, suffix.count);
+ }
+
+ /**
+ * Computes the hashcode for this String. This is done with int arithmetic,
+ * where ** represents exponentiation, by this formula:<br>
+ * <code>s[0]*31**(n-1) + s[1]*31**(n-2) + ... + s[n-1]</code>.
+ *
+ * @return hashcode value of this String
+ */
+ public native int hashCode();
+
+ /**
+ * Finds the first instance of a character in this String.
+ *
+ * @param ch character to find
+ * @return location (base 0) of the character, or -1 if not found
+ */
+ public int indexOf(int ch)
+ {
+ return indexOf(ch, 0);
+ }
+
+ /**
+ * Finds the first instance of a character in this String, starting at
+ * a given index. If starting index is less than 0, the search
+ * starts at the beginning of this String. If the starting index
+ * is greater than the length of this String, -1 is returned.
+ *
+ * @param ch character to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the character, or -1 if not found
+ */
+ public native int indexOf(int ch, int fromIndex);
+
+ /**
+ * Finds the last instance of a character in this String.
+ *
+ * @param ch character to find
+ * @return location (base 0) of the character, or -1 if not found
+ */
+ public int lastIndexOf(int ch)
+ {
+ return lastIndexOf(ch, count - 1);
+ }
+
+ /**
+ * Finds the last instance of a character in this String, starting at
+ * a given index. If starting index is greater than the maximum valid
+ * index, then the search begins at the end of this String. If the
+ * starting index is less than zero, -1 is returned.
+ *
+ * @param ch character to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the character, or -1 if not found
+ */
+ public native int lastIndexOf(int ch, int fromIndex);
+
+ /**
+ * Finds the first instance of a String in this String.
+ *
+ * @param str String to find
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ */
+ public int indexOf(String str)
+ {
+ return indexOf(str, 0);
+ }
+
+ /**
+ * Finds the first instance of a String in this String, starting at
+ * a given index. If starting index is less than 0, the search
+ * starts at the beginning of this String. If the starting index
+ * is greater than the length of this String, -1 is returned.
+ *
+ * @param str String to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ */
+ public native int indexOf(String str, int fromIndex);
+
+ /**
+ * Finds the last instance of a String in this String.
+ *
+ * @param str String to find
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ */
+ public int lastIndexOf(String str)
+ {
+ return lastIndexOf(str, count - str.count);
+ }
+
+ /**
+ * Finds the last instance of a String in this String, starting at
+ * a given index. If starting index is greater than the maximum valid
+ * index, then the search begins at the end of this String. If the
+ * starting index is less than zero, -1 is returned.
+ *
+ * @param str String to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ */
+ public int lastIndexOf(String str, int fromIndex)
+ {
+ if (fromIndex >= count)
+ fromIndex = count - str.count;
+ for (;; --fromIndex)
+ {
+ if (fromIndex < 0)
+ return -1;
+ if (startsWith(str, fromIndex))
+ return fromIndex;
+ }
+ }
+
+ /**
+ * Creates a substring of this String, starting at a specified index
+ * and ending at the end of this String.
+ *
+ * @param begin index to start substring (base 0)
+ * @return new String which is a substring of this String
+ * @throws IndexOutOfBoundsException if begin &lt; 0 || begin &gt; length()
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public String substring(int begin)
+ {
+ return substring(begin, count);
+ }
+
+ /**
+ * Creates a substring of this String, starting at a specified index
+ * and ending at one character before a specified index.
+ *
+ * @param begin index to start substring (inclusive, base 0)
+ * @param end index to end at (exclusive)
+ * @return new String which is a substring of this String
+ * @throws IndexOutOfBoundsException if begin &lt; 0 || end &gt; length()
+ * || begin &gt; end (while unspecified, this is a
+ * StringIndexOutOfBoundsException)
+ */
+ public native String substring(int begin, int end);
+
+ /**
+ * Creates a substring of this String, starting at a specified index
+ * and ending at one character before a specified index. This behaves like
+ * <code>substring(begin, end)</code>.
+ *
+ * @param begin index to start substring (inclusive, base 0)
+ * @param end index to end at (exclusive)
+ * @return new String which is a substring of this String
+ * @throws IndexOutOfBoundsException if begin &lt; 0 || end &gt; length()
+ * || begin &gt; end
+ * @since 1.4
+ */
+ public CharSequence subSequence(int begin, int end)
+ {
+ return substring(begin, end);
+ }
+
+ /**
+ * Concatenates a String to this String. This results in a new string unless
+ * one of the two originals is "".
+ *
+ * @param str String to append to this String
+ * @return newly concatenated String
+ * @throws NullPointerException if str is null
+ */
+ public native String concat(String str);
+
+ /**
+ * Replaces every instance of a character in this String with a new
+ * character. If no replacements occur, this is returned.
+ *
+ * @param oldChar the old character to replace
+ * @param newChar the new character
+ * @return new String with all instances of oldChar replaced with newChar
+ */
+ public native String replace(char oldChar, char newChar);
+
+ /**
+ * Test if this String matches a regular expression. This is shorthand for
+ * <code>{@link Pattern}.matches(regex, this)</code>.
+ *
+ * @param regex the pattern to match
+ * @return true if the pattern matches
+ * @throws NullPointerException if regex is null
+ * @throws PatternSyntaxException if regex is invalid
+ * @see Pattern#matches(String, CharSequence)
+ * @since 1.4
+ */
+ public boolean matches(String regex)
+ {
+ return Pattern.matches(regex, this);
+ }
+
+ /**
+ * Replaces the first substring match of the regular expression with a
+ * given replacement. This is shorthand for <code>{@link Pattern}
+ * .compile(regex).matcher(this).replaceFirst(replacement)</code>.
+ *
+ * @param regex the pattern to match
+ * @param replacement the replacement string
+ * @return the modified string
+ * @throws NullPointerException if regex or replacement is null
+ * @throws PatternSyntaxException if regex is invalid
+ * @see #replaceAll(String, String)
+ * @see Pattern#compile(String)
+ * @see Pattern#matcher(CharSequence)
+ * @see Matcher#replaceFirst(String)
+ * @since 1.4
+ */
+ public String replaceFirst(String regex, String replacement)
+ {
+ return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
+ }
+
+ /**
+ * Replaces all matching substrings of the regular expression with a
+ * given replacement. This is shorthand for <code>{@link Pattern}
+ * .compile(regex).matcher(this).replaceAll(replacement)</code>.
+ *
+ * @param regex the pattern to match
+ * @param replacement the replacement string
+ * @return the modified string
+ * @throws NullPointerException if regex or replacement is null
+ * @throws PatternSyntaxException if regex is invalid
+ * @see #replaceFirst(String, String)
+ * @see Pattern#compile(String)
+ * @see Pattern#matcher(CharSequence)
+ * @see Matcher#replaceAll(String)
+ * @since 1.4
+ */
+ public String replaceAll(String regex, String replacement)
+ {
+ return Pattern.compile(regex).matcher(this).replaceAll(replacement);
+ }
+
+ /**
+ * Split this string around the matches of a regular expression. Each
+ * element of the returned array is the largest block of characters not
+ * terminated by the regular expression, in the order the matches are found.
+ *
+ * <p>The limit affects the length of the array. If it is positive, the
+ * array will contain at most n elements (n - 1 pattern matches). If
+ * negative, the array length is unlimited, but there can be trailing empty
+ * entries. if 0, the array length is unlimited, and trailing empty entries
+ * are discarded.
+ *
+ * <p>For example, splitting "boo:and:foo" yields:<br>
+ * <table border=0>
+ * <th><td>Regex</td> <td>Limit</td> <td>Result</td></th>
+ * <tr><td>":"</td> <td>2</td> <td>{ "boo", "and:foo" }</td></tr>
+ * <tr><td>":"</td> <td>t</td> <td>{ "boo", "and", "foo" }</td></tr>
+ * <tr><td>":"</td> <td>-2</td> <td>{ "boo", "and", "foo" }</td></tr>
+ * <tr><td>"o"</td> <td>5</td> <td>{ "b", "", ":and:f", "", "" }</td></tr>
+ * <tr><td>"o"</td> <td>-2</td> <td>{ "b", "", ":and:f", "", "" }</td></tr>
+ * <tr><td>"o"</td> <td>0</td> <td>{ "b", "", ":and:f" }</td></tr>
+ * </table>
+ *
+ * <p>This is shorthand for
+ * <code>{@link Pattern}.compile(regex).split(this, limit)</code>.
+ *
+ * @param regex the pattern to match
+ * @param limit the limit threshold
+ * @return the array of split strings
+ * @throws NullPointerException if regex or replacement is null
+ * @throws PatternSyntaxException if regex is invalid
+ * @see Pattern#compile(String)
+ * @see Pattern#split(CharSequence, int)
+ * @since 1.4
+ */
+ public String[] split(String regex, int limit)
+ {
+ return Pattern.compile(regex).split(this, limit);
+ }
+
+ /**
+ * Split this string around the matches of a regular expression. Each
+ * element of the returned array is the largest block of characters not
+ * terminated by the regular expression, in the order the matches are found.
+ * The array length is unlimited, and trailing empty entries are discarded,
+ * as though calling <code>split(regex, 0)</code>.
+ *
+ * @param regex the pattern to match
+ * @return the array of split strings
+ * @throws NullPointerException if regex or replacement is null
+ * @throws PatternSyntaxException if regex is invalid
+ * @see #split(String, int)
+ * @see Pattern#compile(String)
+ * @see Pattern#split(CharSequence, int)
+ * @since 1.4
+ */
+ public String[] split(String regex)
+ {
+ return Pattern.compile(regex).split(this, 0);
+ }
+
+ /**
+ * Lowercases this String according to a particular locale. This uses
+ * Unicode's special case mappings, as applied to the given Locale, so the
+ * resulting string may be a different length.
+ *
+ * @param loc locale to use
+ * @return new lowercased String, or this if no characters were lowercased
+ * @throws NullPointerException if loc is null
+ * @see #toUpperCase(Locale)
+ * @since 1.1
+ */
+ public native String toLowerCase(Locale locale);
+
+ /**
+ * Lowercases this String. This uses Unicode's special case mappings, as
+ * applied to the platform's default Locale, so the resulting string may
+ * be a different length.
+ *
+ * @return new lowercased String, or this if no characters were lowercased
+ * @see #toLowerCase(Locale)
+ * @see #toUpperCase()
+ */
+ public String toLowerCase()
+ {
+ // The JDK is a bit confused about what to do here. If we pass in
+ // the default Locale then special Locale handling might be
+ // invoked. However, the docs also say that Character.toLowerCase
+ // rules here. We go with the latter.
+ return toLowerCase (null);
+ }
+
+ /**
+ * Uppercases this String according to a particular locale. This uses
+ * Unicode's special case mappings, as applied to the given Locale, so the
+ * resulting string may be a different length.
+ *
+ * @param loc locale to use
+ * @return new uppercased String, or this if no characters were uppercased
+ * @throws NullPointerException if loc is null
+ * @see #toLowerCase(Locale)
+ * @since 1.1
+ */
+ public native String toUpperCase(Locale locale);
+
+ /**
+ * Uppercases this String. This uses Unicode's special case mappings, as
+ * applied to the platform's default Locale, so the resulting string may
+ * be a different length.
+ *
+ * @return new uppercased String, or this if no characters were uppercased
+ * @see #toUpperCase(Locale)
+ * @see #toLowerCase()
+ */
+ public String toUpperCase()
+ {
+ // The JDK is a bit confused about what to do here. If we pass in
+ // the default Locale then special Locale handling might be
+ // invoked. However, the docs also say that Character.toLowerCase
+ // rules here. We go with the latter.
+ return toUpperCase (null);
+ }
+
+ /**
+ * Trims all characters less than or equal to <code>'\u0020'</code>
+ * (<code>' '</code>) from the beginning and end of this String. This
+ * includes many, but not all, ASCII control characters, and all
+ * {@link Character#isWhitespace(char)}.
+ *
+ * @return new trimmed String, or this if nothing trimmed
+ */
+ public native String trim();
+
+ /**
+ * Returns this, as it is already a String!
+ *
+ * @return this
+ */
+ public String toString()
+ {
+ return this;
+ }
+
+ /**
+ * Copies the contents of this String into a character array. Subsequent
+ * changes to the array do not affect the String.
+ *
+ * @return character array copying the String
+ */
+ public native char[] toCharArray();
+
+ /**
+ * Returns a String representation of an Object. This is "null" if the
+ * object is null, otherwise it is <code>obj.toString()</code> (which
+ * can be null).
+ *
+ * @param obj the Object
+ * @return the string conversion of obj
+ */
+ public static String valueOf(Object obj)
+ {
+ return obj == null ? "null" : obj.toString();
+ }
+
+ /**
+ * Returns a String representation of a character array. Subsequent
+ * changes to the array do not affect the String.
+ *
+ * @param data the character array
+ * @return a String containing the same character sequence as data
+ * @throws NullPointerException if data is null
+ * @see #valueOf(char[], int, int)
+ * @see #String(char[])
+ */
+ public static String valueOf(char[] data)
+ {
+ return valueOf (data, 0, data.length);
+ }
+
+ /**
+ * Returns a String representing the character sequence of the char array,
+ * starting at the specified offset, and copying chars up to the specified
+ * count. Subsequent changes to the array do not affect the String.
+ *
+ * @param data character array
+ * @param offset position (base 0) to start copying out of data
+ * @param count the number of characters from data to copy
+ * @return String containing the chars from data[offset..offset+count]
+ * @throws NullPointerException if data is null
+ * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
+ * || offset + count &gt; data.length)
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ * @see #String(char[], int, int)
+ */
+ public static native String valueOf(char[] data, int offset, int count);
+
+ /**
+ * Returns a String representing the character sequence of the char array,
+ * starting at the specified offset, and copying chars up to the specified
+ * count. Subsequent changes to the array do not affect the String.
+ *
+ * @param data character array
+ * @param offset position (base 0) to start copying out of data
+ * @param count the number of characters from data to copy
+ * @return String containing the chars from data[offset..offset+count]
+ * @throws NullPointerException if data is null
+ * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
+ * || offset + count &lt; 0 (overflow)
+ * || offset + count &gt; data.length)
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ * @see #String(char[], int, int)
+ */
+ public static String copyValueOf(char[] data, int offset, int count)
+ {
+ String r = new String ();
+ r.init(data, offset, count, false);
+ return r;
+ }
+
+ /**
+ * Returns a String representation of a character array. Subsequent
+ * changes to the array do not affect the String.
+ *
+ * @param data the character array
+ * @return a String containing the same character sequence as data
+ * @throws NullPointerException if data is null
+ * @see #copyValueOf(char[], int, int)
+ * @see #String(char[])
+ */
+ public static String copyValueOf(char[] data)
+ {
+ return copyValueOf (data, 0, data.length);
+ }
+
+ /**
+ * Returns a String representing a boolean.
+ *
+ * @param b the boolean
+ * @return "true" if b is true, else "false"
+ */
+ public static String valueOf(boolean b)
+ {
+ return b ? "true" : "false";
+ }
+
+ /**
+ * Returns a String representing a character.
+ *
+ * @param c the character
+ * @return String containing the single character c
+ */
+ public static native String valueOf(char c);
+
+ /**
+ * Returns a String representing an integer.
+ *
+ * @param i the integer
+ * @return String containing the integer in base 10
+ * @see Integer#toString(int)
+ */
+ public static native String valueOf(int i);
+
+ /**
+ * Returns a String representing a long.
+ *
+ * @param l the long
+ * @return String containing the long in base 10
+ * @see Long#toString(long)
+ */
+ public static String valueOf(long l)
+ {
+ return Long.toString(l);
+ }
+
+ /**
+ * Returns a String representing a float.
+ *
+ * @param f the float
+ * @return String containing the float
+ * @see Float#toString(float)
+ */
+ public static String valueOf(float f)
+ {
+ return Float.toString(f);
+ }
+
+ /**
+ * Returns a String representing a double.
+ *
+ * @param d the double
+ * @return String containing the double
+ * @see Double#toString(double)
+ */
+ public static String valueOf(double d)
+ {
+ return Double.toString(d);
+ }
+
+
+ /** @since 1.5 */
+ public static String format(Locale locale, String format, Object... args)
+ {
+ Formatter f = new Formatter(locale);
+ return f.format(format, args).toString();
+ }
+
+ /** @since 1.5 */
+ public static String format(String format, Object... args)
+ {
+ return format(Locale.getDefault(), format, args);
+ }
+
+ /**
+ * Fetches this String from the intern hashtable.
+ * If two Strings are considered equal, by the equals() method,
+ * then intern() will return the same String instance. ie.
+ * if (s1.equals(s2)) then (s1.intern() == s2.intern()).
+ * All string literals and string-valued constant expressions
+ * are already interned.
+ *
+ * @return the interned String
+ */
+ public native String intern();
+
+ /**
+ * Return the number of code points between two indices in the
+ * <code>String</code>. An unpaired surrogate counts as a
+ * code point for this purpose. Characters outside the indicated
+ * range are not examined, even if the range ends in the middle of a
+ * surrogate pair.
+ *
+ * @param start the starting index
+ * @param end one past the ending index
+ * @return the number of code points
+ * @since 1.5
+ */
+ public synchronized int codePointCount(int start, int end)
+ {
+ if (start < 0 || end > count || start > end)
+ throw new StringIndexOutOfBoundsException();
+
+ int count = 0;
+ while (start < end)
+ {
+ char base = charAt(start);
+ if (base < Character.MIN_HIGH_SURROGATE
+ || base > Character.MAX_HIGH_SURROGATE
+ || start == end
+ || start == count
+ || charAt(start + 1) < Character.MIN_LOW_SURROGATE
+ || charAt(start + 1) > Character.MAX_LOW_SURROGATE)
+ {
+ // Nothing.
+ }
+ else
+ {
+ // Surrogate pair.
+ ++start;
+ }
+ ++start;
+ ++count;
+ }
+ return count;
+ }
+
+ /**
+ * Returns true iff this String contains the sequence of Characters
+ * described in s.
+ * @param s the CharSequence
+ * @return true iff this String contains s
+ *
+ * @since 1.5
+ */
+ public boolean contains (CharSequence s)
+ {
+ return this.indexOf(s.toString()) != -1;
+ }
+
+ /**
+ * Returns a string that is this string with all instances of the sequence
+ * represented by <code>target</code> replaced by the sequence in
+ * <code>replacement</code>.
+ * @param target the sequence to be replaced
+ * @param replacement the sequence used as the replacement
+ * @return the string constructed as above
+ */
+ public String replace (CharSequence target, CharSequence replacement)
+ {
+ String targetString = target.toString();
+ String replaceString = replacement.toString();
+ int targetLength = target.length();
+ int replaceLength = replacement.length();
+
+ int startPos = this.indexOf(targetString);
+ StringBuilder result = new StringBuilder(this);
+ while (startPos != -1)
+ {
+ // Replace the target with the replacement
+ result.replace(startPos, startPos + targetLength, replaceString);
+
+ // Search for a new occurrence of the target
+ startPos = result.indexOf(targetString, startPos + replaceLength);
+ }
+ return result.toString();
+ }
+
+ /**
+ * Return the index into this String that is offset from the given index by
+ * <code>codePointOffset</code> code points.
+ * @param index the index at which to start
+ * @param codePointOffset the number of code points to offset
+ * @return the index into this String that is <code>codePointOffset</code>
+ * code points offset from <code>index</code>.
+ *
+ * @throws IndexOutOfBoundsException if index is negative or larger than the
+ * length of this string.
+ * @throws IndexOutOfBoundsException if codePointOffset is positive and the
+ * substring starting with index has fewer than codePointOffset code points.
+ * @throws IndexOutOfBoundsException if codePointOffset is negative and the
+ * substring ending with index has fewer than (-codePointOffset) code points.
+ * @since 1.5
+ */
+ public int offsetByCodePoints(int index, int codePointOffset)
+ {
+ if (index < 0 || index > count)
+ throw new IndexOutOfBoundsException();
+
+ return Character.offsetByCodePoints(this, index, codePointOffset);
+ }
+
+ /**
+ * Returns true if, and only if, {@link #length()}
+ * is <code>0</code>.
+ *
+ * @return true if the length of the string is zero.
+ * @since 1.6
+ */
+ public boolean isEmpty()
+ {
+ return count == 0;
+ }
+
+ // Generate a String that shares the value array: subsequent changes
+ // to this array will affect the String. A private internal method
+ // that is called from CPStringBuilder by compiler-generated code.
+ private static String toString(char[] value, int startIndex, int count)
+ {
+ return new String(value, startIndex, count, true);
+ }
+
+ private native void init(char[] chars, int offset, int count,
+ boolean dont_copy);
+ private native void init(byte[] chars, int hibyte, int offset, int count);
+ private native void init(byte[] chars, int offset, int count, String enc)
+ throws UnsupportedEncodingException;
+ private native void init(gnu.gcj.runtime.StringBuffer buffer);
+}
diff --git a/libjava/java/lang/StringBuffer.h b/libjava/java/lang/StringBuffer.h
new file mode 100644
index 000000000..487e2fcd3
--- /dev/null
+++ b/libjava/java/lang/StringBuffer.h
@@ -0,0 +1,115 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_StringBuffer__
+#define __java_lang_StringBuffer__
+
+#pragma interface
+
+#include <java/lang/AbstractStringBuffer.h>
+#include <gcj/array.h>
+
+
+class java::lang::StringBuffer : public ::java::lang::AbstractStringBuffer
+{
+
+public:
+ StringBuffer();
+ StringBuffer(jint);
+ StringBuffer(::java::lang::String *);
+ StringBuffer(::java::lang::CharSequence *);
+ jint length();
+ jint capacity();
+ void ensureCapacity(jint);
+ void setLength(jint);
+ jchar charAt(jint);
+ jint codePointAt(jint);
+ jint codePointBefore(jint);
+ void getChars(jint, jint, JArray< jchar > *, jint);
+ void setCharAt(jint, jchar);
+ ::java::lang::StringBuffer * StringBuffer$append(::java::lang::Object *);
+ ::java::lang::StringBuffer * StringBuffer$append(::java::lang::String *);
+ ::java::lang::StringBuffer * StringBuffer$append(::java::lang::StringBuffer *);
+ ::java::lang::StringBuffer * StringBuffer$append(JArray< jchar > *);
+ ::java::lang::StringBuffer * StringBuffer$append(JArray< jchar > *, jint, jint);
+ ::java::lang::StringBuffer * StringBuffer$append(jboolean);
+ ::java::lang::StringBuffer * StringBuffer$append(jchar);
+ ::java::lang::StringBuffer * StringBuffer$append(::java::lang::CharSequence *);
+ ::java::lang::StringBuffer * StringBuffer$append(::java::lang::CharSequence *, jint, jint);
+ ::java::lang::StringBuffer * StringBuffer$append(jint);
+ ::java::lang::StringBuffer * StringBuffer$append(jlong);
+ ::java::lang::StringBuffer * StringBuffer$append(jfloat);
+ ::java::lang::StringBuffer * StringBuffer$append(jdouble);
+ ::java::lang::StringBuffer * StringBuffer$appendCodePoint(jint);
+ ::java::lang::StringBuffer * StringBuffer$delete(jint, jint);
+ ::java::lang::StringBuffer * StringBuffer$deleteCharAt(jint);
+ ::java::lang::StringBuffer * StringBuffer$replace(jint, jint, ::java::lang::String *);
+ ::java::lang::String * substring(jint);
+ ::java::lang::CharSequence * subSequence(jint, jint);
+ ::java::lang::String * substring(jint, jint);
+ ::java::lang::StringBuffer * StringBuffer$insert(jint, JArray< jchar > *, jint, jint);
+ ::java::lang::StringBuffer * StringBuffer$insert(jint, ::java::lang::Object *);
+ ::java::lang::StringBuffer * StringBuffer$insert(jint, ::java::lang::String *);
+ ::java::lang::StringBuffer * StringBuffer$insert(jint, ::java::lang::CharSequence *);
+ ::java::lang::StringBuffer * StringBuffer$insert(jint, ::java::lang::CharSequence *, jint, jint);
+ ::java::lang::StringBuffer * StringBuffer$insert(jint, JArray< jchar > *);
+ ::java::lang::StringBuffer * StringBuffer$insert(jint, jboolean);
+ ::java::lang::StringBuffer * StringBuffer$insert(jint, jchar);
+ ::java::lang::StringBuffer * StringBuffer$insert(jint, jint);
+ ::java::lang::StringBuffer * StringBuffer$insert(jint, jlong);
+ ::java::lang::StringBuffer * StringBuffer$insert(jint, jfloat);
+ ::java::lang::StringBuffer * StringBuffer$insert(jint, jdouble);
+ jint indexOf(::java::lang::String *);
+ jint indexOf(::java::lang::String *, jint);
+ jint lastIndexOf(::java::lang::String *);
+ jint lastIndexOf(::java::lang::String *, jint);
+ ::java::lang::StringBuffer * StringBuffer$reverse();
+ ::java::lang::String * toString();
+ void trimToSize();
+ jint codePointCount(jint, jint);
+ jint offsetByCodePoints(jint, jint);
+public: // actually package-private
+ void ensureCapacity_unsynchronized(jint);
+public:
+ ::java::lang::AbstractStringBuffer * reverse();
+ ::java::lang::AbstractStringBuffer * deleteCharAt(jint);
+ ::java::lang::AbstractStringBuffer * replace(jint, jint, ::java::lang::String *);
+ ::java::lang::AbstractStringBuffer * delete$(jint, jint);
+ ::java::lang::AbstractStringBuffer * insert(jint, jdouble);
+ ::java::lang::AbstractStringBuffer * insert(jint, jfloat);
+ ::java::lang::AbstractStringBuffer * insert(jint, jlong);
+ ::java::lang::AbstractStringBuffer * insert(jint, jint);
+ ::java::lang::AbstractStringBuffer * insert(jint, jchar);
+ ::java::lang::AbstractStringBuffer * insert(jint, jboolean);
+ ::java::lang::AbstractStringBuffer * insert(jint, JArray< jchar > *);
+ ::java::lang::AbstractStringBuffer * insert(jint, ::java::lang::CharSequence *, jint, jint);
+ ::java::lang::AbstractStringBuffer * insert(jint, ::java::lang::CharSequence *);
+ ::java::lang::AbstractStringBuffer * insert(jint, ::java::lang::String *);
+ ::java::lang::AbstractStringBuffer * insert(jint, ::java::lang::Object *);
+ ::java::lang::AbstractStringBuffer * insert(jint, JArray< jchar > *, jint, jint);
+ ::java::lang::AbstractStringBuffer * append(jdouble);
+ ::java::lang::AbstractStringBuffer * append(jfloat);
+ ::java::lang::AbstractStringBuffer * append(jlong);
+ ::java::lang::AbstractStringBuffer * append(jint);
+ ::java::lang::Appendable * append(::java::lang::CharSequence *, jint, jint);
+ ::java::lang::AbstractStringBuffer * AbstractStringBuffer$append(::java::lang::CharSequence *, jint, jint);
+ ::java::lang::Appendable * append(::java::lang::CharSequence *);
+ ::java::lang::AbstractStringBuffer * AbstractStringBuffer$append(::java::lang::CharSequence *);
+ ::java::lang::Appendable * append(jchar);
+ ::java::lang::AbstractStringBuffer * AbstractStringBuffer$append(jchar);
+ ::java::lang::AbstractStringBuffer * append(jboolean);
+ ::java::lang::AbstractStringBuffer * append(JArray< jchar > *, jint, jint);
+ ::java::lang::AbstractStringBuffer * append(JArray< jchar > *);
+ ::java::lang::AbstractStringBuffer * append(::java::lang::StringBuffer *);
+ ::java::lang::AbstractStringBuffer * append(::java::lang::String *);
+ ::java::lang::AbstractStringBuffer * append(::java::lang::Object *);
+ ::java::lang::AbstractStringBuffer * appendCodePoint(jint);
+private:
+ static const jlong serialVersionUID = 3388685877147921107LL;
+public: // actually package-private
+ jboolean __attribute__((aligned(__alignof__( ::java::lang::AbstractStringBuffer)))) shared;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_StringBuffer__
diff --git a/libjava/java/lang/StringBuffer.java b/libjava/java/lang/StringBuffer.java
new file mode 100644
index 000000000..0c61b4d9f
--- /dev/null
+++ b/libjava/java/lang/StringBuffer.java
@@ -0,0 +1,976 @@
+/* StringBuffer.java -- Growable strings
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.io.Serializable;
+
+/**
+ * <code>StringBuffer</code> represents a changeable <code>String</code>.
+ * It provides the operations required to modify the
+ * <code>StringBuffer</code>, including insert, replace, delete, append,
+ * and reverse. It is thread-safe; meaning that all modifications to a buffer
+ * are in synchronized methods.
+ *
+ * <p><code>StringBuffer</code>s are variable-length in nature, so even if
+ * you initialize them to a certain size, they can still grow larger than
+ * that. <em>Capacity</em> indicates the number of characters the
+ * <code>StringBuffer</code> can have in it before it has to grow (growing
+ * the char array is an expensive operation involving <code>new</code>).
+ *
+ * <p>Incidentally, compilers often implement the String operator "+"
+ * by using a <code>StringBuffer</code> operation:<br>
+ * <code>a + b</code><br>
+ * is the same as<br>
+ * <code>new StringBuffer().append(a).append(b).toString()</code>.
+ *
+ * <p>Classpath's StringBuffer is capable of sharing memory with Strings for
+ * efficiency. This will help when a StringBuffer is converted to a String
+ * and the StringBuffer is not changed after that (quite common when performing
+ * string concatenation).
+ *
+ * @author Paul Fisher
+ * @author John Keiser
+ * @author Tom Tromey
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see String
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public final class StringBuffer
+ extends AbstractStringBuffer
+ implements Serializable, CharSequence, Appendable
+{
+ // Implementation note: if you change this class, you usually will
+ // want to change StringBuilder as well.
+
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = 3388685877147921107L;
+
+ /**
+ * True if the buffer is shared with another object (StringBuffer or
+ * String); this means the buffer must be copied before writing to it again.
+ * Note that this has permissions set this way so that String can get the
+ * value.
+ *
+ * @serial whether the buffer is shared
+ */
+ boolean shared;
+
+ /**
+ * Create a new StringBuffer with default capacity 16.
+ */
+ public StringBuffer()
+ {
+ super();
+ }
+
+ /**
+ * Create an empty <code>StringBuffer</code> with the specified initial
+ * capacity.
+ *
+ * @param capacity the initial capacity
+ * @throws NegativeArraySizeException if capacity is negative
+ */
+ public StringBuffer(int capacity)
+ {
+ super(capacity);
+ }
+
+ /**
+ * Create a new <code>StringBuffer</code> with the characters in the
+ * specified <code>String</code>. Initial capacity will be the size of the
+ * String plus 16.
+ *
+ * @param str the <code>String</code> to convert
+ * @throws NullPointerException if str is null
+ */
+ public StringBuffer(String str)
+ {
+ // Unfortunately, because the size is 16 larger, we cannot share.
+ super(str);
+ }
+
+ /**
+ * Create a new <code>StringBuffer</code> with the characters in the
+ * specified <code>CharSequence</code>. Initial capacity will be the
+ * length of the sequence plus 16; if the sequence reports a length
+ * less than or equal to 0, then the initial capacity will be 16.
+ *
+ * @param seq the initializing <code>CharSequence</code>
+ * @throws NullPointerException if str is null
+ * @since 1.5
+ */
+ public StringBuffer(CharSequence seq)
+ {
+ super(seq);
+ }
+
+ /**
+ * Get the length of the <code>String</code> this <code>StringBuffer</code>
+ * would create. Not to be confused with the <em>capacity</em> of the
+ * <code>StringBuffer</code>.
+ *
+ * @return the length of this <code>StringBuffer</code>
+ * @see #capacity()
+ * @see #setLength(int)
+ */
+ public synchronized int length()
+ {
+ return count;
+ }
+
+ /**
+ * Get the total number of characters this <code>StringBuffer</code> can
+ * support before it must be grown. Not to be confused with <em>length</em>.
+ *
+ * @return the capacity of this <code>StringBuffer</code>
+ * @see #length()
+ * @see #ensureCapacity(int)
+ */
+ public synchronized int capacity()
+ {
+ return value.length;
+ }
+
+ /**
+ * Increase the capacity of this <code>StringBuffer</code>. This will
+ * ensure that an expensive growing operation will not occur until
+ * <code>minimumCapacity</code> is reached. The buffer is grown to the
+ * larger of <code>minimumCapacity</code> and
+ * <code>capacity() * 2 + 2</code>, if it is not already large enough.
+ *
+ * @param minimumCapacity the new capacity
+ * @see #capacity()
+ */
+ public synchronized void ensureCapacity(int minimumCapacity)
+ {
+ ensureCapacity_unsynchronized(minimumCapacity);
+ }
+
+ /**
+ * Set the length of this StringBuffer. If the new length is greater than
+ * the current length, all the new characters are set to '\0'. If the new
+ * length is less than the current length, the first <code>newLength</code>
+ * characters of the old array will be preserved, and the remaining
+ * characters are truncated.
+ *
+ * @param newLength the new length
+ * @throws IndexOutOfBoundsException if the new length is negative
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ * @see #length()
+ */
+ public synchronized void setLength(int newLength)
+ {
+ super.setLength(newLength);
+ }
+
+ /**
+ * Get the character at the specified index.
+ *
+ * @param index the index of the character to get, starting at 0
+ * @return the character at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public synchronized char charAt(int index)
+ {
+ return super.charAt(index);
+ }
+
+ /**
+ * Get the code point at the specified index. This is like #charAt(int),
+ * but if the character is the start of a surrogate pair, and the
+ * following character completes the pair, then the corresponding
+ * supplementary code point is returned.
+ * @param index the index of the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public synchronized int codePointAt(int index)
+ {
+ return super.codePointAt(index);
+ }
+
+ /**
+ * Get the code point before the specified index. This is like
+ * #codePointAt(int), but checks the characters at <code>index-1</code> and
+ * <code>index-2</code> to see if they form a supplementary code point.
+ * @param index the index just past the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public synchronized int codePointBefore(int index)
+ {
+ return super.codePointBefore(index);
+ }
+
+ /**
+ * Get the specified array of characters. <code>srcOffset - srcEnd</code>
+ * characters will be copied into the array you pass in.
+ *
+ * @param srcOffset the index to start copying from (inclusive)
+ * @param srcEnd the index to stop copying from (exclusive)
+ * @param dst the array to copy into
+ * @param dstOffset the index to start copying into
+ * @throws NullPointerException if dst is null
+ * @throws IndexOutOfBoundsException if any source or target indices are
+ * out of range (while unspecified, source problems cause a
+ * StringIndexOutOfBoundsException, and dest problems cause an
+ * ArrayIndexOutOfBoundsException)
+ * @see System#arraycopy(Object, int, Object, int, int)
+ */
+ public synchronized void getChars(int srcOffset, int srcEnd,
+ char[] dst, int dstOffset)
+ {
+ super.getChars(srcOffset, srcEnd, dst, dstOffset);
+ }
+
+ /**
+ * Set the character at the specified index.
+ *
+ * @param index the index of the character to set starting at 0
+ * @param ch the value to set that character to
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public synchronized void setCharAt(int index, char ch)
+ {
+ super.setCharAt(index, ch);
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param obj the <code>Object</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(Object)
+ * @see #append(String)
+ */
+ public synchronized StringBuffer append(Object obj)
+ {
+ super.append(obj);
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> to this <code>StringBuffer</code>. If
+ * str is null, the String "null" is appended.
+ *
+ * @param str the <code>String</code> to append
+ * @return this <code>StringBuffer</code>
+ */
+ public synchronized StringBuffer append(String str)
+ {
+ super.append(str);
+ return this;
+ }
+
+ /**
+ * Append the <code>StringBuffer</code> value of the argument to this
+ * <code>StringBuffer</code>. This behaves the same as
+ * <code>append((Object) stringBuffer)</code>, except it is more efficient.
+ *
+ * @param stringBuffer the <code>StringBuffer</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see #append(Object)
+ * @since 1.4
+ */
+ public synchronized StringBuffer append(StringBuffer stringBuffer)
+ {
+ super.append(stringBuffer);
+ return this;
+ }
+
+ /**
+ * Append the <code>char</code> array to this <code>StringBuffer</code>.
+ * This is similar (but more efficient) than
+ * <code>append(new String(data))</code>, except in the case of null.
+ *
+ * @param data the <code>char[]</code> to append
+ * @return this <code>StringBuffer</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @see #append(char[], int, int)
+ */
+ public synchronized StringBuffer append(char[] data)
+ {
+ super.append(data, 0, data.length);
+ return this;
+ }
+
+ /**
+ * Append part of the <code>char</code> array to this
+ * <code>StringBuffer</code>. This is similar (but more efficient) than
+ * <code>append(new String(data, offset, count))</code>, except in the case
+ * of null.
+ *
+ * @param data the <code>char[]</code> to append
+ * @param offset the start location in <code>str</code>
+ * @param count the number of characters to get from <code>str</code>
+ * @return this <code>StringBuffer</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @throws IndexOutOfBoundsException if offset or count is out of range
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public synchronized StringBuffer append(char[] data, int offset, int count)
+ {
+ super.append(data, offset, count);
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param bool the <code>boolean</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(boolean)
+ */
+ public synchronized StringBuffer append(boolean bool)
+ {
+ super.append(bool);
+ return this;
+ }
+
+ /**
+ * Append the <code>char</code> to this <code>StringBuffer</code>.
+ *
+ * @param ch the <code>char</code> to append
+ * @return this <code>StringBuffer</code>
+ */
+ public synchronized StringBuffer append(char ch)
+ {
+ super.append(ch);
+ return this;
+ }
+
+ /**
+ * Append the characters in the <code>CharSequence</code> to this
+ * buffer.
+ *
+ * @param seq the <code>CharSequence</code> providing the characters
+ * @return this <code>StringBuffer</code>
+ * @since 1.5
+ */
+ public synchronized StringBuffer append(CharSequence seq)
+ {
+ super.append(seq, 0, seq.length());
+ return this;
+ }
+
+ /**
+ * Append some characters from the <code>CharSequence</code> to this
+ * buffer. If the argument is null, the four characters "null" are
+ * appended.
+ *
+ * @param seq the <code>CharSequence</code> providing the characters
+ * @param start the starting index
+ * @param end one past the final index
+ * @return this <code>StringBuffer</code>
+ * @since 1.5
+ */
+ public synchronized StringBuffer append(CharSequence seq, int start, int end)
+ {
+ super.append(seq, start, end);
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param inum the <code>int</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(int)
+ */
+ // This is native in libgcj, for efficiency.
+ public synchronized StringBuffer append(int inum)
+ {
+ super.append(inum);
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param lnum the <code>long</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(long)
+ */
+ public synchronized StringBuffer append(long lnum)
+ {
+ super.append(lnum);
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param fnum the <code>float</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(float)
+ */
+ public synchronized StringBuffer append(float fnum)
+ {
+ super.append(fnum);
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param dnum the <code>double</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(double)
+ */
+ public synchronized StringBuffer append(double dnum)
+ {
+ super.append(dnum);
+ return this;
+ }
+
+ /**
+ * Append the code point to this <code>StringBuffer</code>.
+ * This is like #append(char), but will append two characters
+ * if a supplementary code point is given.
+ *
+ * @param code the code point to append
+ * @return this <code>StringBuffer</code>
+ * @see Character#toChars(int, char[], int)
+ * @since 1.5
+ */
+ public synchronized StringBuffer appendCodePoint(int code)
+ {
+ super.appendCodePoint(code);
+ return this;
+ }
+
+ /**
+ * Delete characters from this <code>StringBuffer</code>.
+ * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
+ * harmless for end to be larger than length().
+ *
+ * @param start the first character to delete
+ * @param end the index after the last character to delete
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+ * @since 1.2
+ */
+ public synchronized StringBuffer delete(int start, int end)
+ {
+ // This will unshare if required.
+ super.delete(start, end);
+ return this;
+ }
+
+ /**
+ * Delete a character from this <code>StringBuffer</code>.
+ *
+ * @param index the index of the character to delete
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if index is out of bounds
+ * @since 1.2
+ */
+ public synchronized StringBuffer deleteCharAt(int index)
+ {
+ super.deleteCharAt(index);
+ return this;
+ }
+
+ /**
+ * Replace characters between index <code>start</code> (inclusive) and
+ * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
+ * is larger than the size of this StringBuffer, all characters after
+ * <code>start</code> are replaced.
+ *
+ * @param start the beginning index of characters to delete (inclusive)
+ * @param end the ending index of characters to delete (exclusive)
+ * @param str the new <code>String</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+ * @throws NullPointerException if str is null
+ * @since 1.2
+ */
+ public synchronized StringBuffer replace(int start, int end, String str)
+ {
+ super.replace(start, end, str);
+ return this;
+ }
+
+ /**
+ * Creates a substring of this StringBuffer, starting at a specified index
+ * and ending at the end of this StringBuffer.
+ *
+ * @param beginIndex index to start substring (base 0)
+ * @return new String which is a substring of this StringBuffer
+ * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds
+ * @see #substring(int, int)
+ * @since 1.2
+ */
+ public String substring(int beginIndex)
+ {
+ return substring(beginIndex, count);
+ }
+
+ /**
+ * Creates a substring of this StringBuffer, starting at a specified index
+ * and ending at one character before a specified index. This is implemented
+ * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy
+ * the CharSequence interface.
+ *
+ * @param beginIndex index to start at (inclusive, base 0)
+ * @param endIndex index to end at (exclusive)
+ * @return new String which is a substring of this StringBuffer
+ * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of
+ * bounds
+ * @see #substring(int, int)
+ * @since 1.4
+ */
+ public CharSequence subSequence(int beginIndex, int endIndex)
+ {
+ return substring(beginIndex, endIndex);
+ }
+
+ /**
+ * Creates a substring of this StringBuffer, starting at a specified index
+ * and ending at one character before a specified index.
+ *
+ * @param beginIndex index to start at (inclusive, base 0)
+ * @param endIndex index to end at (exclusive)
+ * @return new String which is a substring of this StringBuffer
+ * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out
+ * of bounds
+ * @since 1.2
+ */
+ public synchronized String substring(int beginIndex, int endIndex)
+ {
+ int len = endIndex - beginIndex;
+ if (beginIndex < 0 || endIndex > count || endIndex < beginIndex)
+ throw new StringIndexOutOfBoundsException();
+ if (len == 0)
+ return "";
+ // Don't copy unless substring is smaller than 1/4 of the buffer.
+ boolean share_buffer = ((len << 2) >= value.length);
+ if (share_buffer)
+ this.shared = true;
+ // Package constructor avoids an array copy.
+ return new String(value, beginIndex, len, share_buffer);
+ }
+
+ /**
+ * Insert a subarray of the <code>char[]</code> argument into this
+ * <code>StringBuffer</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param str the <code>char[]</code> to insert
+ * @param str_offset the index in <code>str</code> to start inserting from
+ * @param len the number of characters to insert
+ * @return this <code>StringBuffer</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @throws StringIndexOutOfBoundsException if any index is out of bounds
+ * @since 1.2
+ */
+ public synchronized StringBuffer insert(int offset,
+ char[] str, int str_offset, int len)
+ {
+ super.insert(offset, str, str_offset, len);
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param obj the <code>Object</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @exception StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(Object)
+ */
+ public synchronized StringBuffer insert(int offset, Object obj)
+ {
+ super.insert(offset, obj);
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> argument into this
+ * <code>StringBuffer</code>. If str is null, the String "null" is used
+ * instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param str the <code>String</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ */
+ public synchronized StringBuffer insert(int offset, String str)
+ {
+ super.insert(offset, str);
+ return this;
+ }
+
+ /**
+ * Insert the <code>CharSequence</code> argument into this
+ * <code>StringBuffer</code>. If the sequence is null, the String
+ * "null" is used instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param sequence the <code>CharSequence</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws IndexOutOfBoundsException if offset is out of bounds
+ * @since 1.5
+ */
+ public synchronized StringBuffer insert(int offset, CharSequence sequence)
+ {
+ super.insert(offset, sequence);
+ return this;
+ }
+
+ /**
+ * Insert a subsequence of the <code>CharSequence</code> argument into this
+ * <code>StringBuffer</code>. If the sequence is null, the String
+ * "null" is used instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param sequence the <code>CharSequence</code> to insert
+ * @param start the starting index of the subsequence
+ * @param end one past the ending index of the subsequence
+ * @return this <code>StringBuffer</code>
+ * @throws IndexOutOfBoundsException if offset, start,
+ * or end are out of bounds
+ * @since 1.5
+ */
+ public synchronized StringBuffer insert(int offset, CharSequence sequence,
+ int start, int end)
+ {
+ super.insert(offset, sequence, start, end);
+ return this;
+ }
+
+ /**
+ * Insert the <code>char[]</code> argument into this
+ * <code>StringBuffer</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param data the <code>char[]</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws NullPointerException if <code>data</code> is <code>null</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see #insert(int, char[], int, int)
+ */
+ public synchronized StringBuffer insert(int offset, char[] data)
+ {
+ super.insert(offset, data, 0, data.length);
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param bool the <code>boolean</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(boolean)
+ */
+ public synchronized StringBuffer insert(int offset, boolean bool)
+ {
+ super.insert(offset, bool);
+ return this;
+ }
+
+ /**
+ * Insert the <code>char</code> argument into this <code>StringBuffer</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param ch the <code>char</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ */
+ public synchronized StringBuffer insert(int offset, char ch)
+ {
+ super.insert(offset, ch);
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param inum the <code>int</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(int)
+ */
+ public synchronized StringBuffer insert(int offset, int inum)
+ {
+ super.insert(offset, inum);
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param lnum the <code>long</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(long)
+ */
+ public synchronized StringBuffer insert(int offset, long lnum)
+ {
+ super.insert(offset, lnum);
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param fnum the <code>float</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(float)
+ */
+ public synchronized StringBuffer insert(int offset, float fnum)
+ {
+ super.insert(offset, fnum);
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param dnum the <code>double</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(double)
+ */
+ public synchronized StringBuffer insert(int offset, double dnum)
+ {
+ super.insert(offset, dnum);
+ return this;
+ }
+
+ /**
+ * Finds the first instance of a substring in this StringBuffer.
+ *
+ * @param str String to find
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @see #indexOf(String, int)
+ * @since 1.4
+ */
+ public synchronized int indexOf(String str)
+ {
+ return super.indexOf(str, 0);
+ }
+
+ /**
+ * Finds the first instance of a String in this StringBuffer, starting at
+ * a given index. If starting index is less than 0, the search starts at
+ * the beginning of this String. If the starting index is greater than the
+ * length of this String, or the substring is not found, -1 is returned.
+ *
+ * @param str String to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @since 1.4
+ */
+ public synchronized int indexOf(String str, int fromIndex)
+ {
+ return super.indexOf(str, fromIndex);
+ }
+
+ /**
+ * Finds the last instance of a substring in this StringBuffer.
+ *
+ * @param str String to find
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @see #lastIndexOf(String, int)
+ * @since 1.4
+ */
+ public synchronized int lastIndexOf(String str)
+ {
+ return super.lastIndexOf(str, count - str.count);
+ }
+
+ /**
+ * Finds the last instance of a String in this StringBuffer, starting at a
+ * given index. If starting index is greater than the maximum valid index,
+ * then the search begins at the end of this String. If the starting index
+ * is less than zero, or the substring is not found, -1 is returned.
+ *
+ * @param str String to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @since 1.4
+ */
+ public synchronized int lastIndexOf(String str, int fromIndex)
+ {
+ return super.lastIndexOf(str, fromIndex);
+ }
+
+ /**
+ * Reverse the characters in this StringBuffer. The same sequence of
+ * characters exists, but in the reverse index ordering.
+ *
+ * @return this <code>StringBuffer</code>
+ */
+ public synchronized StringBuffer reverse()
+ {
+ super.reverse();
+ return this;
+ }
+
+ /**
+ * Convert this <code>StringBuffer</code> to a <code>String</code>. The
+ * String is composed of the characters currently in this StringBuffer. Note
+ * that the result is a copy, and that future modifications to this buffer
+ * do not affect the String.
+ *
+ * @return the characters in this StringBuffer
+ */
+ public String toString()
+ {
+ // The string will set this.shared = true.
+ return new String(this);
+ }
+
+ /**
+ * This may reduce the amount of memory used by the StringBuffer,
+ * by resizing the internal array to remove unused space. However,
+ * this method is not required to resize, so this behavior cannot
+ * be relied upon.
+ * @since 1.5
+ */
+ public synchronized void trimToSize()
+ {
+ super.trimToSize();
+ }
+
+ /**
+ * Return the number of code points between two indices in the
+ * <code>StringBuffer</code>. An unpaired surrogate counts as a
+ * code point for this purpose. Characters outside the indicated
+ * range are not examined, even if the range ends in the middle of a
+ * surrogate pair.
+ *
+ * @param start the starting index
+ * @param end one past the ending index
+ * @return the number of code points
+ * @since 1.5
+ */
+ public synchronized int codePointCount(int start, int end)
+ {
+ return super.codePointCount(start, end);
+ }
+
+ /**
+ * Starting at the given index, this counts forward by the indicated
+ * number of code points, and then returns the resulting index. An
+ * unpaired surrogate counts as a single code point for this
+ * purpose.
+ *
+ * @param start the starting index
+ * @param codePoints the number of code points
+ * @return the resulting index
+ * @since 1.5
+ */
+ public synchronized int offsetByCodePoints(int start, int codePoints)
+ {
+ return super.offsetByCodePoints(start, codePoints);
+ }
+
+ /**
+ * An unsynchronized version of ensureCapacity, used internally to avoid
+ * the cost of a second lock on the same object. This also has the side
+ * effect of duplicating the array, if it was shared (to form copy-on-write
+ * semantics).
+ *
+ * @param minimumCapacity the minimum capacity
+ * @see #ensureCapacity(int)
+ */
+ void ensureCapacity_unsynchronized(int minimumCapacity)
+ {
+ if (shared || minimumCapacity > value.length)
+ {
+ // We don't want to make a larger vector when `shared' is
+ // set. If we do, then setLength becomes very inefficient
+ // when repeatedly reusing a StringBuffer in a loop.
+ int max = (minimumCapacity > value.length
+ ? value.length * 2 + 2
+ : value.length);
+ minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
+ char[] nb = new char[minimumCapacity];
+ System.arraycopy(value, 0, nb, 0, count);
+ value = nb;
+ shared = false;
+ }
+ }
+
+}
diff --git a/libjava/java/lang/StringBuilder.h b/libjava/java/lang/StringBuilder.h
new file mode 100644
index 000000000..c8b952a41
--- /dev/null
+++ b/libjava/java/lang/StringBuilder.h
@@ -0,0 +1,96 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_StringBuilder__
+#define __java_lang_StringBuilder__
+
+#pragma interface
+
+#include <java/lang/AbstractStringBuffer.h>
+#include <gcj/array.h>
+
+
+class java::lang::StringBuilder : public ::java::lang::AbstractStringBuffer
+{
+
+public:
+ StringBuilder();
+ StringBuilder(jint);
+ StringBuilder(::java::lang::String *);
+ StringBuilder(::java::lang::CharSequence *);
+ jint length();
+ jint capacity();
+ ::java::lang::StringBuilder * StringBuilder$append(::java::lang::Object *);
+ ::java::lang::StringBuilder * StringBuilder$append(::java::lang::String *);
+ ::java::lang::StringBuilder * StringBuilder$append(::java::lang::StringBuffer *);
+ ::java::lang::StringBuilder * StringBuilder$append(JArray< jchar > *);
+ ::java::lang::StringBuilder * StringBuilder$append(JArray< jchar > *, jint, jint);
+ ::java::lang::StringBuilder * StringBuilder$append(jboolean);
+ ::java::lang::StringBuilder * StringBuilder$append(jchar);
+ ::java::lang::StringBuilder * StringBuilder$append(::java::lang::CharSequence *);
+ ::java::lang::StringBuilder * StringBuilder$append(::java::lang::CharSequence *, jint, jint);
+ ::java::lang::StringBuilder * StringBuilder$append(jint);
+ ::java::lang::StringBuilder * StringBuilder$append(jlong);
+ ::java::lang::StringBuilder * StringBuilder$append(jfloat);
+ ::java::lang::StringBuilder * StringBuilder$append(jdouble);
+ ::java::lang::StringBuilder * StringBuilder$appendCodePoint(jint);
+ ::java::lang::StringBuilder * StringBuilder$delete(jint, jint);
+ ::java::lang::StringBuilder * StringBuilder$deleteCharAt(jint);
+ ::java::lang::StringBuilder * StringBuilder$replace(jint, jint, ::java::lang::String *);
+ ::java::lang::String * substring(jint);
+ ::java::lang::CharSequence * subSequence(jint, jint);
+ ::java::lang::String * substring(jint, jint);
+ ::java::lang::StringBuilder * StringBuilder$insert(jint, JArray< jchar > *, jint, jint);
+ ::java::lang::StringBuilder * StringBuilder$insert(jint, ::java::lang::Object *);
+ ::java::lang::StringBuilder * StringBuilder$insert(jint, ::java::lang::String *);
+ ::java::lang::StringBuilder * StringBuilder$insert(jint, ::java::lang::CharSequence *);
+ ::java::lang::StringBuilder * StringBuilder$insert(jint, ::java::lang::CharSequence *, jint, jint);
+ ::java::lang::StringBuilder * StringBuilder$insert(jint, JArray< jchar > *);
+ ::java::lang::StringBuilder * StringBuilder$insert(jint, jboolean);
+ ::java::lang::StringBuilder * StringBuilder$insert(jint, jchar);
+ ::java::lang::StringBuilder * StringBuilder$insert(jint, jint);
+ ::java::lang::StringBuilder * StringBuilder$insert(jint, jlong);
+ ::java::lang::StringBuilder * StringBuilder$insert(jint, jfloat);
+ ::java::lang::StringBuilder * StringBuilder$insert(jint, jdouble);
+ ::java::lang::StringBuilder * StringBuilder$reverse();
+ ::java::lang::String * toString();
+ ::java::lang::AbstractStringBuffer * reverse();
+ ::java::lang::AbstractStringBuffer * deleteCharAt(jint);
+ ::java::lang::AbstractStringBuffer * replace(jint, jint, ::java::lang::String *);
+ ::java::lang::AbstractStringBuffer * delete$(jint, jint);
+ ::java::lang::AbstractStringBuffer * insert(jint, jdouble);
+ ::java::lang::AbstractStringBuffer * insert(jint, jfloat);
+ ::java::lang::AbstractStringBuffer * insert(jint, jlong);
+ ::java::lang::AbstractStringBuffer * insert(jint, jint);
+ ::java::lang::AbstractStringBuffer * insert(jint, jchar);
+ ::java::lang::AbstractStringBuffer * insert(jint, jboolean);
+ ::java::lang::AbstractStringBuffer * insert(jint, JArray< jchar > *);
+ ::java::lang::AbstractStringBuffer * insert(jint, ::java::lang::CharSequence *, jint, jint);
+ ::java::lang::AbstractStringBuffer * insert(jint, ::java::lang::CharSequence *);
+ ::java::lang::AbstractStringBuffer * insert(jint, ::java::lang::String *);
+ ::java::lang::AbstractStringBuffer * insert(jint, ::java::lang::Object *);
+ ::java::lang::AbstractStringBuffer * insert(jint, JArray< jchar > *, jint, jint);
+ ::java::lang::AbstractStringBuffer * append(jdouble);
+ ::java::lang::AbstractStringBuffer * append(jfloat);
+ ::java::lang::AbstractStringBuffer * append(jlong);
+ ::java::lang::AbstractStringBuffer * append(jint);
+ ::java::lang::Appendable * append(::java::lang::CharSequence *, jint, jint);
+ ::java::lang::AbstractStringBuffer * AbstractStringBuffer$append(::java::lang::CharSequence *, jint, jint);
+ ::java::lang::Appendable * append(::java::lang::CharSequence *);
+ ::java::lang::AbstractStringBuffer * AbstractStringBuffer$append(::java::lang::CharSequence *);
+ ::java::lang::Appendable * append(jchar);
+ ::java::lang::AbstractStringBuffer * AbstractStringBuffer$append(jchar);
+ ::java::lang::AbstractStringBuffer * append(jboolean);
+ ::java::lang::AbstractStringBuffer * append(JArray< jchar > *, jint, jint);
+ ::java::lang::AbstractStringBuffer * append(JArray< jchar > *);
+ ::java::lang::AbstractStringBuffer * append(::java::lang::StringBuffer *);
+ ::java::lang::AbstractStringBuffer * append(::java::lang::String *);
+ ::java::lang::AbstractStringBuffer * append(::java::lang::Object *);
+ ::java::lang::AbstractStringBuffer * appendCodePoint(jint);
+private:
+ static const jlong serialVersionUID = 4383685877147921099LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_StringBuilder__
diff --git a/libjava/java/lang/StringBuilder.java b/libjava/java/lang/StringBuilder.java
new file mode 100644
index 000000000..aefe9272b
--- /dev/null
+++ b/libjava/java/lang/StringBuilder.java
@@ -0,0 +1,706 @@
+/* StringBuilder.java -- Unsynchronized growable strings
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.io.Serializable;
+
+/**
+ * <code>StringBuilder</code> represents a changeable <code>String</code>.
+ * It provides the operations required to modify the
+ * <code>StringBuilder</code>, including insert, replace, delete, append,
+ * and reverse. It like <code>StringBuffer</code>, but is not
+ * synchronized. It is ideal for use when it is known that the
+ * object will only be used from a single thread.
+ *
+ * <p><code>StringBuilder</code>s are variable-length in nature, so even if
+ * you initialize them to a certain size, they can still grow larger than
+ * that. <em>Capacity</em> indicates the number of characters the
+ * <code>StringBuilder</code> can have in it before it has to grow (growing
+ * the char array is an expensive operation involving <code>new</code>).
+ *
+ * <p>Incidentally, compilers often implement the String operator "+"
+ * by using a <code>StringBuilder</code> operation:<br>
+ * <code>a + b</code><br>
+ * is the same as<br>
+ * <code>new StringBuilder().append(a).append(b).toString()</code>.
+ *
+ * <p>Classpath's StringBuilder is capable of sharing memory with Strings for
+ * efficiency. This will help when a StringBuilder is converted to a String
+ * and the StringBuilder is not changed after that (quite common when
+ * performing string concatenation).
+ *
+ * @author Paul Fisher
+ * @author John Keiser
+ * @author Tom Tromey
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see String
+ * @see StringBuffer
+ *
+ * @since 1.5
+ */
+public final class StringBuilder
+ extends AbstractStringBuffer
+ implements Serializable, CharSequence, Appendable
+{
+ // Implementation note: if you change this class, you usually will
+ // want to change StringBuffer as well.
+
+ /**
+ * For compatability with Sun's JDK
+ */
+ private static final long serialVersionUID = 4383685877147921099L;
+
+ /**
+ * Create a new StringBuilder with default capacity 16.
+ */
+ public StringBuilder()
+ {
+ super();
+ }
+
+ /**
+ * Create an empty <code>StringBuilder</code> with the specified initial
+ * capacity.
+ *
+ * @param capacity the initial capacity
+ * @throws NegativeArraySizeException if capacity is negative
+ */
+ public StringBuilder(int capacity)
+ {
+ super(capacity);
+ }
+
+ /**
+ * Create a new <code>StringBuilder</code> with the characters in the
+ * specified <code>String</code>. Initial capacity will be the size of the
+ * String plus 16.
+ *
+ * @param str the <code>String</code> to convert
+ * @throws NullPointerException if str is null
+ */
+ public StringBuilder(String str)
+ {
+ super(str);
+ }
+
+ /**
+ * Create a new <code>StringBuilder</code> with the characters in the
+ * specified <code>CharSequence</code>. Initial capacity will be the
+ * length of the sequence plus 16; if the sequence reports a length
+ * less than or equal to 0, then the initial capacity will be 16.
+ *
+ * @param seq the initializing <code>CharSequence</code>
+ * @throws NullPointerException if str is null
+ */
+ public StringBuilder(CharSequence seq)
+ {
+ super(seq);
+ }
+
+ /**
+ * Get the length of the <code>String</code> this <code>StringBuilder</code>
+ * would create. Not to be confused with the <em>capacity</em> of the
+ * <code>StringBuilder</code>.
+ *
+ * @return the length of this <code>StringBuilder</code>
+ * @see #capacity()
+ * @see #setLength(int)
+ */
+ public int length()
+ {
+ return count;
+ }
+
+ /**
+ * Get the total number of characters this <code>StringBuilder</code> can
+ * support before it must be grown. Not to be confused with <em>length</em>.
+ *
+ * @return the capacity of this <code>StringBuilder</code>
+ * @see #length()
+ * @see #ensureCapacity(int)
+ */
+ public int capacity()
+ {
+ return value.length;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param obj the <code>Object</code> to convert and append
+ * @return this <code>StringBuilder</code>
+ * @see String#valueOf(Object)
+ * @see #append(String)
+ */
+ public StringBuilder append(Object obj)
+ {
+ super.append(obj);
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> to this <code>StringBuilder</code>. If
+ * str is null, the String "null" is appended.
+ *
+ * @param str the <code>String</code> to append
+ * @return this <code>StringBuilder</code>
+ */
+ public StringBuilder append(String str)
+ {
+ super.append(str);
+ return this;
+ }
+
+ /**
+ * Append the <code>StringBuilder</code> value of the argument to this
+ * <code>StringBuilder</code>. This behaves the same as
+ * <code>append((Object) stringBuffer)</code>, except it is more efficient.
+ *
+ * @param stringBuffer the <code>StringBuilder</code> to convert and append
+ * @return this <code>StringBuilder</code>
+ * @see #append(Object)
+ */
+ public StringBuilder append(StringBuffer stringBuffer)
+ {
+ super.append(stringBuffer);
+ return this;
+ }
+
+ /**
+ * Append the <code>char</code> array to this <code>StringBuilder</code>.
+ * This is similar (but more efficient) than
+ * <code>append(new String(data))</code>, except in the case of null.
+ *
+ * @param data the <code>char[]</code> to append
+ * @return this <code>StringBuilder</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @see #append(char[], int, int)
+ */
+ public StringBuilder append(char[] data)
+ {
+ super.append(data, 0, data.length);
+ return this;
+ }
+
+ /**
+ * Append part of the <code>char</code> array to this
+ * <code>StringBuilder</code>. This is similar (but more efficient) than
+ * <code>append(new String(data, offset, count))</code>, except in the case
+ * of null.
+ *
+ * @param data the <code>char[]</code> to append
+ * @param offset the start location in <code>str</code>
+ * @param count the number of characters to get from <code>str</code>
+ * @return this <code>StringBuilder</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @throws IndexOutOfBoundsException if offset or count is out of range
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public StringBuilder append(char[] data, int offset, int count)
+ {
+ super.append(data, offset, count);
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param bool the <code>boolean</code> to convert and append
+ * @return this <code>StringBuilder</code>
+ * @see String#valueOf(boolean)
+ */
+ public StringBuilder append(boolean bool)
+ {
+ super.append(bool);
+ return this;
+ }
+
+ /**
+ * Append the <code>char</code> to this <code>StringBuilder</code>.
+ *
+ * @param ch the <code>char</code> to append
+ * @return this <code>StringBuilder</code>
+ */
+ public StringBuilder append(char ch)
+ {
+ super.append(ch);
+ return this;
+ }
+
+ /**
+ * Append the characters in the <code>CharSequence</code> to this
+ * buffer.
+ *
+ * @param seq the <code>CharSequence</code> providing the characters
+ * @return this <code>StringBuilder</code>
+ */
+ public StringBuilder append(CharSequence seq)
+ {
+ super.append(seq, 0, seq.length());
+ return this;
+ }
+
+ /**
+ * Append some characters from the <code>CharSequence</code> to this
+ * buffer. If the argument is null, the four characters "null" are
+ * appended.
+ *
+ * @param seq the <code>CharSequence</code> providing the characters
+ * @param start the starting index
+ * @param end one past the final index
+ * @return this <code>StringBuilder</code>
+ */
+ public StringBuilder append(CharSequence seq, int start,
+ int end)
+ {
+ super.append(seq, start, end);
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param inum the <code>int</code> to convert and append
+ * @return this <code>StringBuilder</code>
+ * @see String#valueOf(int)
+ */
+ // This is native in libgcj, for efficiency.
+ public StringBuilder append(int inum)
+ {
+ super.append(inum);
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param lnum the <code>long</code> to convert and append
+ * @return this <code>StringBuilder</code>
+ * @see String#valueOf(long)
+ */
+ public StringBuilder append(long lnum)
+ {
+ super.append(lnum);
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param fnum the <code>float</code> to convert and append
+ * @return this <code>StringBuilder</code>
+ * @see String#valueOf(float)
+ */
+ public StringBuilder append(float fnum)
+ {
+ super.append(fnum);
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param dnum the <code>double</code> to convert and append
+ * @return this <code>StringBuilder</code>
+ * @see String#valueOf(double)
+ */
+ public StringBuilder append(double dnum)
+ {
+ super.append(dnum);
+ return this;
+ }
+
+ /**
+ * Append the code point to this <code>StringBuilder</code>.
+ * This is like #append(char), but will append two characters
+ * if a supplementary code point is given.
+ *
+ * @param code the code point to append
+ * @return this <code>StringBuilder</code>
+ * @see Character#toChars(int, char[], int)
+ * @since 1.5
+ */
+ public StringBuilder appendCodePoint(int code)
+ {
+ super.appendCodePoint(code);
+ return this;
+ }
+
+ /**
+ * Delete characters from this <code>StringBuilder</code>.
+ * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
+ * harmless for end to be larger than length().
+ *
+ * @param start the first character to delete
+ * @param end the index after the last character to delete
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+ */
+ public StringBuilder delete(int start, int end)
+ {
+ super.delete(start, end);
+ return this;
+ }
+
+ /**
+ * Delete a character from this <code>StringBuilder</code>.
+ *
+ * @param index the index of the character to delete
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if index is out of bounds
+ */
+ public StringBuilder deleteCharAt(int index)
+ {
+ super.deleteCharAt(index);
+ return this;
+ }
+
+ /**
+ * Replace characters between index <code>start</code> (inclusive) and
+ * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
+ * is larger than the size of this StringBuilder, all characters after
+ * <code>start</code> are replaced.
+ *
+ * @param start the beginning index of characters to delete (inclusive)
+ * @param end the ending index of characters to delete (exclusive)
+ * @param str the new <code>String</code> to insert
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+ * @throws NullPointerException if str is null
+ */
+ public StringBuilder replace(int start, int end, String str)
+ {
+ super.replace(start, end, str);
+ return this;
+ }
+
+ /**
+ * Creates a substring of this StringBuilder, starting at a specified index
+ * and ending at the end of this StringBuilder.
+ *
+ * @param beginIndex index to start substring (base 0)
+ * @return new String which is a substring of this StringBuilder
+ * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds
+ * @see #substring(int, int)
+ */
+ public String substring(int beginIndex)
+ {
+ return substring(beginIndex, count);
+ }
+
+ /**
+ * Creates a substring of this StringBuilder, starting at a specified index
+ * and ending at one character before a specified index. This is implemented
+ * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy
+ * the CharSequence interface.
+ *
+ * @param beginIndex index to start at (inclusive, base 0)
+ * @param endIndex index to end at (exclusive)
+ * @return new String which is a substring of this StringBuilder
+ * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of
+ * bounds
+ * @see #substring(int, int)
+ */
+ public CharSequence subSequence(int beginIndex, int endIndex)
+ {
+ return substring(beginIndex, endIndex);
+ }
+
+ /**
+ * Creates a substring of this StringBuilder, starting at a specified index
+ * and ending at one character before a specified index.
+ *
+ * @param beginIndex index to start at (inclusive, base 0)
+ * @param endIndex index to end at (exclusive)
+ * @return new String which is a substring of this StringBuilder
+ * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out
+ * of bounds
+ */
+ public String substring(int beginIndex, int endIndex)
+ {
+ int len = endIndex - beginIndex;
+ if (beginIndex < 0 || endIndex > count || endIndex < beginIndex)
+ throw new StringIndexOutOfBoundsException();
+ if (len == 0)
+ return "";
+ return new String(value, beginIndex, len);
+ }
+
+ /**
+ * Insert a subarray of the <code>char[]</code> argument into this
+ * <code>StringBuilder</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param str the <code>char[]</code> to insert
+ * @param str_offset the index in <code>str</code> to start inserting from
+ * @param len the number of characters to insert
+ * @return this <code>StringBuilder</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @throws StringIndexOutOfBoundsException if any index is out of bounds
+ */
+ public StringBuilder insert(int offset,
+ char[] str, int str_offset, int len)
+ {
+ super.insert(offset, str, str_offset, len);
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param obj the <code>Object</code> to convert and insert
+ * @return this <code>StringBuilder</code>
+ * @exception StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(Object)
+ */
+ public StringBuilder insert(int offset, Object obj)
+ {
+ super.insert(offset, obj);
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> argument into this
+ * <code>StringBuilder</code>. If str is null, the String "null" is used
+ * instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param str the <code>String</code> to insert
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ */
+ public StringBuilder insert(int offset, String str)
+ {
+ super.insert(offset, str);
+ return this;
+ }
+
+ /**
+ * Insert the <code>CharSequence</code> argument into this
+ * <code>StringBuilder</code>. If the sequence is null, the String
+ * "null" is used instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param sequence the <code>CharSequence</code> to insert
+ * @return this <code>StringBuilder</code>
+ * @throws IndexOutOfBoundsException if offset is out of bounds
+ */
+ public StringBuilder insert(int offset, CharSequence sequence)
+ {
+ super.insert(offset, sequence);
+ return this;
+ }
+
+ /**
+ * Insert a subsequence of the <code>CharSequence</code> argument into this
+ * <code>StringBuilder</code>. If the sequence is null, the String
+ * "null" is used instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param sequence the <code>CharSequence</code> to insert
+ * @param start the starting index of the subsequence
+ * @param end one past the ending index of the subsequence
+ * @return this <code>StringBuilder</code>
+ * @throws IndexOutOfBoundsException if offset, start,
+ * or end are out of bounds
+ */
+ public StringBuilder insert(int offset, CharSequence sequence,
+ int start, int end)
+ {
+ super.insert(offset, sequence, start, end);
+ return this;
+ }
+
+ /**
+ * Insert the <code>char[]</code> argument into this
+ * <code>StringBuilder</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param data the <code>char[]</code> to insert
+ * @return this <code>StringBuilder</code>
+ * @throws NullPointerException if <code>data</code> is <code>null</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see #insert(int, char[], int, int)
+ */
+ public StringBuilder insert(int offset, char[] data)
+ {
+ super.insert(offset, data);
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param bool the <code>boolean</code> to convert and insert
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(boolean)
+ */
+ public StringBuilder insert(int offset, boolean bool)
+ {
+ super.insert(offset, bool);
+ return this;
+ }
+
+ /**
+ * Insert the <code>char</code> argument into this <code>StringBuilder</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param ch the <code>char</code> to insert
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ */
+ public StringBuilder insert(int offset, char ch)
+ {
+ super.insert(offset, ch);
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param inum the <code>int</code> to convert and insert
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(int)
+ */
+ public StringBuilder insert(int offset, int inum)
+ {
+ super.insert(offset, inum);
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param lnum the <code>long</code> to convert and insert
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(long)
+ */
+ public StringBuilder insert(int offset, long lnum)
+ {
+ super.insert(offset, lnum);
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param fnum the <code>float</code> to convert and insert
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(float)
+ */
+ public StringBuilder insert(int offset, float fnum)
+ {
+ super.insert(offset, fnum);
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param dnum the <code>double</code> to convert and insert
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(double)
+ */
+ public StringBuilder insert(int offset, double dnum)
+ {
+ super.insert(offset, dnum);
+ return this;
+ }
+
+ /**
+ * Reverse the characters in this StringBuilder. The same sequence of
+ * characters exists, but in the reverse index ordering.
+ *
+ * @return this <code>StringBuilder</code>
+ */
+ public StringBuilder reverse()
+ {
+ super.reverse();
+ return this;
+ }
+
+ /**
+ * Convert this <code>StringBuilder</code> to a <code>String</code>. The
+ * String is composed of the characters currently in this StringBuilder. Note
+ * that the result is a copy, and that future modifications to this buffer
+ * do not affect the String.
+ *
+ * @return the characters in this StringBuilder
+ */
+ public String toString()
+ {
+ return new String(this);
+ }
+
+}
diff --git a/libjava/java/lang/StringIndexOutOfBoundsException.h b/libjava/java/lang/StringIndexOutOfBoundsException.h
new file mode 100644
index 000000000..e3669a0d3
--- /dev/null
+++ b/libjava/java/lang/StringIndexOutOfBoundsException.h
@@ -0,0 +1,24 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_StringIndexOutOfBoundsException__
+#define __java_lang_StringIndexOutOfBoundsException__
+
+#pragma interface
+
+#include <java/lang/IndexOutOfBoundsException.h>
+
+class java::lang::StringIndexOutOfBoundsException : public ::java::lang::IndexOutOfBoundsException
+{
+
+public:
+ StringIndexOutOfBoundsException();
+ StringIndexOutOfBoundsException(::java::lang::String *);
+ StringIndexOutOfBoundsException(jint);
+private:
+ static const jlong serialVersionUID = -6762910422159637258LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_StringIndexOutOfBoundsException__
diff --git a/libjava/java/lang/SuppressWarnings.h b/libjava/java/lang/SuppressWarnings.h
new file mode 100644
index 000000000..3f28104d9
--- /dev/null
+++ b/libjava/java/lang/SuppressWarnings.h
@@ -0,0 +1,22 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_SuppressWarnings__
+#define __java_lang_SuppressWarnings__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::SuppressWarnings : public ::java::lang::Object
+{
+
+public:
+ virtual JArray< ::java::lang::String * > * value() = 0;
+ virtual ::java::lang::Class * annotationType() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_SuppressWarnings__
diff --git a/libjava/java/lang/System$EnvironmentCollection.h b/libjava/java/lang/System$EnvironmentCollection.h
new file mode 100644
index 000000000..8392e1782
--- /dev/null
+++ b/libjava/java/lang/System$EnvironmentCollection.h
@@ -0,0 +1,29 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_System$EnvironmentCollection__
+#define __java_lang_System$EnvironmentCollection__
+
+#pragma interface
+
+#include <java/util/AbstractCollection.h>
+
+class java::lang::System$EnvironmentCollection : public ::java::util::AbstractCollection
+{
+
+public:
+ System$EnvironmentCollection(::java::util::Collection *);
+ virtual jboolean contains(::java::lang::Object *);
+ virtual jboolean containsAll(::java::util::Collection *);
+ virtual ::java::util::Iterator * iterator();
+ virtual jboolean remove(::java::lang::Object *);
+ virtual jboolean removeAll(::java::util::Collection *);
+ virtual jboolean retainAll(::java::util::Collection *);
+ virtual jint size();
+public: // actually protected
+ ::java::util::Collection * __attribute__((aligned(__alignof__( ::java::util::AbstractCollection)))) c;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_System$EnvironmentCollection__
diff --git a/libjava/java/lang/System$EnvironmentMap.h b/libjava/java/lang/System$EnvironmentMap.h
new file mode 100644
index 000000000..c8ef8aade
--- /dev/null
+++ b/libjava/java/lang/System$EnvironmentMap.h
@@ -0,0 +1,37 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_System$EnvironmentMap__
+#define __java_lang_System$EnvironmentMap__
+
+#pragma interface
+
+#include <java/util/HashMap.h>
+
+class java::lang::System$EnvironmentMap : public ::java::util::HashMap
+{
+
+public: // actually package-private
+ System$EnvironmentMap();
+ System$EnvironmentMap(::java::util::Map *);
+public:
+ virtual jboolean containsKey(::java::lang::Object *);
+ virtual jboolean containsValue(::java::lang::Object *);
+ virtual ::java::util::Set * entrySet();
+ virtual ::java::lang::String * System$EnvironmentMap$get(::java::lang::Object *);
+ virtual ::java::util::Set * keySet();
+ virtual ::java::lang::String * System$EnvironmentMap$put(::java::lang::String *, ::java::lang::String *);
+ virtual ::java::lang::String * System$EnvironmentMap$remove(::java::lang::Object *);
+ virtual ::java::util::Collection * values();
+ virtual ::java::lang::Object * get(::java::lang::Object *);
+ virtual ::java::lang::Object * remove(::java::lang::Object *);
+ virtual ::java::lang::Object * put(::java::lang::Object *, ::java::lang::Object *);
+private:
+ ::java::util::Set * __attribute__((aligned(__alignof__( ::java::util::HashMap)))) entries;
+ ::java::util::Set * keys;
+ ::java::util::Collection * values__;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_System$EnvironmentMap__
diff --git a/libjava/java/lang/System$EnvironmentSet.h b/libjava/java/lang/System$EnvironmentSet.h
new file mode 100644
index 000000000..9a1e1a65d
--- /dev/null
+++ b/libjava/java/lang/System$EnvironmentSet.h
@@ -0,0 +1,21 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_System$EnvironmentSet__
+#define __java_lang_System$EnvironmentSet__
+
+#pragma interface
+
+#include <java/lang/System$EnvironmentCollection.h>
+
+class java::lang::System$EnvironmentSet : public ::java::lang::System$EnvironmentCollection
+{
+
+public:
+ System$EnvironmentSet(::java::util::Set *);
+ virtual jboolean equals(::java::lang::Object *);
+ virtual jint hashCode();
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_System$EnvironmentSet__
diff --git a/libjava/java/lang/System.h b/libjava/java/lang/System.h
new file mode 100644
index 000000000..8a67628b0
--- /dev/null
+++ b/libjava/java/lang/System.h
@@ -0,0 +1,70 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_System__
+#define __java_lang_System__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+extern "Java"
+{
+ namespace java
+ {
+ namespace nio
+ {
+ namespace channels
+ {
+ class Channel;
+ }
+ }
+ }
+}
+
+class java::lang::System : public ::java::lang::Object
+{
+
+ System();
+public:
+ static void setIn(::java::io::InputStream *);
+ static void setOut(::java::io::PrintStream *);
+ static void setErr(::java::io::PrintStream *);
+ static void setSecurityManager(::java::lang::SecurityManager *);
+ static ::java::lang::SecurityManager * getSecurityManager();
+ static jlong currentTimeMillis();
+ static jlong nanoTime();
+ static void arraycopy(::java::lang::Object *, jint, ::java::lang::Object *, jint, jint);
+ static jint identityHashCode(::java::lang::Object *);
+ static ::java::util::Properties * getProperties();
+ static void setProperties(::java::util::Properties *);
+ static ::java::lang::String * getProperty(::java::lang::String *);
+ static ::java::lang::String * getProperty(::java::lang::String *, ::java::lang::String *);
+ static ::java::lang::String * setProperty(::java::lang::String *, ::java::lang::String *);
+ static ::java::lang::String * clearProperty(::java::lang::String *);
+ static ::java::lang::String * getenv(::java::lang::String *);
+ static ::java::util::Map * getenv();
+ static void exit(jint);
+ static void gc();
+ static void runFinalization();
+ static void runFinalizersOnExit(jboolean);
+ static void load(::java::lang::String *);
+ static void loadLibrary(::java::lang::String *);
+ static ::java::lang::String * mapLibraryName(::java::lang::String *);
+private:
+ static void setIn0(::java::io::InputStream *);
+ static void setOut0(::java::io::PrintStream *);
+ static void setErr0(::java::io::PrintStream *);
+public: // actually package-private
+ static ::java::lang::String * getenv0(::java::lang::String *);
+public:
+ static ::java::nio::channels::Channel * inheritedChannel();
+ static ::java::io::InputStream * in;
+ static ::java::io::PrintStream * out;
+ static ::java::io::PrintStream * err;
+private:
+ static ::java::util::Map * environmentMap;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_System__
diff --git a/libjava/java/lang/System.java b/libjava/java/lang/System.java
new file mode 100644
index 000000000..ecfad2557
--- /dev/null
+++ b/libjava/java/lang/System.java
@@ -0,0 +1,1089 @@
+/* System.java -- useful methods to interface with the system
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang;
+
+import gnu.classpath.SystemProperties;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.nio.channels.Channel;
+import java.nio.channels.spi.SelectorProvider;
+import java.util.AbstractCollection;
+import java.util.ArrayList;
+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;
+
+/**
+ * System represents system-wide resources; things that represent the
+ * general environment. As such, all methods are static.
+ *
+ * @author John Keiser
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.0
+ * @status still missing 1.4 functionality
+ */
+public final class System
+{
+ // WARNING: System is a CORE class in the bootstrap cycle. See the comments
+ // in vm/reference/java/lang/Runtime for implications of this fact.
+
+ /**
+ * The standard InputStream. This is assigned at startup and starts its
+ * life perfectly valid. Although it is marked final, you can change it
+ * using {@link #setIn(InputStream)} through some hefty VM magic.
+ *
+ * <p>This corresponds to the C stdin and C++ cin variables, which
+ * typically input from the keyboard, but may be used to pipe input from
+ * other processes or files. That should all be transparent to you,
+ * however.
+ */
+ public static final InputStream in
+ = new BufferedInputStream(new FileInputStream(FileDescriptor.in));
+ /**
+ * The standard output PrintStream. This is assigned at startup and
+ * starts its life perfectly valid. Although it is marked final, you can
+ * change it using {@link #setOut(PrintStream)} through some hefty VM magic.
+ *
+ * <p>This corresponds to the C stdout and C++ cout variables, which
+ * typically output normal messages to the screen, but may be used to pipe
+ * output to other processes or files. That should all be transparent to
+ * you, however.
+ */
+ public static final PrintStream out
+ = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)), true);
+ /**
+ * The standard output PrintStream. This is assigned at startup and
+ * starts its life perfectly valid. Although it is marked final, you can
+ * change it using {@link #setErr(PrintStream)} through some hefty VM magic.
+ *
+ * <p>This corresponds to the C stderr and C++ cerr variables, which
+ * typically output error messages to the screen, but may be used to pipe
+ * output to other processes or files. That should all be transparent to
+ * you, however.
+ */
+ public static final PrintStream err
+ = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.err)), true);
+
+ /**
+ * A cached copy of the environment variable map.
+ */
+ private static Map<String,String> environmentMap;
+
+ /**
+ * This class is uninstantiable.
+ */
+ private System()
+ {
+ }
+
+ /**
+ * Set {@link #in} to a new InputStream. This uses some VM magic to change
+ * a "final" variable, so naturally there is a security check,
+ * <code>RuntimePermission("setIO")</code>.
+ *
+ * @param in the new InputStream
+ * @throws SecurityException if permission is denied
+ * @since 1.1
+ */
+ public static void setIn(InputStream in)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("setIO"));
+ setIn0(in);
+ }
+
+ /**
+ * Set {@link #out} to a new PrintStream. This uses some VM magic to change
+ * a "final" variable, so naturally there is a security check,
+ * <code>RuntimePermission("setIO")</code>.
+ *
+ * @param out the new PrintStream
+ * @throws SecurityException if permission is denied
+ * @since 1.1
+ */
+ public static void setOut(PrintStream out)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("setIO"));
+
+ setOut0(out);
+ }
+
+ /**
+ * Set {@link #err} to a new PrintStream. This uses some VM magic to change
+ * a "final" variable, so naturally there is a security check,
+ * <code>RuntimePermission("setIO")</code>.
+ *
+ * @param err the new PrintStream
+ * @throws SecurityException if permission is denied
+ * @since 1.1
+ */
+ public static void setErr(PrintStream err)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("setIO"));
+ setErr0(err);
+ }
+
+ /**
+ * Set the current SecurityManager. If a security manager already exists,
+ * then <code>RuntimePermission("setSecurityManager")</code> is checked
+ * first. Since this permission is denied by the default security manager,
+ * setting the security manager is often an irreversible action.
+ *
+ * @param sm the new SecurityManager
+ * @throws SecurityException if permission is denied
+ */
+ public static synchronized void setSecurityManager(SecurityManager sm)
+ {
+ // Implementation note: the field lives in SecurityManager because of
+ // bootstrap initialization issues. This method is synchronized so that
+ // no other thread changes it to null before this thread makes the change.
+ if (SecurityManager.current != null)
+ SecurityManager.current.checkPermission
+ (new RuntimePermission("setSecurityManager"));
+ SecurityManager.current = sm;
+ }
+
+ /**
+ * Get the current SecurityManager. If the SecurityManager has not been
+ * set yet, then this method returns null.
+ *
+ * @return the current SecurityManager, or null
+ */
+ public static SecurityManager getSecurityManager()
+ {
+ return SecurityManager.current;
+ }
+
+ /**
+ * Get the current time, measured in the number of milliseconds from the
+ * beginning of Jan. 1, 1970. This is gathered from the system clock, with
+ * any attendant incorrectness (it may be timezone dependent).
+ *
+ * @return the current time
+ * @see java.util.Date
+ */
+ public static native long currentTimeMillis();
+
+ /**
+ * Get the current time, measured in nanoseconds. The result is as
+ * precise as possible, and is measured against a fixed epoch.
+ * However, unlike currentTimeMillis(), the epoch chosen is
+ * arbitrary and may vary by platform, etc.
+ * @since 1.5
+ */
+ public static native long nanoTime();
+
+ /**
+ * Copy one array onto another from <code>src[srcStart]</code> ...
+ * <code>src[srcStart+len-1]</code> to <code>dest[destStart]</code> ...
+ * <code>dest[destStart+len-1]</code>. First, the arguments are validated:
+ * neither array may be null, they must be of compatible types, and the
+ * start and length must fit within both arrays. Then the copying starts,
+ * and proceeds through increasing slots. If src and dest are the same
+ * array, this will appear to copy the data to a temporary location first.
+ * An ArrayStoreException in the middle of copying will leave earlier
+ * elements copied, but later elements unchanged.
+ *
+ * @param src the array to copy elements from
+ * @param srcStart the starting position in src
+ * @param dest the array to copy elements to
+ * @param destStart the starting position in dest
+ * @param len the number of elements to copy
+ * @throws NullPointerException if src or dest is null
+ * @throws ArrayStoreException if src or dest is not an array, if they are
+ * not compatible array types, or if an incompatible runtime type
+ * is stored in dest
+ * @throws IndexOutOfBoundsException if len is negative, or if the start or
+ * end copy position in either array is out of bounds
+ */
+ public static native void arraycopy(Object src, int srcStart,
+ Object dest, int destStart, int len);
+
+ /**
+ * Get a hash code computed by the VM for the Object. This hash code will
+ * be the same as Object's hashCode() method. It is usually some
+ * convolution of the pointer to the Object internal to the VM. It
+ * follows standard hash code rules, in that it will remain the same for a
+ * given Object for the lifetime of that Object.
+ *
+ * @param o the Object to get the hash code for
+ * @return the VM-dependent hash code for this Object
+ * @since 1.1
+ */
+ public static native int identityHashCode(Object o);
+
+ /**
+ * Get all the system properties at once. A security check may be performed,
+ * <code>checkPropertiesAccess</code>. Note that a security manager may
+ * allow getting a single property, but not the entire group.
+ *
+ * <p>The required properties include:
+ * <dl>
+ * <dt>java.version</dt> <dd>Java version number</dd>
+ * <dt>java.vendor</dt> <dd>Java vendor specific string</dd>
+ * <dt>java.vendor.url</dt> <dd>Java vendor URL</dd>
+ * <dt>java.home</dt> <dd>Java installation directory</dd>
+ * <dt>java.vm.specification.version</dt> <dd>VM Spec version</dd>
+ * <dt>java.vm.specification.vendor</dt> <dd>VM Spec vendor</dd>
+ * <dt>java.vm.specification.name</dt> <dd>VM Spec name</dd>
+ * <dt>java.vm.version</dt> <dd>VM implementation version</dd>
+ * <dt>java.vm.vendor</dt> <dd>VM implementation vendor</dd>
+ * <dt>java.vm.name</dt> <dd>VM implementation name</dd>
+ * <dt>java.specification.version</dt> <dd>Java Runtime Environment version</dd>
+ * <dt>java.specification.vendor</dt> <dd>Java Runtime Environment vendor</dd>
+ * <dt>java.specification.name</dt> <dd>Java Runtime Environment name</dd>
+ * <dt>java.class.version</dt> <dd>Java class version number</dd>
+ * <dt>java.class.path</dt> <dd>Java classpath</dd>
+ * <dt>java.library.path</dt> <dd>Path for finding Java libraries</dd>
+ * <dt>java.io.tmpdir</dt> <dd>Default temp file path</dd>
+ * <dt>java.compiler</dt> <dd>Name of JIT to use</dd>
+ * <dt>java.ext.dirs</dt> <dd>Java extension path</dd>
+ * <dt>os.name</dt> <dd>Operating System Name</dd>
+ * <dt>os.arch</dt> <dd>Operating System Architecture</dd>
+ * <dt>os.version</dt> <dd>Operating System Version</dd>
+ * <dt>file.separator</dt> <dd>File separator ("/" on Unix)</dd>
+ * <dt>path.separator</dt> <dd>Path separator (":" on Unix)</dd>
+ * <dt>line.separator</dt> <dd>Line separator ("\n" on Unix)</dd>
+ * <dt>user.name</dt> <dd>User account name</dd>
+ * <dt>user.home</dt> <dd>User home directory</dd>
+ * <dt>user.dir</dt> <dd>User's current working directory</dd>
+ * </dl>
+ *
+ * In addition, gnu defines several other properties, where ? stands for
+ * each character in '0' through '9':
+ * <dl>
+ * <dt>gnu.classpath.home</dt> <dd>Path to the classpath libraries.</dd>
+ * <dt>gnu.classpath.version</dt> <dd>Version of the classpath libraries.</dd>
+ * <dt>gnu.classpath.vm.shortname</dt> <dd>Succinct version of the VM name;
+ * used for finding property files in file system</dd>
+ * <dt>gnu.classpath.home.url</dt> <dd> Base URL; used for finding
+ * property files in file system</dd>
+ * <dt>gnu.cpu.endian</dt> <dd>big or little</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.ISO-8859-?</dt> <dd>8859_?</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.iso-8859-?</dt> <dd>8859_?</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.iso8859_?</dt> <dd>8859_?</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.iso-latin-_?</dt> <dd>8859_?</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.latin?</dt> <dd>8859_?</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.UTF-8</dt> <dd>UTF8</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.utf-8</dt> <dd>UTF8</dd>
+ * <dt>gnu.java.util.zoneinfo.dir</dt> <dd>Root of zoneinfo tree</dd>
+ * </dl>
+ *
+ * @return the system properties, will never be null
+ * @throws SecurityException if permission is denied
+ */
+ public static Properties getProperties()
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPropertiesAccess();
+ return SystemProperties.getProperties();
+ }
+
+ /**
+ * Set all the system properties at once. A security check may be performed,
+ * <code>checkPropertiesAccess</code>. Note that a security manager may
+ * allow setting a single property, but not the entire group. An argument
+ * of null resets the properties to the startup default.
+ *
+ * @param properties the new set of system properties
+ * @throws SecurityException if permission is denied
+ */
+ public static void setProperties(Properties properties)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPropertiesAccess();
+ SystemProperties.setProperties(properties);
+ }
+
+ /**
+ * Get a single system property by name. A security check may be performed,
+ * <code>checkPropertyAccess(key)</code>.
+ *
+ * @param key the name of the system property to get
+ * @return the property, or null if not found
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if key is null
+ * @throws IllegalArgumentException if key is ""
+ */
+ public static String getProperty(String key)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPropertyAccess(key);
+ else if (key.length() == 0)
+ throw new IllegalArgumentException("key can't be empty");
+ return SystemProperties.getProperty(key);
+ }
+
+ /**
+ * Get a single system property by name. A security check may be performed,
+ * <code>checkPropertyAccess(key)</code>.
+ *
+ * @param key the name of the system property to get
+ * @param def the default
+ * @return the property, or def if not found
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if key is null
+ * @throws IllegalArgumentException if key is ""
+ */
+ public static String getProperty(String key, String def)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPropertyAccess(key);
+ return SystemProperties.getProperty(key, def);
+ }
+
+ /**
+ * Set a single system property by name. A security check may be performed,
+ * <code>checkPropertyAccess(key, "write")</code>.
+ *
+ * @param key the name of the system property to set
+ * @param value the new value
+ * @return the previous value, or null
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if key is null
+ * @throws IllegalArgumentException if key is ""
+ * @since 1.2
+ */
+ public static String setProperty(String key, String value)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new PropertyPermission(key, "write"));
+ return SystemProperties.setProperty(key, value);
+ }
+
+ /**
+ * Remove a single system property by name. A security check may be
+ * performed, <code>checkPropertyAccess(key, "write")</code>.
+ *
+ * @param key the name of the system property to remove
+ * @return the previous value, or null
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if key is null
+ * @throws IllegalArgumentException if key is ""
+ * @since 1.5
+ */
+ public static String clearProperty(String key)
+ {
+ 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.remove(key);
+ }
+
+ /**
+ * Gets the value of an environment variable.
+ *
+ * @param name the name of the environment variable
+ * @return the string value of the variable or null when the
+ * environment variable is not defined.
+ * @throws NullPointerException
+ * @throws SecurityException if permission is denied
+ * @since 1.5
+ * @specnote This method was deprecated in some JDK releases, but
+ * was restored in 1.5.
+ */
+ public static String getenv(String name)
+ {
+ if (name == null)
+ throw new NullPointerException();
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("getenv." + name));
+ return getenv0(name);
+ }
+
+ /**
+ * <p>
+ * Returns an unmodifiable view of the system environment variables.
+ * If the underlying system does not support environment variables,
+ * an empty map is returned.
+ * </p>
+ * <p>
+ * The returned map is read-only and does not accept queries using
+ * null keys or values, or those of a type other than <code>String</code>.
+ * Attempts to modify the map will throw an
+ * <code>UnsupportedOperationException</code>, while attempts
+ * to pass in a null value will throw a
+ * <code>NullPointerException</code>. Types other than <code>String</code>
+ * throw a <code>ClassCastException</code>.
+ * </p>
+ * <p>
+ * As the returned map is generated using data from the underlying
+ * platform, it may not comply with the <code>equals()</code>
+ * and <code>hashCode()</code> contracts. It is also likely that
+ * the keys of this map will be case-sensitive.
+ * </p>
+ * <p>
+ * Use of this method may require a security check for the
+ * RuntimePermission "getenv.*".
+ * </p>
+ *
+ * @return a map of the system environment variables.
+ * @throws SecurityException if the checkPermission method of
+ * an installed security manager prevents access to
+ * the system environment variables.
+ * @since 1.5
+ */
+ public static Map<String, String> getenv()
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("getenv.*"));
+ if (environmentMap == null)
+ {
+ // List<String> environ = (List<String>)VMSystem.environ();
+ // FIXME
+ List<String> environ = new ArrayList<String>();
+ Map<String,String> variables = new EnvironmentMap();
+ for (String pair : environ)
+ {
+ String[] parts = pair.split("=");
+ variables.put(parts[0], parts[1]);
+ }
+ environmentMap = Collections.unmodifiableMap(variables);
+ }
+ return environmentMap;
+ }
+
+ /**
+ * Terminate the Virtual Machine. This just calls
+ * <code>Runtime.getRuntime().exit(status)</code>, and never returns.
+ * Obviously, a security check is in order, <code>checkExit</code>.
+ *
+ * @param status the exit status; by convention non-zero is abnormal
+ * @throws SecurityException if permission is denied
+ * @see Runtime#exit(int)
+ */
+ public static void exit(int status)
+ {
+ Runtime.getRuntime().exit(status);
+ }
+
+ /**
+ * Calls the garbage collector. This is only a hint, and it is up to the
+ * implementation what this hint suggests, but it usually causes a
+ * best-effort attempt to reclaim unused memory from discarded objects.
+ * This calls <code>Runtime.getRuntime().gc()</code>.
+ *
+ * @see Runtime#gc()
+ */
+ public static void gc()
+ {
+ Runtime.getRuntime().gc();
+ }
+
+ /**
+ * Runs object finalization on pending objects. This is only a hint, and
+ * it is up to the implementation what this hint suggests, but it usually
+ * causes a best-effort attempt to run finalizers on all objects ready
+ * to be reclaimed. This calls
+ * <code>Runtime.getRuntime().runFinalization()</code>.
+ *
+ * @see Runtime#runFinalization()
+ */
+ public static void runFinalization()
+ {
+ Runtime.getRuntime().runFinalization();
+ }
+
+ /**
+ * Tell the Runtime whether to run finalization before exiting the
+ * JVM. This is inherently unsafe in multi-threaded applications,
+ * since it can force initialization on objects which are still in use
+ * by live threads, leading to deadlock; therefore this is disabled by
+ * default. There may be a security check, <code>checkExit(0)</code>. This
+ * calls <code>Runtime.getRuntime().runFinalizersOnExit()</code>.
+ *
+ * @param finalizeOnExit whether to run finalizers on exit
+ * @throws SecurityException if permission is denied
+ * @see Runtime#runFinalizersOnExit()
+ * @since 1.1
+ * @deprecated never rely on finalizers to do a clean, thread-safe,
+ * mop-up from your code
+ */
+ public static void runFinalizersOnExit(boolean finalizeOnExit)
+ {
+ Runtime.getRuntime().runFinalizersOnExit(finalizeOnExit);
+ }
+
+ /**
+ * Load a code file using its explicit system-dependent filename. A security
+ * check may be performed, <code>checkLink</code>. This just calls
+ * <code>Runtime.getRuntime().load(filename)</code>.
+ *
+ * <p>
+ * The library is loaded using the class loader associated with the
+ * class associated with the invoking method.
+ *
+ * @param filename the code file to load
+ * @throws SecurityException if permission is denied
+ * @throws UnsatisfiedLinkError if the file cannot be loaded
+ * @see Runtime#load(String)
+ */
+ public static void load(String filename)
+ {
+ Runtime.getRuntime().load(filename);
+ }
+
+ /**
+ * Load a library using its explicit system-dependent filename. A security
+ * check may be performed, <code>checkLink</code>. This just calls
+ * <code>Runtime.getRuntime().load(filename)</code>.
+ *
+ * <p>
+ * The library is loaded using the class loader associated with the
+ * class associated with the invoking method.
+ *
+ * @param libname the library file to load
+ * @throws SecurityException if permission is denied
+ * @throws UnsatisfiedLinkError if the file cannot be loaded
+ * @see Runtime#load(String)
+ */
+ public static void loadLibrary(String libname)
+ {
+ Runtime.getRuntime().loadLibrary(libname);
+ }
+
+ /**
+ * Convert a library name to its platform-specific variant.
+ *
+ * @param libname the library name, as used in <code>loadLibrary</code>
+ * @return the platform-specific mangling of the name
+ * @since 1.2
+ */
+ public static String mapLibraryName(String libname)
+ {
+ // XXX Fix this!!!!
+ return Runtime.nativeGetLibname("", libname);
+ }
+
+ /**
+ * Set {@link #in} to a new InputStream.
+ *
+ * @param in the new InputStream
+ * @see #setIn(InputStream)
+ */
+ private static native void setIn0(InputStream in);
+
+ /**
+ * Set {@link #out} to a new PrintStream.
+ *
+ * @param out the new PrintStream
+ * @see #setOut(PrintStream)
+ */
+ private static native void setOut0(PrintStream out);
+
+ /**
+ * Set {@link #err} to a new PrintStream.
+ *
+ * @param err the new PrintStream
+ * @see #setErr(PrintStream)
+ */
+ private static native void setErr0(PrintStream err);
+
+ /**
+ * Gets the value of an environment variable.
+ *
+ * @see #getenv(String)
+ */
+ static native String getenv0(String name);
+
+ /**
+ * Returns the inherited channel of the VM.
+ *
+ * This wraps the inheritedChannel() call of the system's default
+ * {@link SelectorProvider}.
+ *
+ * @return the inherited channel of the VM
+ *
+ * @throws IOException If an I/O error occurs
+ * @throws SecurityException If an installed security manager denies access
+ * to RuntimePermission("inheritedChannel")
+ *
+ * @since 1.5
+ */
+ public static Channel inheritedChannel()
+ throws IOException
+ {
+ return SelectorProvider.provider().inheritedChannel();
+ }
+
+ /**
+ * This is a specialised <code>Collection</code>, providing
+ * the necessary provisions for the collections used by the
+ * environment variable map. Namely, it prevents
+ * querying anything but <code>String</code>s.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+ private static class EnvironmentCollection
+ extends AbstractCollection<String>
+ {
+
+ /**
+ * The wrapped collection.
+ */
+ protected Collection<String> c;
+
+ /**
+ * Constructs a new environment collection, which
+ * wraps the elements of the supplied collection.
+ *
+ * @param coll the collection to use as a base for
+ * this collection.
+ */
+ public EnvironmentCollection(Collection<String> coll)
+ {
+ c = coll;
+ }
+
+ /**
+ * Blocks queries containing a null object or an object which
+ * isn't of type <code>String</code>. All other queries
+ * are forwarded to the underlying collection.
+ *
+ * @param obj the object to look for.
+ * @return true if the object exists in the collection.
+ * @throws NullPointerException if the specified object is null.
+ * @throws ClassCastException if the specified object is not a String.
+ */
+ public boolean contains(Object obj)
+ {
+ if (obj == null)
+ throw new
+ NullPointerException("This collection does not support " +
+ "null values.");
+ if (!(obj instanceof String))
+ throw new
+ ClassCastException("This collection only supports Strings.");
+ return c.contains(obj);
+ }
+
+ /**
+ * Blocks queries where the collection contains a null object or
+ * an object which isn't of type <code>String</code>. All other
+ * queries are forwarded to the underlying collection.
+ *
+ * @param coll the collection of objects to look for.
+ * @return true if the collection contains all elements in the collection.
+ * @throws NullPointerException if the collection is null.
+ * @throws NullPointerException if any collection entry is null.
+ * @throws ClassCastException if any collection entry is not a String.
+ */
+ public boolean containsAll(Collection<?> coll)
+ {
+ for (Object o: coll)
+ {
+ if (o == null)
+ throw new
+ NullPointerException("This collection does not support " +
+ "null values.");
+ if (!(o instanceof String))
+ throw new
+ ClassCastException("This collection only supports Strings.");
+ }
+ return c.containsAll(coll);
+ }
+
+ /**
+ * This returns an iterator over the map elements, with the
+ * same provisions as for the collection and underlying map.
+ *
+ * @return an iterator over the map elements.
+ */
+ public Iterator<String> iterator()
+ {
+ return c.iterator();
+ }
+
+ /**
+ * Blocks the removal of elements from the collection.
+ *
+ * @return true if the removal was sucessful.
+ * @throws NullPointerException if the collection is null.
+ * @throws NullPointerException if any collection entry is null.
+ * @throws ClassCastException if any collection entry is not a String.
+ */
+ public boolean remove(Object key)
+ {
+ if (key == null)
+ throw new
+ NullPointerException("This collection does not support " +
+ "null values.");
+ if (!(key instanceof String))
+ throw new
+ ClassCastException("This collection only supports Strings.");
+ return c.contains(key);
+ }
+
+ /**
+ * Blocks the removal of all elements in the specified
+ * collection from the collection.
+ *
+ * @param coll the collection of elements to remove.
+ * @return true if the elements were removed.
+ * @throws NullPointerException if the collection is null.
+ * @throws NullPointerException if any collection entry is null.
+ * @throws ClassCastException if any collection entry is not a String.
+ */
+ public boolean removeAll(Collection<?> coll)
+ {
+ for (Object o: coll)
+ {
+ if (o == null)
+ throw new
+ NullPointerException("This collection does not support " +
+ "null values.");
+ if (!(o instanceof String))
+ throw new
+ ClassCastException("This collection only supports Strings.");
+ }
+ return c.removeAll(coll);
+ }
+
+ /**
+ * Blocks the retention of all elements in the specified
+ * collection from the collection.
+ *
+ * @param c the collection of elements to retain.
+ * @return true if the other elements were removed.
+ * @throws NullPointerException if the collection is null.
+ * @throws NullPointerException if any collection entry is null.
+ * @throws ClassCastException if any collection entry is not a String.
+ */
+ public boolean retainAll(Collection<?> coll)
+ {
+ for (Object o: coll)
+ {
+ if (o == null)
+ throw new
+ NullPointerException("This collection does not support " +
+ "null values.");
+ if (!(o instanceof String))
+ throw new
+ ClassCastException("This collection only supports Strings.");
+ }
+ return c.containsAll(coll);
+ }
+
+ /**
+ * This simply calls the same method on the wrapped
+ * collection.
+ *
+ * @return the size of the underlying collection.
+ */
+ public int size()
+ {
+ return c.size();
+ }
+
+ } // class EnvironmentCollection<String>
+
+ /**
+ * This is a specialised <code>HashMap</code>, which
+ * prevents the addition or querying of anything other than
+ * <code>String</code> objects.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+ static class EnvironmentMap
+ extends HashMap<String,String>
+ {
+
+ /**
+ * Cache the entry set.
+ */
+ private transient Set<Map.Entry<String,String>> entries;
+
+ /**
+ * Cache the key set.
+ */
+ private transient Set<String> keys;
+
+ /**
+ * Cache the value collection.
+ */
+ private transient Collection<String> values;
+
+ /**
+ * Constructs a new empty <code>EnvironmentMap</code>.
+ */
+ EnvironmentMap()
+ {
+ super();
+ }
+
+ /**
+ * Constructs a new <code>EnvironmentMap</code> containing
+ * the contents of the specified map.
+ *
+ * @param m the map to be added to this.
+ * @throws NullPointerException if a key or value is null.
+ * @throws ClassCastException if a key or value is not a String.
+ */
+ EnvironmentMap(Map<String,String> m)
+ {
+ super(m);
+ }
+
+ /**
+ * Blocks queries containing a null key or one which is not
+ * of type <code>String</code>. All other queries
+ * are forwarded to the superclass.
+ *
+ * @param key the key to look for in the map.
+ * @return true if the key exists in the map.
+ * @throws NullPointerException if the specified key is null.
+ */
+ public boolean containsKey(Object key)
+ {
+ if (key == null)
+ throw new
+ NullPointerException("This map does not support null keys.");
+ if (!(key instanceof String))
+ throw new
+ ClassCastException("This map only allows queries using Strings.");
+ return super.containsKey(key);
+ }
+
+ /**
+ * Blocks queries using a null or non-<code>String</code> value.
+ * All other queries are forwarded to the superclass.
+ *
+ * @param value the value to look for in the map.
+ * @return true if the value exists in the map.
+ * @throws NullPointerException if the specified value is null.
+ */
+ public boolean containsValue(Object value)
+ {
+ if (value == null)
+ throw new
+ NullPointerException("This map does not support null values.");
+ if (!(value instanceof String))
+ throw new
+ ClassCastException("This map only allows queries using Strings.");
+ return super.containsValue(value);
+ }
+
+ /**
+ * Returns a set view of the map entries, with the same
+ * provisions as for the underlying map.
+ *
+ * @return a set containing the map entries.
+ */
+ public Set<Map.Entry<String,String>> entrySet()
+ {
+ if (entries == null)
+ entries = super.entrySet();
+ return entries;
+ }
+
+ /**
+ * Blocks queries containing a null or non-<code>String</code> key.
+ * All other queries are passed on to the superclass.
+ *
+ * @param key the key to retrieve the value for.
+ * @return the value associated with the given key.
+ * @throws NullPointerException if the specified key is null.
+ * @throws ClassCastException if the specified key is not a String.
+ */
+ public String get(Object key)
+ {
+ if (key == null)
+ throw new
+ NullPointerException("This map does not support null keys.");
+ if (!(key instanceof String))
+ throw new
+ ClassCastException("This map only allows queries using Strings.");
+ return super.get(key);
+ }
+
+ /**
+ * Returns a set view of the keys, with the same
+ * provisions as for the underlying map.
+ *
+ * @return a set containing the keys.
+ */
+ public Set<String> keySet()
+ {
+ if (keys == null)
+ keys = new EnvironmentSet(super.keySet());
+ return keys;
+ }
+
+ /**
+ * Associates the given key to the given value. If the
+ * map already contains the key, its value is replaced.
+ * The map does not accept null keys or values, or keys
+ * and values not of type {@link String}.
+ *
+ * @param key the key to map.
+ * @param value the value to be mapped.
+ * @return the previous value of the key, or null if there was no mapping
+ * @throws NullPointerException if a key or value is null.
+ * @throws ClassCastException if a key or value is not a String.
+ */
+ public String put(String key, String value)
+ {
+ if (key == null)
+ throw new NullPointerException("A new key is null.");
+ if (value == null)
+ throw new NullPointerException("A new value is null.");
+ if (!(key instanceof String))
+ throw new ClassCastException("A new key is not a String.");
+ if (!(value instanceof String))
+ throw new ClassCastException("A new value is not a String.");
+ return super.put(key, value);
+ }
+
+ /**
+ * Removes a key-value pair from the map. The queried key may not
+ * be null or of a type other than a <code>String</code>.
+ *
+ * @param key the key of the entry to remove.
+ * @return the removed value.
+ * @throws NullPointerException if the specified key is null.
+ * @throws ClassCastException if the specified key is not a String.
+ */
+ public String remove(Object key)
+ {
+ if (key == null)
+ throw new
+ NullPointerException("This map does not support null keys.");
+ if (!(key instanceof String))
+ throw new
+ ClassCastException("This map only allows queries using Strings.");
+ return super.remove(key);
+ }
+
+ /**
+ * Returns a collection view of the values, with the same
+ * provisions as for the underlying map.
+ *
+ * @return a collection containing the values.
+ */
+ public Collection<String> values()
+ {
+ if (values == null)
+ values = new EnvironmentCollection(super.values());
+ return values;
+ }
+
+ }
+
+ /**
+ * This is a specialised <code>Set</code>, providing
+ * the necessary provisions for the collections used by the
+ * environment variable map. Namely, it prevents
+ * modifications and the use of queries with null
+ * or non-<code>String</code> values.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+ private static class EnvironmentSet
+ extends EnvironmentCollection
+ implements Set<String>
+ {
+
+ /**
+ * Constructs a new environment set, which
+ * wraps the elements of the supplied set.
+ *
+ * @param set the set to use as a base for
+ * this set.
+ */
+ public EnvironmentSet(Set<String> set)
+ {
+ super(set);
+ }
+
+ /**
+ * This simply calls the same method on the wrapped
+ * collection.
+ *
+ * @param obj the object to compare with.
+ * @return true if the two objects are equal.
+ */
+ public boolean equals(Object obj)
+ {
+ return c.equals(obj);
+ }
+
+ /**
+ * This simply calls the same method on the wrapped
+ * collection.
+ *
+ * @return the hashcode of the collection.
+ */
+ public int hashCode()
+ {
+ return c.hashCode();
+ }
+
+ } // class EnvironmentSet<String>
+
+} // class System
diff --git a/libjava/java/lang/Thread$State.h b/libjava/java/lang/Thread$State.h
new file mode 100644
index 000000000..4620c7224
--- /dev/null
+++ b/libjava/java/lang/Thread$State.h
@@ -0,0 +1,32 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Thread$State__
+#define __java_lang_Thread$State__
+
+#pragma interface
+
+#include <java/lang/Enum.h>
+#include <gcj/array.h>
+
+
+class java::lang::Thread$State : public ::java::lang::Enum
+{
+
+ Thread$State(::java::lang::String *, jint);
+public:
+ static JArray< ::java::lang::Thread$State * > * values();
+ static ::java::lang::Thread$State * valueOf(::java::lang::String *);
+ static ::java::lang::Thread$State * BLOCKED;
+ static ::java::lang::Thread$State * NEW;
+ static ::java::lang::Thread$State * RUNNABLE;
+ static ::java::lang::Thread$State * TERMINATED;
+ static ::java::lang::Thread$State * TIMED_WAITING;
+ static ::java::lang::Thread$State * WAITING;
+private:
+ static JArray< ::java::lang::Thread$State * > * ENUM$VALUES;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Thread$State__
diff --git a/libjava/java/lang/Thread$UncaughtExceptionHandler.h b/libjava/java/lang/Thread$UncaughtExceptionHandler.h
new file mode 100644
index 000000000..88d2b5b90
--- /dev/null
+++ b/libjava/java/lang/Thread$UncaughtExceptionHandler.h
@@ -0,0 +1,19 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Thread$UncaughtExceptionHandler__
+#define __java_lang_Thread$UncaughtExceptionHandler__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Thread$UncaughtExceptionHandler : public ::java::lang::Object
+{
+
+public:
+ virtual void uncaughtException(::java::lang::Thread *, ::java::lang::Throwable *) = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_Thread$UncaughtExceptionHandler__
diff --git a/libjava/java/lang/Thread.h b/libjava/java/lang/Thread.h
new file mode 100644
index 000000000..54764c83c
--- /dev/null
+++ b/libjava/java/lang/Thread.h
@@ -0,0 +1,157 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Thread__
+#define __java_lang_Thread__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ class RawData;
+ class RawDataManaged;
+ }
+ }
+}
+
+class _Jv_JNIEnv;
+#define _JV_NOT_OWNER 1
+#define _JV_INTERRUPTED 2
+_Jv_JNIEnv * _Jv_GetCurrentJNIEnv ();
+void _Jv_SetCurrentJNIEnv (_Jv_JNIEnv *env);
+void _Jv_ThreadRun (java::lang::Thread* thread);
+jint _Jv_AttachCurrentThread(java::lang::Thread* thread);
+java::lang::Thread* _Jv_AttachCurrentThread (jstring name, java::lang::ThreadGroup* group);
+java::lang::Thread* _Jv_AttachCurrentThreadAsDaemon (jstring name, java::lang::ThreadGroup* group);
+jint _Jv_DetachCurrentThread ();
+struct _Jv_Thread_t;
+_Jv_Thread_t* _Jv_ThreadGetData (java::lang::Thread* thread);
+
+class java::lang::Thread : public ::java::lang::Object
+{
+
+public:
+ Thread();
+ Thread(::java::lang::Runnable *);
+ Thread(::java::lang::String *);
+ Thread(::java::lang::ThreadGroup *, ::java::lang::Runnable *);
+ Thread(::java::lang::ThreadGroup *, ::java::lang::String *);
+ Thread(::java::lang::Runnable *, ::java::lang::String *);
+ Thread(::java::lang::ThreadGroup *, ::java::lang::Runnable *, ::java::lang::String *);
+ Thread(::java::lang::ThreadGroup *, ::java::lang::Runnable *, ::java::lang::String *, jlong);
+public: // actually package-private
+ Thread(::java::lang::String *, jboolean);
+private:
+ Thread(::java::lang::Thread *, ::java::lang::ThreadGroup *, ::java::lang::Runnable *, ::java::lang::String *, jboolean);
+public:
+ static jint activeCount();
+ virtual void checkAccess();
+ virtual jint countStackFrames();
+ static ::java::lang::Thread * currentThread();
+ virtual void destroy();
+ static void dumpStack();
+ static jint enumerate(JArray< ::java::lang::Thread * > *);
+ virtual ::java::lang::String * getName();
+ virtual jint getPriority();
+ virtual ::java::lang::ThreadGroup * getThreadGroup();
+ static jboolean holdsLock(::java::lang::Object *);
+ virtual void interrupt();
+ static jboolean interrupted();
+ virtual jboolean isInterrupted();
+ virtual jboolean isAlive();
+ virtual jboolean isDaemon();
+ virtual void join();
+ virtual void join(jlong);
+ virtual void join(jlong, jint);
+ virtual void resume();
+private:
+ void finish_();
+ jboolean isInterrupted(jboolean);
+public:
+ virtual void run();
+ virtual void setDaemon(jboolean);
+ virtual ::java::lang::ClassLoader * getContextClassLoader();
+ virtual void setContextClassLoader(::java::lang::ClassLoader *);
+ virtual void setName(::java::lang::String *);
+ static void yield();
+ static void sleep(jlong);
+ static void sleep(jlong, jint);
+ virtual void start();
+ virtual void stop();
+ virtual void stop(::java::lang::Throwable *);
+ virtual void suspend();
+ virtual void setPriority(jint);
+ virtual ::java::lang::String * toString();
+private:
+ void initialize_native();
+ static ::java::lang::String * gen_name();
+public: // actually package-private
+ static ::java::lang::ThreadLocalMap * getThreadLocals();
+public:
+ virtual void setUncaughtExceptionHandler(::java::lang::Thread$UncaughtExceptionHandler *);
+ virtual ::java::lang::Thread$UncaughtExceptionHandler * getUncaughtExceptionHandler();
+ static void setDefaultUncaughtExceptionHandler(::java::lang::Thread$UncaughtExceptionHandler *);
+ static ::java::lang::Thread$UncaughtExceptionHandler * getDefaultUncaughtExceptionHandler();
+ virtual jlong getId();
+ virtual ::java::lang::Thread$State * getState();
+ static ::java::util::Map * getAllStackTraces();
+ virtual JArray< ::java::lang::StackTraceElement * > * getStackTrace();
+ static const jint MIN_PRIORITY = 1;
+ static const jint NORM_PRIORITY = 5;
+ static const jint MAX_PRIORITY = 10;
+public: // actually package-private
+ ::java::lang::ThreadGroup * __attribute__((aligned(__alignof__( ::java::lang::Object)))) group;
+private:
+ ::java::lang::Runnable * runnable;
+public: // actually package-private
+ ::java::lang::String * name;
+private:
+ jboolean daemon;
+ jint priority;
+public: // actually package-private
+ jboolean interrupt_flag;
+private:
+ static const jbyte THREAD_DEAD = 0;
+ static const jbyte THREAD_ALIVE = 1;
+ static const jbyte THREAD_SIGNALED = 2;
+ jboolean startable_flag;
+ ::java::lang::ClassLoader * contextClassLoader;
+ jlong threadId;
+ static jlong nextThreadId;
+ static jlong totalThreadsCreated;
+ static ::java::lang::Thread$UncaughtExceptionHandler * defaultHandler;
+public: // actually package-private
+ ::java::lang::ThreadLocalMap * locals;
+ ::java::lang::Thread$UncaughtExceptionHandler * exceptionHandler;
+private:
+ ::java::lang::Object * parkBlocker;
+public: // actually package-private
+ static const jbyte THREAD_PARK_RUNNING = 0;
+ static const jbyte THREAD_PARK_PERMIT = 1;
+ static const jbyte THREAD_PARK_PARKED = 2;
+ static const jbyte THREAD_PARK_DEAD = 3;
+ ::java::lang::Object * accessControlState;
+ ::gnu::gcj::RawData * interp_frame;
+ ::gnu::gcj::RawData * frame;
+ jint volatile state;
+ ::gnu::gcj::RawDataManaged * data;
+public:
+ static ::java::lang::Class class$;
+
+ friend _Jv_JNIEnv * ::_Jv_GetCurrentJNIEnv ();
+ friend void ::_Jv_SetCurrentJNIEnv (_Jv_JNIEnv *env);
+ friend void ::_Jv_ThreadRun (java::lang::Thread* thread);
+ friend jint (::_Jv_AttachCurrentThread) (java::lang::Thread* thread);
+ friend java::lang::Thread* ::_Jv_AttachCurrentThread (jstring name, java::lang::ThreadGroup* group);
+ friend java::lang::Thread* ::_Jv_AttachCurrentThreadAsDaemon (jstring name, java::lang::ThreadGroup* group);
+ friend jint (::_Jv_DetachCurrentThread) ();
+};
+
+#endif // __java_lang_Thread__
diff --git a/libjava/java/lang/Thread.java b/libjava/java/lang/Thread.java
new file mode 100644
index 000000000..8b6d4ba75
--- /dev/null
+++ b/libjava/java/lang/Thread.java
@@ -0,0 +1,1358 @@
+/* Thread -- an independent thread of executable code
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import gnu.classpath.VMStackWalker;
+import gnu.gcj.RawData;
+import gnu.gcj.RawDataManaged;
+import gnu.java.util.WeakIdentityHashMap;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete to version 1.4, with caveats. We do not
+ * implement the deprecated (and dangerous) stop, suspend, and resume
+ * methods. Security implementation is not complete.
+ */
+
+/**
+ * Thread represents a single thread of execution in the VM. When an
+ * application VM starts up, it creates a non-daemon Thread which calls the
+ * main() method of a particular class. There may be other Threads running,
+ * such as the garbage collection thread.
+ *
+ * <p>Threads have names to identify them. These names are not necessarily
+ * unique. Every Thread has a priority, as well, which tells the VM which
+ * Threads should get more running time. New threads inherit the priority
+ * and daemon status of the parent thread, by default.
+ *
+ * <p>There are two methods of creating a Thread: you may subclass Thread and
+ * implement the <code>run()</code> method, at which point you may start the
+ * Thread by calling its <code>start()</code> method, or you may implement
+ * <code>Runnable</code> in the class you want to use and then call new
+ * <code>Thread(your_obj).start()</code>.
+ *
+ * <p>The virtual machine runs until all non-daemon threads have died (either
+ * by returning from the run() method as invoked by start(), or by throwing
+ * an uncaught exception); or until <code>System.exit</code> is called with
+ * adequate permissions.
+ *
+ * <p>It is unclear at what point a Thread should be added to a ThreadGroup,
+ * and at what point it should be removed. Should it be inserted when it
+ * starts, or when it is created? Should it be removed when it is suspended
+ * or interrupted? The only thing that is clear is that the Thread should be
+ * removed when it is stopped.
+ *
+ * @author Tom Tromey
+ * @author John Keiser
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @see Runnable
+ * @see Runtime#exit(int)
+ * @see #run()
+ * @see #start()
+ * @see ThreadLocal
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public class Thread implements Runnable
+{
+ /** The minimum priority for a Thread. */
+ public static final int MIN_PRIORITY = 1;
+
+ /** The priority a Thread gets by default. */
+ public static final int NORM_PRIORITY = 5;
+
+ /** The maximum priority for a Thread. */
+ public static final int MAX_PRIORITY = 10;
+
+ /**
+ * The group this thread belongs to. This is set to null by
+ * ThreadGroup.removeThread when the thread dies.
+ */
+ ThreadGroup group;
+
+ /** The object to run(), null if this is the target. */
+ private Runnable runnable;
+
+ /** The thread name, non-null. */
+ String name;
+
+ /** Whether the thread is a daemon. */
+ private boolean daemon;
+
+ /** The thread priority, 1 to 10. */
+ private int priority;
+
+ boolean interrupt_flag;
+
+ /** A thread is either alive, dead, or being sent a signal; if it is
+ being sent a signal, it is also alive. Thus, if you want to
+ know if a thread is alive, it is sufficient to test
+ alive_status != THREAD_DEAD. */
+ private static final byte THREAD_DEAD = 0;
+ private static final byte THREAD_ALIVE = 1;
+ private static final byte THREAD_SIGNALED = 2;
+
+ private boolean startable_flag;
+
+ /** The context classloader for this Thread. */
+ private ClassLoader contextClassLoader;
+
+ /** This thread's ID. */
+ private final long threadId;
+
+ /** The next thread ID to use. */
+ private static long nextThreadId;
+
+ /** Used to generate the next thread ID to use. */
+ private static long totalThreadsCreated;
+
+ /** The default exception handler. */
+ private static UncaughtExceptionHandler defaultHandler;
+
+ /** Thread local storage. Package accessible for use by
+ * InheritableThreadLocal.
+ */
+ ThreadLocalMap locals;
+
+ /** The uncaught exception handler. */
+ UncaughtExceptionHandler exceptionHandler;
+
+ /** This object is recorded while the thread is blocked to permit
+ * monitoring and diagnostic tools to identify the reasons that
+ * threads are blocked.
+ */
+ private Object parkBlocker;
+
+ /** Used by Unsafe.park and Unsafe.unpark. Se Unsafe for a full
+ description. */
+ static final byte THREAD_PARK_RUNNING = 0;
+ static final byte THREAD_PARK_PERMIT = 1;
+ static final byte THREAD_PARK_PARKED = 2;
+ static final byte THREAD_PARK_DEAD = 3;
+
+ /** The access control state for this thread. Package accessible
+ * for use by java.security.VMAccessControlState's native method.
+ */
+ Object accessControlState = null;
+
+ // This describes the top-most interpreter frame for this thread.
+ RawData interp_frame;
+
+ // This describes the top most frame in the composite (interp + JNI) stack
+ RawData frame;
+
+ // Current state.
+ volatile int state;
+
+ // Our native data - points to an instance of struct natThread.
+ RawDataManaged data;
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(null, null,</code>
+ * <i>gname</i><code>)</code>, where <b><i>gname</i></b> is
+ * a newly generated name. Automatically generated names are of the
+ * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
+ * <p>
+ * Threads created this way must have overridden their
+ * <code>run()</code> method to actually do anything. An example
+ * illustrating this method being used follows:
+ * <p><blockquote><pre>
+ * import java.lang.*;
+ *
+ * class plain01 implements Runnable {
+ * String name;
+ * plain01() {
+ * name = null;
+ * }
+ * plain01(String s) {
+ * name = s;
+ * }
+ * public void run() {
+ * if (name == null)
+ * System.out.println("A new thread created");
+ * else
+ * System.out.println("A new thread with name " + name +
+ * " created");
+ * }
+ * }
+ * class threadtest01 {
+ * public static void main(String args[] ) {
+ * int failed = 0 ;
+ *
+ * <b>Thread t1 = new Thread();</b>
+ * if (t1 != null)
+ * System.out.println("new Thread() succeed");
+ * else {
+ * System.out.println("new Thread() failed");
+ * failed++;
+ * }
+ * }
+ * }
+ * </pre></blockquote>
+ *
+ * @see java.lang.Thread#Thread(java.lang.ThreadGroup,
+ * java.lang.Runnable, java.lang.String)
+ */
+ public Thread()
+ {
+ this(null, null, gen_name());
+ }
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(null, target,</code>
+ * <i>gname</i><code>)</code>, where <i>gname</i> is
+ * a newly generated name. Automatically generated names are of the
+ * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
+ *
+ * @param target the object whose <code>run</code> method is called.
+ * @see java.lang.Thread#Thread(java.lang.ThreadGroup,
+ * java.lang.Runnable, java.lang.String)
+ */
+ public Thread(Runnable target)
+ {
+ this(null, target, gen_name());
+ }
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(null, null, name)</code>.
+ *
+ * @param name the name of the new thread.
+ * @see java.lang.Thread#Thread(java.lang.ThreadGroup,
+ * java.lang.Runnable, java.lang.String)
+ */
+ public Thread(String name)
+ {
+ this(null, null, name);
+ }
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(group, target,</code>
+ * <i>gname</i><code>)</code>, where <i>gname</i> is
+ * a newly generated name. Automatically generated names are of the
+ * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
+ *
+ * @param group the group to put the Thread into
+ * @param target the Runnable object to execute
+ * @throws SecurityException if this thread cannot access <code>group</code>
+ * @throws IllegalThreadStateException if group is destroyed
+ * @see #Thread(ThreadGroup, Runnable, String)
+ */
+ public Thread(ThreadGroup group, Runnable target)
+ {
+ this(group, target, gen_name());
+ }
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(group, null, name)</code>
+ *
+ * @param group the group to put the Thread into
+ * @param name the name for the Thread
+ * @throws NullPointerException if name is null
+ * @throws SecurityException if this thread cannot access <code>group</code>
+ * @throws IllegalThreadStateException if group is destroyed
+ * @see #Thread(ThreadGroup, Runnable, String)
+ */
+ public Thread(ThreadGroup group, String name)
+ {
+ this(group, null, name);
+ }
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(null, target, name)</code>.
+ *
+ * @param target the Runnable object to execute
+ * @param name the name for the Thread
+ * @throws NullPointerException if name is null
+ * @see #Thread(ThreadGroup, Runnable, String)
+ */
+ public Thread(Runnable target, String name)
+ {
+ this(null, target, name);
+ }
+
+ /**
+ * Allocate a new Thread object, with the specified ThreadGroup and name, and
+ * using the specified Runnable object's <code>run()</code> method to
+ * execute. If the Runnable object is null, <code>this</code> (which is
+ * a Runnable) is used instead.
+ *
+ * <p>If the ThreadGroup is null, the security manager is checked. If a
+ * manager exists and returns a non-null object for
+ * <code>getThreadGroup</code>, that group is used; otherwise the group
+ * of the creating thread is used. Note that the security manager calls
+ * <code>checkAccess</code> if the ThreadGroup is not null.
+ *
+ * <p>The new Thread will inherit its creator's priority and daemon status.
+ * These can be changed with <code>setPriority</code> and
+ * <code>setDaemon</code>.
+ *
+ * @param group the group to put the Thread into
+ * @param target the Runnable object to execute
+ * @param name the name for the Thread
+ * @throws NullPointerException if name is null
+ * @throws SecurityException if this thread cannot access <code>group</code>
+ * @throws IllegalThreadStateException if group is destroyed
+ * @see Runnable#run()
+ * @see #run()
+ * @see #setDaemon(boolean)
+ * @see #setPriority(int)
+ * @see SecurityManager#checkAccess(ThreadGroup)
+ * @see ThreadGroup#checkAccess()
+ */
+ public Thread(ThreadGroup group, Runnable target, String name)
+ {
+ this(currentThread(), group, target, name, false);
+ }
+
+ /**
+ * Allocate a new Thread object, as if by
+ * <code>Thread(group, null, name)</code>, and give it the specified stack
+ * size, in bytes. The stack size is <b>highly platform independent</b>,
+ * and the virtual machine is free to round up or down, or ignore it
+ * completely. A higher value might let you go longer before a
+ * <code>StackOverflowError</code>, while a lower value might let you go
+ * longer before an <code>OutOfMemoryError</code>. Or, it may do absolutely
+ * nothing! So be careful, and expect to need to tune this value if your
+ * virtual machine even supports it.
+ *
+ * @param group the group to put the Thread into
+ * @param target the Runnable object to execute
+ * @param name the name for the Thread
+ * @param size the stack size, in bytes; 0 to be ignored
+ * @throws NullPointerException if name is null
+ * @throws SecurityException if this thread cannot access <code>group</code>
+ * @throws IllegalThreadStateException if group is destroyed
+ * @since 1.4
+ */
+ public Thread(ThreadGroup group, Runnable target, String name, long size)
+ {
+ // Just ignore stackSize for now.
+ this(currentThread(), group, target, name, false);
+ }
+
+ /**
+ * Allocate a new Thread object for threads used internally to the
+ * run time. Runtime threads should not be members of an
+ * application ThreadGroup, nor should they execute arbitrary user
+ * code as part of the InheritableThreadLocal protocol.
+ *
+ * @param name the name for the Thread
+ * @param noInheritableThreadLocal if true, do not initialize
+ * InheritableThreadLocal variables for this thread.
+ * @throws IllegalThreadStateException if group is destroyed
+ */
+ Thread(String name, boolean noInheritableThreadLocal)
+ {
+ this(null, null, null, name, noInheritableThreadLocal);
+ }
+
+ private Thread (Thread current, ThreadGroup g, Runnable r, String n, boolean noInheritableThreadLocal)
+ {
+ // Make sure the current thread may create a new thread.
+ checkAccess();
+
+ // The Class Libraries book says ``threadName cannot be null''. I
+ // take this to mean NullPointerException.
+ if (n == null)
+ throw new NullPointerException ();
+
+ if (g == null)
+ {
+ // If CURRENT is null, then we are bootstrapping the first thread.
+ // Use ThreadGroup.root, the main threadgroup.
+ if (current == null)
+ group = ThreadGroup.root;
+ else
+ group = current.getThreadGroup();
+ }
+ else
+ group = g;
+
+ data = null;
+ interrupt_flag = false;
+ startable_flag = true;
+
+ synchronized (Thread.class)
+ {
+ this.threadId = nextThreadId++;
+ }
+
+ // Always create the ThreadLocalMap when creating a thread; the
+ // previous code did this lazily when getThreadLocals was called,
+ // but this is a divergence from Classpath's implementation of
+ // ThreadLocal.
+ this.locals = new ThreadLocalMap();
+
+ if (current != null)
+ {
+ group.checkAccess();
+
+ daemon = current.isDaemon();
+ int gmax = group.getMaxPriority();
+ int pri = current.getPriority();
+ priority = (gmax < pri ? gmax : pri);
+ contextClassLoader = current.contextClassLoader;
+ // InheritableThreadLocal allows arbitrary user code to be
+ // executed, only do this if our caller desires it.
+ if (!noInheritableThreadLocal)
+ InheritableThreadLocal.newChildThread(this);
+ }
+ else
+ {
+ daemon = false;
+ priority = NORM_PRIORITY;
+ }
+
+ name = n;
+ group.addThread(this);
+ runnable = r;
+
+ initialize_native ();
+ }
+
+ /**
+ * Get the number of active threads in the current Thread's ThreadGroup.
+ * This implementation calls
+ * <code>currentThread().getThreadGroup().activeCount()</code>.
+ *
+ * @return the number of active threads in the current ThreadGroup
+ * @see ThreadGroup#activeCount()
+ */
+ public static int activeCount()
+ {
+ return currentThread().group.activeCount();
+ }
+
+ /**
+ * Check whether the current Thread is allowed to modify this Thread. This
+ * passes the check on to <code>SecurityManager.checkAccess(this)</code>.
+ *
+ * @throws SecurityException if the current Thread cannot modify this Thread
+ * @see SecurityManager#checkAccess(Thread)
+ */
+ public final void checkAccess()
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkAccess(this);
+ }
+
+ /**
+ * Count the number of stack frames in this Thread. The Thread in question
+ * must be suspended when this occurs.
+ *
+ * @return the number of stack frames in this Thread
+ * @throws IllegalThreadStateException if this Thread is not suspended
+ * @deprecated pointless, since suspend is deprecated
+ */
+ public native int countStackFrames();
+
+ /**
+ * Get the currently executing Thread. In the situation that the
+ * currently running thread was created by native code and doesn't
+ * have an associated Thread object yet, a new Thread object is
+ * constructed and associated with the native thread.
+ *
+ * @return the currently executing Thread
+ */
+ public static native Thread currentThread();
+
+ /**
+ * Originally intended to destroy this thread, this method was never
+ * implemented by Sun, and is hence a no-op.
+ *
+ * @deprecated This method was originally intended to simply destroy
+ * the thread without performing any form of cleanup operation.
+ * However, it was never implemented. It is now deprecated
+ * for the same reason as <code>suspend()</code>,
+ * <code>stop()</code> and <code>resume()</code>; namely,
+ * it is prone to deadlocks. If a thread is destroyed while
+ * it still maintains a lock on a resource, then this resource
+ * will remain locked and any attempts by other threads to
+ * access the resource will result in a deadlock. Thus, even
+ * an implemented version of this method would be still be
+ * deprecated, due to its unsafe nature.
+ * @throws NoSuchMethodError as this method was never implemented.
+ */
+ public void destroy()
+ {
+ throw new NoSuchMethodError();
+ }
+
+ /**
+ * Print a stack trace of the current thread to stderr using the same
+ * format as Throwable's printStackTrace() method.
+ *
+ * @see Throwable#printStackTrace()
+ */
+ public static void dumpStack()
+ {
+ (new Exception("Stack trace")).printStackTrace();
+ }
+
+ /**
+ * Copy every active thread in the current Thread's ThreadGroup into the
+ * array. Extra threads are silently ignored. This implementation calls
+ * <code>getThreadGroup().enumerate(array)</code>, which may have a
+ * security check, <code>checkAccess(group)</code>.
+ *
+ * @param array the array to place the Threads into
+ * @return the number of Threads placed into the array
+ * @throws NullPointerException if array is null
+ * @throws SecurityException if you cannot access the ThreadGroup
+ * @see ThreadGroup#enumerate(Thread[])
+ * @see #activeCount()
+ * @see SecurityManager#checkAccess(ThreadGroup)
+ */
+ public static int enumerate(Thread[] array)
+ {
+ return currentThread().group.enumerate(array);
+ }
+
+ /**
+ * Get this Thread's name.
+ *
+ * @return this Thread's name
+ */
+ public final String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Get this Thread's priority.
+ *
+ * @return the Thread's priority
+ */
+ public final int getPriority()
+ {
+ return priority;
+ }
+
+ /**
+ * Get the ThreadGroup this Thread belongs to. If the thread has died, this
+ * returns null.
+ *
+ * @return this Thread's ThreadGroup
+ */
+ public final ThreadGroup getThreadGroup()
+ {
+ return group;
+ }
+
+ /**
+ * Checks whether the current thread holds the monitor on a given object.
+ * This allows you to do <code>assert Thread.holdsLock(obj)</code>.
+ *
+ * @param obj the object to test lock ownership on.
+ * @return true if the current thread is currently synchronized on obj
+ * @throws NullPointerException if obj is null
+ * @since 1.4
+ */
+ public static native boolean holdsLock(Object obj);
+
+ /**
+ * Interrupt this Thread. First, there is a security check,
+ * <code>checkAccess</code>. Then, depending on the current state of the
+ * thread, various actions take place:
+ *
+ * <p>If the thread is waiting because of {@link #wait()},
+ * {@link #sleep(long)}, or {@link #join()}, its <i>interrupt status</i>
+ * will be cleared, and an InterruptedException will be thrown. Notice that
+ * this case is only possible if an external thread called interrupt().
+ *
+ * <p>If the thread is blocked in an interruptible I/O operation, in
+ * {@link java.nio.channels.InterruptibleChannel}, the <i>interrupt
+ * status</i> will be set, and ClosedByInterruptException will be thrown.
+ *
+ * <p>If the thread is blocked on a {@link java.nio.channels.Selector}, the
+ * <i>interrupt status</i> will be set, and the selection will return, with
+ * a possible non-zero value, as though by the wakeup() method.
+ *
+ * <p>Otherwise, the interrupt status will be set.
+ *
+ * @throws SecurityException if you cannot modify this Thread
+ */
+ public native void interrupt();
+
+ /**
+ * Determine whether the current Thread has been interrupted, and clear
+ * the <i>interrupted status</i> in the process.
+ *
+ * @return whether the current Thread has been interrupted
+ * @see #isInterrupted()
+ */
+ public static boolean interrupted()
+ {
+ return currentThread().isInterrupted(true);
+ }
+
+ /**
+ * Determine whether the given Thread has been interrupted, but leave
+ * the <i>interrupted status</i> alone in the process.
+ *
+ * @return whether the Thread has been interrupted
+ * @see #interrupted()
+ */
+ public boolean isInterrupted()
+ {
+ return interrupt_flag;
+ }
+
+ /**
+ * Determine whether this Thread is alive. A thread which is alive has
+ * started and not yet died.
+ *
+ * @return whether this Thread is alive
+ */
+ public final native boolean isAlive();
+
+ /**
+ * Tell whether this is a daemon Thread or not.
+ *
+ * @return whether this is a daemon Thread or not
+ * @see #setDaemon(boolean)
+ */
+ public final boolean isDaemon()
+ {
+ return daemon;
+ }
+
+ /**
+ * Wait forever for the Thread in question to die.
+ *
+ * @throws InterruptedException if the Thread is interrupted; it's
+ * <i>interrupted status</i> will be cleared
+ */
+ public final void join() throws InterruptedException
+ {
+ join(0, 0);
+ }
+
+ /**
+ * Wait the specified amount of time for the Thread in question to die.
+ *
+ * @param ms the number of milliseconds to wait, or 0 for forever
+ * @throws InterruptedException if the Thread is interrupted; it's
+ * <i>interrupted status</i> will be cleared
+ */
+ public final void join(long ms) throws InterruptedException
+ {
+ join(ms, 0);
+ }
+
+ /**
+ * Wait the specified amount of time for the Thread in question to die.
+ *
+ * <p>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do
+ * not offer that fine a grain of timing resolution. Besides, there is
+ * no guarantee that this thread can start up immediately when time expires,
+ * because some other thread may be active. So don't expect real-time
+ * performance.
+ *
+ * @param ms the number of milliseconds to wait, or 0 for forever
+ * @param ns the number of extra nanoseconds to sleep (0-999999)
+ * @throws InterruptedException if the Thread is interrupted; it's
+ * <i>interrupted status</i> will be cleared
+ * @throws IllegalArgumentException if ns is invalid
+ * @XXX A ThreadListener would be nice, to make this efficient.
+ */
+ public final native void join(long ms, int ns)
+ throws InterruptedException;
+
+ /**
+ * Resume this Thread. If the thread is not suspended, this method does
+ * nothing. To mirror suspend(), there may be a security check:
+ * <code>checkAccess</code>.
+ *
+ * @throws SecurityException if you cannot resume the Thread
+ * @see #checkAccess()
+ * @see #suspend()
+ * @deprecated pointless, since suspend is deprecated
+ */
+ public final native void resume();
+
+ private final native void finish_();
+
+ /**
+ * Determine whether the given Thread has been interrupted, but leave
+ * the <i>interrupted status</i> alone in the process.
+ *
+ * @return whether the current Thread has been interrupted
+ * @see #interrupted()
+ */
+ private boolean isInterrupted(boolean clear_flag)
+ {
+ boolean r = interrupt_flag;
+ if (clear_flag && r)
+ {
+ // Only clear the flag if we saw it as set. Otherwise this could
+ // potentially cause us to miss an interrupt in a race condition,
+ // because this method is not synchronized.
+ interrupt_flag = false;
+ }
+ return r;
+ }
+
+ /**
+ * The method of Thread that will be run if there is no Runnable object
+ * associated with the Thread. Thread's implementation does nothing at all.
+ *
+ * @see #start()
+ * @see #Thread(ThreadGroup, Runnable, String)
+ */
+ public void run()
+ {
+ if (runnable != null)
+ runnable.run();
+ }
+
+ /**
+ * Set the daemon status of this Thread. If this is a daemon Thread, then
+ * the VM may exit even if it is still running. This may only be called
+ * before the Thread starts running. There may be a security check,
+ * <code>checkAccess</code>.
+ *
+ * @param daemon whether this should be a daemon thread or not
+ * @throws SecurityException if you cannot modify this Thread
+ * @throws IllegalThreadStateException if the Thread is active
+ * @see #isDaemon()
+ * @see #checkAccess()
+ */
+ public final void setDaemon(boolean daemon)
+ {
+ if (!startable_flag)
+ throw new IllegalThreadStateException();
+ checkAccess();
+ this.daemon = daemon;
+ }
+
+ /**
+ * Returns the context classloader of this Thread. The context
+ * classloader can be used by code that want to load classes depending
+ * on the current thread. Normally classes are loaded depending on
+ * the classloader of the current class. There may be a security check
+ * for <code>RuntimePermission("getClassLoader")</code> if the caller's
+ * class loader is not null or an ancestor of this thread's context class
+ * loader.
+ *
+ * @return the context class loader
+ * @throws SecurityException when permission is denied
+ * @see #setContextClassLoader(ClassLoader)
+ * @since 1.2
+ */
+ public synchronized ClassLoader getContextClassLoader()
+ {
+ if (contextClassLoader == null)
+ contextClassLoader = ClassLoader.getSystemClassLoader();
+
+ // Check if we may get the classloader
+ SecurityManager sm = System.getSecurityManager();
+ if (contextClassLoader != null && sm != null)
+ {
+ // Get the calling classloader
+ ClassLoader cl = VMStackWalker.getCallingClassLoader();
+ if (cl != null && !cl.isAncestorOf(contextClassLoader))
+ sm.checkPermission(new RuntimePermission("getClassLoader"));
+ }
+ return contextClassLoader;
+ }
+
+ /**
+ * Sets the context classloader for this Thread. When not explicitly set,
+ * the context classloader for a thread is the same as the context
+ * classloader of the thread that created this thread. The first thread has
+ * as context classloader the system classloader. There may be a security
+ * check for <code>RuntimePermission("setContextClassLoader")</code>.
+ *
+ * @param classloader the new context class loader
+ * @throws SecurityException when permission is denied
+ * @see #getContextClassLoader()
+ * @since 1.2
+ */
+ public synchronized void setContextClassLoader(ClassLoader classloader)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+ this.contextClassLoader = classloader;
+ }
+
+ /**
+ * Set this Thread's name. There may be a security check,
+ * <code>checkAccess</code>.
+ *
+ * @param name the new name for this Thread
+ * @throws NullPointerException if name is null
+ * @throws SecurityException if you cannot modify this Thread
+ */
+ public final void setName(String name)
+ {
+ checkAccess();
+ // The Class Libraries book says ``threadName cannot be null''. I
+ // take this to mean NullPointerException.
+ if (name == null)
+ throw new NullPointerException();
+ this.name = name;
+ }
+
+ /**
+ * Yield to another thread. The Thread will not lose any locks it holds
+ * during this time. There are no guarantees which thread will be
+ * next to run, and it could even be this one, but most VMs will choose
+ * the highest priority thread that has been waiting longest.
+ */
+ public static native void yield();
+
+ /**
+ * Suspend the current Thread's execution for the specified amount of
+ * time. The Thread will not lose any locks it has during this time. There
+ * are no guarantees which thread will be next to run, but most VMs will
+ * choose the highest priority thread that has been waiting longest.
+ *
+ * @param ms the number of milliseconds to sleep, or 0 for forever
+ * @throws InterruptedException if the Thread is (or was) interrupted;
+ * it's <i>interrupted status</i> will be cleared
+ * @throws IllegalArgumentException if ms is negative
+ * @see #interrupt()
+ * @see #notify()
+ * @see #wait(long)
+ */
+ public static void sleep(long ms) throws InterruptedException
+ {
+ sleep(ms, 0);
+ }
+
+ /**
+ * Suspend the current Thread's execution for the specified amount of
+ * time. The Thread will not lose any locks it has during this time. There
+ * are no guarantees which thread will be next to run, but most VMs will
+ * choose the highest priority thread that has been waiting longest.
+ * <p>
+ * Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs
+ * do not offer that fine a grain of timing resolution. When ms is
+ * zero and ns is non-zero the Thread will sleep for at least one
+ * milli second. There is no guarantee that this thread can start up
+ * immediately when time expires, because some other thread may be
+ * active. So don't expect real-time performance.
+ *
+ * @param ms the number of milliseconds to sleep, or 0 for forever
+ * @param ns the number of extra nanoseconds to sleep (0-999999)
+ * @throws InterruptedException if the Thread is (or was) interrupted;
+ * it's <i>interrupted status</i> will be cleared
+ * @throws IllegalArgumentException if ms or ns is negative
+ * or ns is larger than 999999.
+ * @see #interrupt()
+ * @see #notify()
+ * @see #wait(long, int)
+ */
+ public static native void sleep(long timeout, int nanos)
+ throws InterruptedException;
+
+ /**
+ * Start this Thread, calling the run() method of the Runnable this Thread
+ * was created with, or else the run() method of the Thread itself. This
+ * is the only way to start a new thread; calling run by yourself will just
+ * stay in the same thread. The virtual machine will remove the thread from
+ * its thread group when the run() method completes.
+ *
+ * @throws IllegalThreadStateException if the thread has already started
+ * @see #run()
+ */
+ public native void start();
+
+ /**
+ * Cause this Thread to stop abnormally because of the throw of a ThreadDeath
+ * error. If you stop a Thread that has not yet started, it will stop
+ * immediately when it is actually started.
+ *
+ * <p>This is inherently unsafe, as it can interrupt synchronized blocks and
+ * leave data in bad states. Hence, there is a security check:
+ * <code>checkAccess(this)</code>, plus another one if the current thread
+ * is not this: <code>RuntimePermission("stopThread")</code>. If you must
+ * catch a ThreadDeath, be sure to rethrow it after you have cleaned up.
+ * ThreadDeath is the only exception which does not print a stack trace when
+ * the thread dies.
+ *
+ * @throws SecurityException if you cannot stop the Thread
+ * @see #interrupt()
+ * @see #checkAccess()
+ * @see #start()
+ * @see ThreadDeath
+ * @see ThreadGroup#uncaughtException(Thread, Throwable)
+ * @see SecurityManager#checkAccess(Thread)
+ * @see SecurityManager#checkPermission(Permission)
+ * @deprecated unsafe operation, try not to use
+ */
+ public final void stop()
+ {
+ // Argument doesn't matter, because this is no longer
+ // supported.
+ stop(null);
+ }
+
+ /**
+ * Cause this Thread to stop abnormally and throw the specified exception.
+ * If you stop a Thread that has not yet started, the stop is ignored
+ * (contrary to what the JDK documentation says).
+ * <b>WARNING</b>This bypasses Java security, and can throw a checked
+ * exception which the call stack is unprepared to handle. Do not abuse
+ * this power.
+ *
+ * <p>This is inherently unsafe, as it can interrupt synchronized blocks and
+ * leave data in bad states. Hence, there is a security check:
+ * <code>checkAccess(this)</code>, plus another one if the current thread
+ * is not this: <code>RuntimePermission("stopThread")</code>. If you must
+ * catch a ThreadDeath, be sure to rethrow it after you have cleaned up.
+ * ThreadDeath is the only exception which does not print a stack trace when
+ * the thread dies.
+ *
+ * @param t the Throwable to throw when the Thread dies
+ * @throws SecurityException if you cannot stop the Thread
+ * @throws NullPointerException in the calling thread, if t is null
+ * @see #interrupt()
+ * @see #checkAccess()
+ * @see #start()
+ * @see ThreadDeath
+ * @see ThreadGroup#uncaughtException(Thread, Throwable)
+ * @see SecurityManager#checkAccess(Thread)
+ * @see SecurityManager#checkPermission(Permission)
+ * @deprecated unsafe operation, try not to use
+ */
+ public final native void stop(Throwable t);
+
+ /**
+ * Suspend this Thread. It will not come back, ever, unless it is resumed.
+ *
+ * <p>This is inherently unsafe, as the suspended thread still holds locks,
+ * and can potentially deadlock your program. Hence, there is a security
+ * check: <code>checkAccess</code>.
+ *
+ * @throws SecurityException if you cannot suspend the Thread
+ * @see #checkAccess()
+ * @see #resume()
+ * @deprecated unsafe operation, try not to use
+ */
+ public final native void suspend();
+
+ /**
+ * Set this Thread's priority. There may be a security check,
+ * <code>checkAccess</code>, then the priority is set to the smaller of
+ * priority and the ThreadGroup maximum priority.
+ *
+ * @param priority the new priority for this Thread
+ * @throws IllegalArgumentException if priority exceeds MIN_PRIORITY or
+ * MAX_PRIORITY
+ * @throws SecurityException if you cannot modify this Thread
+ * @see #getPriority()
+ * @see #checkAccess()
+ * @see ThreadGroup#getMaxPriority()
+ * @see #MIN_PRIORITY
+ * @see #MAX_PRIORITY
+ */
+ public final native void setPriority(int newPriority);
+
+ /**
+ * Returns a string representation of this thread, including the
+ * thread's name, priority, and thread group.
+ *
+ * @return a human-readable String representing this Thread
+ */
+ public String toString()
+ {
+ return ("Thread[" + name + "," + priority + ","
+ + (group == null ? "" : group.getName()) + "]");
+ }
+
+ private final native void initialize_native();
+
+ private final native static String gen_name();
+
+ /**
+ * Returns the map used by ThreadLocal to store the thread local values.
+ */
+ static ThreadLocalMap getThreadLocals()
+ {
+ Thread thread = currentThread();
+ ThreadLocalMap locals = thread.locals;
+
+ return locals;
+ }
+
+ /**
+ * Assigns the given <code>UncaughtExceptionHandler</code> to this
+ * thread. This will then be called if the thread terminates due
+ * to an uncaught exception, pre-empting that of the
+ * <code>ThreadGroup</code>.
+ *
+ * @param h the handler to use for this thread.
+ * @throws SecurityException if the current thread can't modify this thread.
+ * @since 1.5
+ */
+ public void setUncaughtExceptionHandler(UncaughtExceptionHandler h)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkAccess(this);
+ exceptionHandler = h;
+ }
+
+ /**
+ * <p>
+ * Returns the handler used when this thread terminates due to an
+ * uncaught exception. The handler used is determined by the following:
+ * </p>
+ * <ul>
+ * <li>If this thread has its own handler, this is returned.</li>
+ * <li>If not, then the handler of the thread's <code>ThreadGroup</code>
+ * object is returned.</li>
+ * <li>If both are unavailable, then <code>null</code> is returned
+ * (which can only happen when the thread was terminated since
+ * then it won't have an associated thread group anymore).</li>
+ * </ul>
+ *
+ * @return the appropriate <code>UncaughtExceptionHandler</code> or
+ * <code>null</code> if one can't be obtained.
+ * @since 1.5
+ */
+ public UncaughtExceptionHandler getUncaughtExceptionHandler()
+ {
+ // FIXME: if thread is dead, should return null...
+ return exceptionHandler != null ? exceptionHandler : group;
+ }
+
+ /**
+ * <p>
+ * Sets the default uncaught exception handler used when one isn't
+ * provided by the thread or its associated <code>ThreadGroup</code>.
+ * This exception handler is used when the thread itself does not
+ * have an exception handler, and the thread's <code>ThreadGroup</code>
+ * does not override this default mechanism with its own. As the group
+ * calls this handler by default, this exception handler should not defer
+ * to that of the group, as it may lead to infinite recursion.
+ * </p>
+ * <p>
+ * Uncaught exception handlers are used when a thread terminates due to
+ * an uncaught exception. Replacing this handler allows default code to
+ * be put in place for all threads in order to handle this eventuality.
+ * </p>
+ *
+ * @param h the new default uncaught exception handler to use.
+ * @throws SecurityException if a security manager is present and
+ * disallows the runtime permission
+ * "setDefaultUncaughtExceptionHandler".
+ * @since 1.5
+ */
+ public static void
+ setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler h)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("setDefaultUncaughtExceptionHandler"));
+ defaultHandler = h;
+ }
+
+ /**
+ * Returns the handler used by default when a thread terminates
+ * unexpectedly due to an exception, or <code>null</code> if one doesn't
+ * exist.
+ *
+ * @return the default uncaught exception handler.
+ * @since 1.5
+ */
+ public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler()
+ {
+ return defaultHandler;
+ }
+
+ /**
+ * Returns the unique identifier for this thread. This ID is generated
+ * on thread creation, and may be re-used on its death.
+ *
+ * @return a positive long number representing the thread's ID.
+ * @since 1.5
+ */
+ public long getId()
+ {
+ return threadId;
+ }
+
+ /**
+ * <p>
+ * This interface is used to handle uncaught exceptions
+ * which cause a <code>Thread</code> to terminate. When
+ * a thread, t, is about to terminate due to an uncaught
+ * exception, the virtual machine looks for a class which
+ * implements this interface, in order to supply it with
+ * the dying thread and its uncaught exception.
+ * </p>
+ * <p>
+ * The virtual machine makes two attempts to find an
+ * appropriate handler for the uncaught exception, in
+ * the following order:
+ * </p>
+ * <ol>
+ * <li>
+ * <code>t.getUncaughtExceptionHandler()</code> --
+ * the dying thread is queried first for a handler
+ * specific to that thread.
+ * </li>
+ * <li>
+ * <code>t.getThreadGroup()</code> --
+ * the thread group of the dying thread is used to
+ * handle the exception. If the thread group has
+ * no special requirements for handling the exception,
+ * it may simply forward it on to
+ * <code>Thread.getDefaultUncaughtExceptionHandler()</code>,
+ * the default handler, which is used as a last resort.
+ * </li>
+ * </ol>
+ * <p>
+ * The first handler found is the one used to handle
+ * the uncaught exception.
+ * </p>
+ *
+ * @author Tom Tromey <tromey@redhat.com>
+ * @author Andrew John Hughes <gnu_andrew@member.fsf.org>
+ * @since 1.5
+ * @see Thread#getUncaughtExceptionHandler()
+ * @see Thread#setUncaughtExceptionHandler(UncaughtExceptionHandler)
+ * @see Thread#getDefaultUncaughtExceptionHandler()
+ * @see
+ * Thread#setDefaultUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler)
+ */
+ public interface UncaughtExceptionHandler
+ {
+ /**
+ * Invoked by the virtual machine with the dying thread
+ * and the uncaught exception. Any exceptions thrown
+ * by this method are simply ignored by the virtual
+ * machine.
+ *
+ * @param thr the dying thread.
+ * @param exc the uncaught exception.
+ */
+ void uncaughtException(Thread thr, Throwable exc);
+ }
+
+ /**
+ * <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;
+ }
+
+
+ /**
+ * Returns the current state of the thread. This
+ * is designed for monitoring thread behaviour, rather
+ * than for synchronization control.
+ *
+ * @return the current thread state.
+ */
+ public native State getState();
+
+ /**
+ * <p>
+ * Returns a map of threads to stack traces for each
+ * live thread. The keys of the map are {@link Thread}
+ * objects, which map to arrays of {@link StackTraceElement}s.
+ * The results obtained from Calling this method are
+ * equivalent to calling {@link getStackTrace()} on each
+ * thread in succession. Threads may be executing while
+ * this takes place, and the results represent a snapshot
+ * of the thread at the time its {@link getStackTrace()}
+ * method is called.
+ * </p>
+ * <p>
+ * The stack trace information contains the methods called
+ * by the thread, with the most recent method forming the
+ * first element in the array. The array will be empty
+ * if the virtual machine can not obtain information on the
+ * thread.
+ * </p>
+ * <p>
+ * To execute this method, the current security manager
+ * (if one exists) must allow both the
+ * <code>"getStackTrace"</code> and
+ * <code>"modifyThreadGroup"</code> {@link RuntimePermission}s.
+ * </p>
+ *
+ * @return a map of threads to arrays of {@link StackTraceElement}s.
+ * @throws SecurityException if a security manager exists, and
+ * prevents either or both the runtime
+ * permissions specified above.
+ * @since 1.5
+ * @see #getStackTrace()
+ */
+ public static Map<Thread, StackTraceElement[]> getAllStackTraces()
+ {
+ ThreadGroup group = currentThread().group;
+ while (group.getParent() != null)
+ group = group.getParent();
+ int arraySize = group.activeCount();
+ Thread[] threadList = new Thread[arraySize];
+ int filled = group.enumerate(threadList);
+ while (filled == arraySize)
+ {
+ arraySize *= 2;
+ threadList = new Thread[arraySize];
+ filled = group.enumerate(threadList);
+ }
+ Map traces = new HashMap();
+ for (int a = 0; a < filled; ++a)
+ traces.put(threadList[a],
+ threadList[a].getStackTrace());
+ return traces;
+ }
+
+ /**
+ * <p>
+ * Returns an array of {@link StackTraceElement}s
+ * representing the current stack trace of this thread.
+ * The first element of the array is the most recent
+ * method called, and represents the top of the stack.
+ * The elements continue in this order, with the last
+ * element representing the bottom of the stack.
+ * </p>
+ * <p>
+ * A zero element array is returned for threads which
+ * have not yet started (and thus have not yet executed
+ * any methods) or for those which have terminated.
+ * Where the virtual machine can not obtain a trace for
+ * the thread, an empty array is also returned. The
+ * virtual machine may also omit some methods from the
+ * trace in non-zero arrays.
+ * </p>
+ * <p>
+ * To execute this method, the current security manager
+ * (if one exists) must allow both the
+ * <code>"getStackTrace"</code> and
+ * <code>"modifyThreadGroup"</code> {@link RuntimePermission}s.
+ * </p>
+ *
+ * @return a stack trace for this thread.
+ * @throws SecurityException if a security manager exists, and
+ * prevents the use of the
+ * <code>"getStackTrace"</code>
+ * permission.
+ * @since 1.5
+ * @see #getAllStackTraces()
+ */
+ public StackTraceElement[] getStackTrace()
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("getStackTrace"));
+
+ // Calling java.lang.management via reflection means that
+ // javax.management be overridden in the endorsed directory.
+
+ // This is the equivalent code:
+ //
+ // ThreadMXBean bean = ManagementFactory.getThreadMXBean();
+ // ThreadInfo info = bean.getThreadInfo(getId(), Integer.MAX_VALUE);
+ // return info.getStackTrace();
+
+ try
+ {
+ try
+ {
+ Object bean
+ = (Class.forName("java.lang.management.ManagementFactory")
+ .getDeclaredMethod("getThreadMXBean")
+ .invoke(null));
+ Object info = bean.getClass()
+ .getDeclaredMethod("getThreadInfo", long.class, int.class)
+ .invoke(bean, new Long(getId()), new Integer(Integer.MAX_VALUE));
+ Object trace = info.getClass()
+ .getDeclaredMethod("getStackTrace").invoke(info);
+ return (StackTraceElement[])trace;
+ }
+ catch (InvocationTargetException e)
+ {
+ throw (Exception)e.getTargetException();
+ }
+ }
+ catch (UnsupportedOperationException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new UnsupportedOperationException(e);
+ }
+ }
+}
diff --git a/libjava/java/lang/ThreadDeath.h b/libjava/java/lang/ThreadDeath.h
new file mode 100644
index 000000000..d06ce3458
--- /dev/null
+++ b/libjava/java/lang/ThreadDeath.h
@@ -0,0 +1,22 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ThreadDeath__
+#define __java_lang_ThreadDeath__
+
+#pragma interface
+
+#include <java/lang/Error.h>
+
+class java::lang::ThreadDeath : public ::java::lang::Error
+{
+
+public:
+ ThreadDeath();
+private:
+ static const jlong serialVersionUID = -4417128565033088268LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ThreadDeath__
diff --git a/libjava/java/lang/ThreadGroup.h b/libjava/java/lang/ThreadGroup.h
new file mode 100644
index 000000000..a197ca16e
--- /dev/null
+++ b/libjava/java/lang/ThreadGroup.h
@@ -0,0 +1,69 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ThreadGroup__
+#define __java_lang_ThreadGroup__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::ThreadGroup : public ::java::lang::Object
+{
+
+ ThreadGroup();
+public:
+ ThreadGroup(::java::lang::String *);
+ ThreadGroup(::java::lang::ThreadGroup *, ::java::lang::String *);
+ virtual ::java::lang::String * getName();
+ virtual ::java::lang::ThreadGroup * getParent();
+ virtual jint getMaxPriority();
+ virtual jboolean isDaemon();
+ virtual jboolean isDestroyed();
+ virtual void setDaemon(jboolean);
+ virtual void setMaxPriority(jint);
+ virtual jboolean parentOf(::java::lang::ThreadGroup *);
+ virtual void checkAccess();
+ virtual jint activeCount();
+ virtual jint enumerate(JArray< ::java::lang::Thread * > *);
+ virtual jint enumerate(JArray< ::java::lang::Thread * > *, jboolean);
+ virtual jint activeGroupCount();
+ virtual jint enumerate(JArray< ::java::lang::ThreadGroup * > *);
+ virtual jint enumerate(JArray< ::java::lang::ThreadGroup * > *, jboolean);
+ virtual void stop();
+ virtual void interrupt();
+ virtual void suspend();
+ virtual void resume();
+ virtual void destroy();
+ virtual void list();
+ virtual void uncaughtException(::java::lang::Thread *, ::java::lang::Throwable *);
+ virtual jboolean allowThreadSuspension(jboolean);
+ virtual ::java::lang::String * toString();
+private:
+ jint enumerate(JArray< ::java::lang::Thread * > *, jint, jboolean);
+ jint enumerate(JArray< ::java::lang::ThreadGroup * > *, jint, jboolean);
+ void list(::java::lang::String *);
+public: // actually package-private
+ virtual void addThread(::java::lang::Thread *);
+ virtual void removeThread(::java::lang::Thread *);
+ virtual void removeGroup(::java::lang::ThreadGroup *);
+ static ::java::lang::Thread * getThreadFromId(jlong);
+private:
+ ::java::lang::Thread * getThreadFromIdImpl(jlong);
+public: // actually package-private
+ static ::java::lang::ThreadGroup * root;
+ static jboolean had_uncaught_exception;
+ ::java::lang::ThreadGroup * __attribute__((aligned(__alignof__( ::java::lang::Object)))) parent;
+ ::java::lang::String * name;
+private:
+ ::java::util::Vector * threads;
+ ::java::util::Vector * groups;
+ jboolean daemon_flag;
+ jint maxpri;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ThreadGroup__
diff --git a/libjava/java/lang/ThreadLocal.h b/libjava/java/lang/ThreadLocal.h
new file mode 100644
index 000000000..13e1f84c6
--- /dev/null
+++ b/libjava/java/lang/ThreadLocal.h
@@ -0,0 +1,57 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ThreadLocal__
+#define __java_lang_ThreadLocal__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ class RawData;
+ }
+ }
+}
+
+class java::lang::ThreadLocal : public ::java::lang::Object
+{
+
+ jint computeNextHash();
+public:
+ ThreadLocal();
+public: // actually protected
+ virtual ::java::lang::Object * initialValue();
+public:
+ virtual ::java::lang::Object * get();
+private:
+ ::java::lang::Object * internalGet();
+public:
+ virtual void set(::java::lang::Object *);
+private:
+ void internalSet(::java::lang::Object *);
+public:
+ virtual void remove();
+private:
+ void internalRemove();
+public: // actually protected
+ virtual void finalize();
+private:
+ void constructNative();
+public: // actually package-private
+ static ::java::lang::Object * sentinel;
+private:
+ static jint nextHashBase;
+public: // actually package-private
+ jint __attribute__((aligned(__alignof__( ::java::lang::Object)))) fastHash;
+private:
+ ::gnu::gcj::RawData * TLSPointer;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ThreadLocal__
diff --git a/libjava/java/lang/ThreadLocal.java b/libjava/java/lang/ThreadLocal.java
new file mode 100644
index 000000000..9223dbaae
--- /dev/null
+++ b/libjava/java/lang/ThreadLocal.java
@@ -0,0 +1,198 @@
+/* ThreadLocal -- a variable with a unique value per thread
+ Copyright (C) 2000, 2002, 2003, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.util.Map;
+
+
+/**
+ * ThreadLocal objects have a different state associated with every
+ * Thread that accesses them. Every access to the ThreadLocal object
+ * (through the <code>get()</code> and <code>set()</code> methods)
+ * only affects the state of the object as seen by the currently
+ * executing Thread.
+ *
+ * <p>The first time a ThreadLocal object is accessed on a particular
+ * Thread, the state for that Thread's copy of the local variable is set by
+ * executing the method <code>initialValue()</code>.
+ * </p>
+ *
+ * <p>An example how you can use this:
+ * </p>
+ *
+ * <pre>
+ * class Connection
+ * {
+ * private static ThreadLocal owner = new ThreadLocal()
+ * {
+ * public Object initialValue()
+ * {
+ * return("nobody");
+ * }
+ * };
+ * ...
+ * }
+ * </pre>
+ *
+ * <p>Now all instances of connection can see who the owner of the currently
+ * executing Thread is by calling <code>owner.get()</code>. By default any
+ * Thread would be associated with 'nobody'. But the Connection object could
+ * offer a method that changes the owner associated with the Thread on
+ * which the method was called by calling <code>owner.put("somebody")</code>.
+ * (Such an owner changing method should then be guarded by security checks.)
+ * </p>
+ *
+ * <p>When a Thread is garbage collected all references to values of
+ * the ThreadLocal objects associated with that Thread are removed.
+ * </p>
+ *
+ * @author Mark Wielaard (mark@klomp.org)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ * @status updated to 1.5
+ */
+public class ThreadLocal<T>
+{
+ /**
+ * Placeholder to distinguish between uninitialized and null set by the
+ * user. Do not expose this to the public. Package visible for use by
+ * InheritableThreadLocal
+ */
+ static final Object sentinel = new Object();
+
+ /**
+ * The base for the computation of the next hash for a thread local.
+ */
+ private static int nextHashBase = 1;
+
+ /**
+ * Allocate a new hash.
+ */
+ private synchronized int computeNextHash()
+ {
+ return nextHashBase++ * 6709;
+ }
+
+ /**
+ * Hash code computed for ThreadLocalMap
+ */
+ final int fastHash;
+
+ /**
+ * Creates a ThreadLocal object without associating any value to it yet.
+ */
+ public ThreadLocal()
+ {
+ constructNative();
+ fastHash = computeNextHash();
+ }
+
+ /**
+ * Called once per thread on the first invocation of get(), if set() was
+ * not already called. The default implementation returns <code>null</code>.
+ * Often, this method is overridden to create the appropriate initial object
+ * for the current thread's view of the ThreadLocal.
+ *
+ * @return the initial value of the variable in this thread
+ */
+ protected T initialValue()
+ {
+ return null;
+ }
+
+ /**
+ * Gets the value associated with the ThreadLocal object for the currently
+ * executing Thread. If this is the first time the current thread has called
+ * get(), and it has not already called set(), the value is obtained by
+ * <code>initialValue()</code>.
+ *
+ * @return the value of the variable in this thread
+ */
+ public native T get();
+
+ private final Object internalGet()
+ {
+ ThreadLocalMap map = Thread.getThreadLocals();
+ // Note that we don't have to synchronize, as only this thread will
+ // ever modify the map.
+ T value = (T) map.get(this);
+ if (value == sentinel)
+ {
+ value = initialValue();
+ map.set(this, value);
+ }
+ return value;
+ }
+
+ /**
+ * Sets the value associated with the ThreadLocal object for the currently
+ * executing Thread. This overrides any existing value associated with the
+ * current Thread and prevents <code>initialValue()</code> from being
+ * called if this is the first access to this ThreadLocal in this Thread.
+ *
+ * @param value the value to set this thread's view of the variable to
+ */
+ public native void set(T value);
+
+ private final void internalSet(Object value)
+ {
+ ThreadLocalMap map = Thread.getThreadLocals();
+ // Note that we don't have to synchronize, as only this thread will
+ // ever modify the map.
+ map.set(this, value);
+ }
+
+ /**
+ * Removes the value associated with the ThreadLocal object for the
+ * currently executing Thread.
+ * @since 1.5
+ */
+ public native void remove();
+
+ private final void internalRemove()
+ {
+ ThreadLocalMap map = Thread.getThreadLocals();
+ map.remove(this);
+ }
+
+ protected native void finalize () throws Throwable;
+
+ private native void constructNative();
+
+ private gnu.gcj.RawData TLSPointer;
+}
diff --git a/libjava/java/lang/ThreadLocalMap$Entry.h b/libjava/java/lang/ThreadLocalMap$Entry.h
new file mode 100644
index 000000000..51b4db9c2
--- /dev/null
+++ b/libjava/java/lang/ThreadLocalMap$Entry.h
@@ -0,0 +1,21 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ThreadLocalMap$Entry__
+#define __java_lang_ThreadLocalMap$Entry__
+
+#pragma interface
+
+#include <java/lang/ref/WeakReference.h>
+
+class java::lang::ThreadLocalMap$Entry : public ::java::lang::ref::WeakReference
+{
+
+public: // actually package-private
+ ThreadLocalMap$Entry(::java::lang::ThreadLocal *);
+ ::java::lang::Object * __attribute__((aligned(__alignof__( ::java::lang::ref::WeakReference)))) value;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ThreadLocalMap$Entry__
diff --git a/libjava/java/lang/ThreadLocalMap.h b/libjava/java/lang/ThreadLocalMap.h
new file mode 100644
index 000000000..3a1f107cf
--- /dev/null
+++ b/libjava/java/lang/ThreadLocalMap.h
@@ -0,0 +1,41 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ThreadLocalMap__
+#define __java_lang_ThreadLocalMap__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::ThreadLocalMap : public ::java::lang::Object
+{
+
+public: // actually package-private
+ ThreadLocalMap();
+private:
+ void newEntryArray(jint);
+ void overflow();
+public:
+ ::java::lang::Object * get(::java::lang::ThreadLocal *);
+ void set(::java::lang::ThreadLocal *, ::java::lang::Object *);
+ void remove(::java::lang::ThreadLocal *);
+public: // actually package-private
+ void clear();
+public:
+ void inherit(::java::lang::ThreadLocalMap *);
+private:
+ static const jint LOG_INITIAL_SIZE = 3;
+ static jfloat MAX_OCCUPANCY;
+ static jfloat TARGET_OCCUPANCY;
+ static ::java::lang::ThreadLocalMap$Entry * deletedEntry;
+ JArray< ::java::lang::ThreadLocalMap$Entry * > * __attribute__((aligned(__alignof__( ::java::lang::Object)))) entries;
+ jint hashMask;
+ jint count;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ThreadLocalMap__
diff --git a/libjava/java/lang/Throwable$StaticData.h b/libjava/java/lang/Throwable$StaticData.h
new file mode 100644
index 000000000..6bb0912de
--- /dev/null
+++ b/libjava/java/lang/Throwable$StaticData.h
@@ -0,0 +1,21 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Throwable$StaticData__
+#define __java_lang_Throwable$StaticData__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Throwable$StaticData : public ::java::lang::Object
+{
+
+ Throwable$StaticData();
+public: // actually package-private
+ static ::java::lang::String * nl;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Throwable$StaticData__
diff --git a/libjava/java/lang/Throwable.h b/libjava/java/lang/Throwable.h
new file mode 100644
index 000000000..2e7532c3a
--- /dev/null
+++ b/libjava/java/lang/Throwable.h
@@ -0,0 +1,59 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Throwable__
+#define __java_lang_Throwable__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace java
+ {
+ namespace lang
+ {
+ class CPStringBuilder;
+ }
+ }
+ }
+}
+
+class java::lang::Throwable : public ::java::lang::Object
+{
+
+public:
+ Throwable();
+ Throwable(::java::lang::String *);
+ Throwable(::java::lang::String *, ::java::lang::Throwable *);
+ Throwable(::java::lang::Throwable *);
+ virtual ::java::lang::String * getMessage();
+ virtual ::java::lang::String * getLocalizedMessage();
+ virtual ::java::lang::Throwable * getCause();
+ virtual ::java::lang::Throwable * initCause(::java::lang::Throwable *);
+ virtual ::java::lang::String * toString();
+ virtual void printStackTrace();
+ virtual void printStackTrace(::java::io::PrintStream *);
+ virtual void printStackTrace(::java::io::PrintWriter *);
+private:
+ ::java::lang::String * stackTraceString();
+ static void stackTraceStringBuffer(::gnu::java::lang::CPStringBuilder *, ::java::lang::String *, JArray< ::java::lang::StackTraceElement * > *, jint);
+public:
+ virtual ::java::lang::Throwable * fillInStackTrace();
+ virtual JArray< ::java::lang::StackTraceElement * > * getStackTrace();
+ virtual void setStackTrace(JArray< ::java::lang::StackTraceElement * > *);
+private:
+ static const jlong serialVersionUID = -3042686055658047285LL;
+ ::java::lang::String * __attribute__((aligned(__alignof__( ::java::lang::Object)))) detailMessage;
+ ::java::lang::Throwable * cause;
+ JArray< ::java::lang::StackTraceElement * > * stackTrace;
+ ::java::lang::VMThrowable * vmState;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Throwable__
diff --git a/libjava/java/lang/TypeNotPresentException.h b/libjava/java/lang/TypeNotPresentException.h
new file mode 100644
index 000000000..076f0a6d4
--- /dev/null
+++ b/libjava/java/lang/TypeNotPresentException.h
@@ -0,0 +1,24 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_TypeNotPresentException__
+#define __java_lang_TypeNotPresentException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::TypeNotPresentException : public ::java::lang::RuntimeException
+{
+
+public:
+ TypeNotPresentException(::java::lang::String *, ::java::lang::Throwable *);
+ virtual ::java::lang::String * typeName();
+private:
+ static const jlong serialVersionUID = -5101214195716534496LL;
+ ::java::lang::String * __attribute__((aligned(__alignof__( ::java::lang::RuntimeException)))) typeName__;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_TypeNotPresentException__
diff --git a/libjava/java/lang/UnknownError.h b/libjava/java/lang/UnknownError.h
new file mode 100644
index 000000000..2ed851aae
--- /dev/null
+++ b/libjava/java/lang/UnknownError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_UnknownError__
+#define __java_lang_UnknownError__
+
+#pragma interface
+
+#include <java/lang/VirtualMachineError.h>
+
+class java::lang::UnknownError : public ::java::lang::VirtualMachineError
+{
+
+public:
+ UnknownError();
+ UnknownError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 2524784860676771849LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_UnknownError__
diff --git a/libjava/java/lang/UnsatisfiedLinkError.h b/libjava/java/lang/UnsatisfiedLinkError.h
new file mode 100644
index 000000000..a560313fe
--- /dev/null
+++ b/libjava/java/lang/UnsatisfiedLinkError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_UnsatisfiedLinkError__
+#define __java_lang_UnsatisfiedLinkError__
+
+#pragma interface
+
+#include <java/lang/LinkageError.h>
+
+class java::lang::UnsatisfiedLinkError : public ::java::lang::LinkageError
+{
+
+public:
+ UnsatisfiedLinkError();
+ UnsatisfiedLinkError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -4019343241616879428LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_UnsatisfiedLinkError__
diff --git a/libjava/java/lang/UnsupportedClassVersionError.h b/libjava/java/lang/UnsupportedClassVersionError.h
new file mode 100644
index 000000000..afa5b1875
--- /dev/null
+++ b/libjava/java/lang/UnsupportedClassVersionError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_UnsupportedClassVersionError__
+#define __java_lang_UnsupportedClassVersionError__
+
+#pragma interface
+
+#include <java/lang/ClassFormatError.h>
+
+class java::lang::UnsupportedClassVersionError : public ::java::lang::ClassFormatError
+{
+
+public:
+ UnsupportedClassVersionError();
+ UnsupportedClassVersionError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -7123279212883497373LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_UnsupportedClassVersionError__
diff --git a/libjava/java/lang/UnsupportedOperationException.h b/libjava/java/lang/UnsupportedOperationException.h
new file mode 100644
index 000000000..ce808bded
--- /dev/null
+++ b/libjava/java/lang/UnsupportedOperationException.h
@@ -0,0 +1,25 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_UnsupportedOperationException__
+#define __java_lang_UnsupportedOperationException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::UnsupportedOperationException : public ::java::lang::RuntimeException
+{
+
+public:
+ UnsupportedOperationException();
+ UnsupportedOperationException(::java::lang::String *);
+ UnsupportedOperationException(::java::lang::String *, ::java::lang::Throwable *);
+ UnsupportedOperationException(::java::lang::Throwable *);
+private:
+ static const jlong serialVersionUID = -1242599979055084673LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_UnsupportedOperationException__
diff --git a/libjava/java/lang/VMClassLoader.h b/libjava/java/lang/VMClassLoader.h
new file mode 100644
index 000000000..dce7092bf
--- /dev/null
+++ b/libjava/java/lang/VMClassLoader.h
@@ -0,0 +1,74 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_VMClassLoader__
+#define __java_lang_VMClassLoader__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class BootClassLoader;
+ }
+ }
+ }
+ namespace java
+ {
+ namespace net
+ {
+ class URL;
+ }
+ namespace security
+ {
+ class Permission;
+ class ProtectionDomain;
+ }
+ }
+}
+
+class java::lang::VMClassLoader : public ::java::lang::Object
+{
+
+public: // actually package-private
+ VMClassLoader();
+ static ::java::lang::Class * defineClass(::java::lang::ClassLoader *, ::java::lang::String *, JArray< jbyte > *, jint, jint, ::java::security::ProtectionDomain *);
+ static void resolveClass(::java::lang::Class *);
+ static ::java::lang::Class * loadClass(::java::lang::String *, jboolean);
+ static ::java::net::URL * getResource(::java::lang::String *);
+ static ::java::util::Enumeration * getResources(::java::lang::String *);
+ static ::java::lang::Package * getPackage(::java::lang::String *);
+ static JArray< ::java::lang::Package * > * getPackages();
+ static void definePackageForNative(::java::lang::String *);
+ static ::java::lang::Class * getPrimitiveClass(jchar);
+ static jboolean defaultAssertionStatus();
+ static ::java::util::Map * packageAssertionStatus();
+ static ::java::util::Map * classAssertionStatus();
+ static ::java::lang::ClassLoader * getSystemClassLoaderInternal();
+ static void initBootLoader(::java::lang::String *);
+ static void initialize(::java::lang::String *);
+ static ::java::lang::Class * nativeFindClass(::java::lang::String *);
+ static ::java::lang::ClassLoader * getSystemClassLoader();
+ static ::java::security::Permission * protectionDomainPermission;
+ static ::java::security::ProtectionDomain * unknownProtectionDomain;
+ static ::java::util::HashMap * definedPackages;
+ static ::gnu::gcj::runtime::BootClassLoader * bootLoader;
+private:
+ static ::java::util::HashSet * tried_libraries;
+ static jint lib_control;
+ static const jint LIB_FULL = 0;
+ static const jint LIB_CACHE = 1;
+ static const jint LIB_NEVER = 2;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_VMClassLoader__
diff --git a/libjava/java/lang/VMClassLoader.java b/libjava/java/lang/VMClassLoader.java
new file mode 100644
index 000000000..21019b757
--- /dev/null
+++ b/libjava/java/lang/VMClassLoader.java
@@ -0,0 +1,348 @@
+/* VMClassLoader.java -- Reference implementation of native interface
+ required by ClassLoader
+ Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import gnu.java.util.EmptyEnumeration;
+import java.lang.reflect.Constructor;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.AllPermission;
+import java.security.Permission;
+import java.security.Permissions;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.StringTokenizer;
+import gnu.gcj.runtime.BootClassLoader;
+
+/**
+ * java.lang.VMClassLoader is a package-private helper for VMs to implement
+ * on behalf of java.lang.ClassLoader.
+ *
+ * @author John Keiser
+ * @author Mark Wielaard <mark@klomp.org>
+ * @author Eric Blake <ebb9@email.byu.edu>
+ */
+final class VMClassLoader
+{
+ // Protection Domain definitions
+ // FIXME: should there be a special protection domain used for native code?
+
+ // The permission required to check what a classes protection domain is.
+ static final Permission protectionDomainPermission
+ = new RuntimePermission("getProtectionDomain");
+ // The protection domain returned if we cannot determine it.
+ static ProtectionDomain unknownProtectionDomain;
+
+ static
+ {
+ Permissions permissions = new Permissions();
+ permissions.add(new AllPermission());
+ unknownProtectionDomain = new ProtectionDomain(null, permissions);
+ }
+
+ static final HashMap definedPackages = new HashMap();
+
+ // This is a helper for handling java.endorsed.dirs. It is null
+ // until we've initialized the system, at which point it is created.
+ static BootClassLoader bootLoader;
+
+ // This keeps track of shared libraries we've already tried to load.
+ private static HashSet tried_libraries;
+
+ // Holds one of the LIB_* constants; used to determine how shared
+ // library loads are done.
+ private static int lib_control;
+
+ private static final int LIB_FULL = 0;
+ private static final int LIB_CACHE = 1;
+ private static final int LIB_NEVER = 2;
+
+ /**
+ * Helper to define a class using a string of bytes. This assumes that
+ * the security checks have already been performed, if necessary.
+ *
+ * <strong>For backward compatibility, this just ignores the protection
+ * domain; that is the wrong behavior, and you should directly implement
+ * this method natively if you can.</strong>
+ *
+ * @param name the name to give the class, or null if unknown
+ * @param data the data representing the classfile, in classfile format
+ * @param offset the offset into the data where the classfile starts
+ * @param len the length of the classfile data in the array
+ * @param pd the protection domain
+ * @return the class that was defined
+ * @throws ClassFormatError if data is not in proper classfile format
+ */
+ static final native Class defineClass(ClassLoader cl, String name,
+ byte[] data, int offset, int len,
+ ProtectionDomain pd)
+ throws ClassFormatError;
+
+ /**
+ * Helper to resolve all references to other classes from this class.
+ *
+ * @param c the class to resolve
+ */
+ static final void resolveClass(Class clazz)
+ {
+ // There doesn't seem to be a need for this to do anything.
+ // Testing reveals that the JDK doesn't seem to do anything here,
+ // either.
+ }
+
+ /**
+ * Helper to load a class from the bootstrap class loader.
+ *
+ * @param name the class name to load
+ * @param resolve whether to resolve it
+ * @return the class, loaded by the bootstrap classloader or null
+ * if the class wasn't found. Returning null is equivalent to throwing
+ * a ClassNotFoundException (but a possible performance optimization).
+ */
+ static final native Class loadClass(String name, boolean resolve)
+ throws ClassNotFoundException;
+
+ /**
+ * Helper to load a resource from the bootstrap class loader.
+ *
+ * In libgcj, this does nothing, as the default system loader knows
+ * how to find resources that have been linked in.
+ *
+ * @param name the resource to find
+ * @return the URL to the resource
+ */
+ static URL getResource(String name)
+ {
+ if (bootLoader != null)
+ return bootLoader.bootGetResource(name);
+ return null;
+ }
+
+ /**
+ * Helper to get a list of resources from the bootstrap class loader.
+ *
+ * In libgcj, this does nothing, as the default system loader knows
+ * how to find resources that have been linked in.
+ *
+ * @param name the resource to find
+ * @return an enumeration of resources
+ * @throws IOException if one occurs
+ */
+ static Enumeration getResources(String name) throws IOException
+ {
+ if (bootLoader != null)
+ return bootLoader.bootGetResources(name);
+ return EmptyEnumeration.getInstance();
+ }
+
+ /**
+ * Helper to get a package from the bootstrap class loader. The default
+ * implementation of returning null may be adequate, or you may decide
+ * that this needs some native help.
+ *
+ * @param name the name to find
+ * @return the named package, if it exists
+ */
+ static synchronized Package getPackage(String name)
+ {
+ return (Package) definedPackages.get(name);
+ }
+
+ /**
+ * Helper to get all packages from the bootstrap class loader. The default
+ * implementation of returning an empty array may be adequate, or you may
+ * decide that this needs some native help.
+ *
+ * @return all named packages, if any exist
+ */
+ static synchronized Package[] getPackages()
+ {
+ Package[] packages = new Package[definedPackages.size()];
+ return (Package[]) definedPackages.values().toArray(packages);
+ }
+
+ // Define a package for something loaded natively.
+ static synchronized void definePackageForNative(String className)
+ {
+ int lastDot = className.lastIndexOf('.');
+ if (lastDot != -1)
+ {
+ String packageName = className.substring(0, lastDot);
+ if (getPackage(packageName) == null)
+ {
+ // FIXME: this assumes we're defining the core, which
+ // isn't necessarily so. We could detect this and set up
+ // appropriately. We could also look at a manifest file
+ // compiled into the .so.
+ Package p = new Package(packageName,
+ "Java Platform API Specification",
+ "GNU", "1.4", "gcj", "GNU",
+ null, // FIXME: gcj version.
+ null);
+ definedPackages.put(packageName, p);
+ }
+ }
+ }
+
+ /**
+ * Helper for java.lang.Integer, Byte, etc to get the TYPE class
+ * at initialization time. The type code is one of the chars that
+ * represents the primitive type as in JNI.
+ *
+ * <ul>
+ * <li>'Z' - boolean</li>
+ * <li>'B' - byte</li>
+ * <li>'C' - char</li>
+ * <li>'D' - double</li>
+ * <li>'F' - float</li>
+ * <li>'I' - int</li>
+ * <li>'J' - long</li>
+ * <li>'S' - short</li>
+ * <li>'V' - void</li>
+ * </ul>
+ *
+ * @param type the primitive type
+ * @return a "bogus" class representing the primitive type
+ */
+ static final native Class getPrimitiveClass(char type);
+
+ /**
+ * The system default for assertion status. This is used for all system
+ * classes (those with a null ClassLoader), as well as the initial value for
+ * every ClassLoader's default assertion status.
+ *
+ * XXX - Not implemented yet; this requires native help.
+ *
+ * @return the system-wide default assertion status
+ */
+ static final boolean defaultAssertionStatus()
+ {
+ return true;
+ }
+
+ /**
+ * The system default for package assertion status. This is used for all
+ * ClassLoader's packageAssertionStatus defaults. It must be a map of
+ * package names to Boolean.TRUE or Boolean.FALSE, with the unnamed package
+ * represented as a null key.
+ *
+ * XXX - Not implemented yet; this requires native help.
+ *
+ * @return a (read-only) map for the default packageAssertionStatus
+ */
+ static final Map packageAssertionStatus()
+ {
+ return new HashMap();
+ }
+
+ /**
+ * The system default for class assertion status. This is used for all
+ * ClassLoader's classAssertionStatus defaults. It must be a map of
+ * class names to Boolean.TRUE or Boolean.FALSE
+ *
+ * XXX - Not implemented yet; this requires native help.
+ *
+ * @return a (read-only) map for the default classAssertionStatus
+ */
+ static final Map classAssertionStatus()
+ {
+ return new HashMap();
+ }
+
+ static native ClassLoader getSystemClassLoaderInternal();
+
+ static native void initBootLoader(String libdir);
+
+ static void initialize(String libdir)
+ {
+ initBootLoader(libdir);
+
+ String p
+ = System.getProperty ("gnu.gcj.runtime.VMClassLoader.library_control",
+ "");
+ if ("never".equals(p))
+ lib_control = LIB_NEVER;
+ else if ("cache".equals(p))
+ lib_control = LIB_CACHE;
+ else if ("full".equals(p))
+ lib_control = LIB_FULL;
+ else
+ lib_control = LIB_NEVER;
+
+ tried_libraries = new HashSet();
+ }
+
+ /**
+ * Possibly load a .so and search it for classes.
+ */
+ static native Class nativeFindClass(String name);
+
+ static ClassLoader getSystemClassLoader()
+ {
+ // This method is called as the initialization of systemClassLoader,
+ // so if there is a null value, this is the first call and we must check
+ // for java.system.class.loader.
+ String loader = System.getProperty("java.system.class.loader");
+ ClassLoader default_sys = getSystemClassLoaderInternal();
+ if (loader != null)
+ {
+ try
+ {
+ Class load_class = Class.forName(loader, true, default_sys);
+ Constructor c
+ = load_class.getConstructor(new Class[] { ClassLoader.class });
+ default_sys
+ = (ClassLoader) c.newInstance(new Object[] { default_sys });
+ }
+ catch (Exception ex)
+ {
+ throw new Error("Failed to load requested system classloader "
+ + loader, ex);
+ }
+ }
+
+ return default_sys;
+ }
+}
diff --git a/libjava/java/lang/VMCompiler.h b/libjava/java/lang/VMCompiler.h
new file mode 100644
index 000000000..e81f694e1
--- /dev/null
+++ b/libjava/java/lang/VMCompiler.h
@@ -0,0 +1,64 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_VMCompiler__
+#define __java_lang_VMCompiler__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace java
+ {
+ namespace security
+ {
+ namespace hash
+ {
+ class MD5;
+ }
+ }
+ }
+ }
+ namespace java
+ {
+ namespace security
+ {
+ class ProtectionDomain;
+ }
+ }
+}
+
+class java::lang::VMCompiler : public ::java::lang::Object
+{
+
+public:
+ static jboolean precompiles();
+private:
+ VMCompiler();
+ static ::java::lang::Class * loadSharedLibrary(::java::lang::ClassLoader *, ::java::lang::String *, ::java::security::ProtectionDomain *, ::java::lang::String *);
+public:
+ static ::java::lang::Class * compileClass(::java::lang::ClassLoader *, ::java::lang::String *, JArray< jbyte > *, jint, jint, ::java::security::ProtectionDomain *);
+ static jboolean compileClass(::java::lang::Class *);
+ static jboolean compileClasses(::java::lang::String *);
+ static ::java::lang::Object * command(::java::lang::Object *);
+ static void enable();
+ static void disable();
+ static jboolean useCompiler;
+ static jboolean canUseCompiler;
+ static ::java::lang::String * gcjJitCompiler;
+ static ::java::lang::String * gcjJitCompilerOptions;
+ static ::java::lang::String * gcjJitTmpdir;
+private:
+ static ::java::util::WeakHashMap * sharedHelperMap;
+ static ::java::util::Vector * precompiledMapFiles;
+ static ::gnu::java::security::hash::MD5 * md5Digest;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_VMCompiler__
diff --git a/libjava/java/lang/VMCompiler.java b/libjava/java/lang/VMCompiler.java
new file mode 100644
index 000000000..1f600f12e
--- /dev/null
+++ b/libjava/java/lang/VMCompiler.java
@@ -0,0 +1,369 @@
+/* VMClassLoader.java -- Reference implementation of compiler interface
+ Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.security.MessageDigest;
+import java.security.ProtectionDomain;
+import java.security.NoSuchAlgorithmException;
+import java.util.WeakHashMap;
+import java.util.HashSet;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import gnu.gcj.runtime.SharedLibHelper;
+import gnu.gcj.runtime.PersistentByteMap;
+import gnu.java.security.hash.MD5;
+
+/**
+ * This class is just a per-VM reflection of java.lang.Compiler.
+ * All methods are defined identically.
+ */
+final class VMCompiler
+{
+ // True if we want to use gcj-jit.
+ public static boolean useCompiler = true;
+
+ // True if we're able to use gcj-jit.
+ public static final boolean canUseCompiler;
+
+ // Compiler to use.
+ public static String gcjJitCompiler;
+
+ // Compiler options.
+ public static String gcjJitCompilerOptions;
+
+ // Temporary directory to use.
+ public static String gcjJitTmpdir;
+
+ public static boolean precompiles()
+ {
+ return (canUseCompiler & useCompiler);
+ }
+
+ // This maps a ClassLoader to a set of SharedLibHelper objects that
+ // it has used. We do things this way to ensure that a
+ // SharedLibHelper is collected if and only if the ClassLoader is.
+ private static WeakHashMap sharedHelperMap = new WeakHashMap();
+
+ private static Vector precompiledMapFiles;
+
+ // We create a single MD5 engine and then clone it whenever we want
+ // a new one.
+
+ // We don't use
+ //
+ // md5Digest = MessageDigest.getInstance("MD5");
+ //
+ // here because that loads a great deal of security provider code as
+ // interpreted bytecode -- before we're able to use this class to
+ // load precompiled classes.
+
+ private static final MD5 md5Digest
+ = new gnu.java.security.hash.MD5();
+
+ static
+ {
+ gcjJitCompiler = System.getProperty("gnu.gcj.jit.compiler");
+ if (gcjJitCompiler == null)
+ canUseCompiler = false;
+ else
+ {
+ gcjJitCompilerOptions = System.getProperty("gnu.gcj.jit.options",
+ "-g");
+ gcjJitTmpdir = System.getProperty("gnu.gcj.jit.cachedir");
+ // Note that we *don't* choose java.io.tmpdir as a default --
+ // that would allow easy attacks against the VM.
+ if (gcjJitTmpdir == null)
+ canUseCompiler = false;
+ else
+ canUseCompiler = true;
+ }
+
+ String prop = System.getProperty ("gnu.gcj.precompiled.db.path");
+ if (prop != null)
+ {
+ precompiledMapFiles = new Vector();
+ // Add the
+ StringTokenizer st
+ = new StringTokenizer (prop,
+ System.getProperty ("path.separator", ":"));
+ {
+ while (st.hasMoreElements ())
+ {
+ String e = st.nextToken ();
+ try
+ {
+ PersistentByteMap map
+ = new PersistentByteMap
+ (e, PersistentByteMap.AccessMode.READ_ONLY);
+ precompiledMapFiles.add(map);
+ }
+ catch (IllegalArgumentException _)
+ {
+ // Not a map file
+ }
+ catch (java.io.IOException _)
+ {
+ }
+ catch (java.nio.BufferUnderflowException _)
+ {
+ // Invalid map file.
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Don't allow new `Compiler's to be made.
+ */
+ private VMCompiler()
+ {
+ }
+
+ private static Class loadSharedLibrary(ClassLoader loader,
+ String fileName,
+ ProtectionDomain domain,
+ String className)
+ {
+ Class c = null;
+ SharedLibHelper helper
+ = SharedLibHelper.findHelper (loader, fileName, domain.getCodeSource(),
+ domain, false);
+ c = helper.findClass (className);
+ if (c != null)
+ {
+ HashSet hs = (HashSet) sharedHelperMap.get(loader);
+ if (hs == null)
+ {
+ hs = new HashSet();
+ sharedHelperMap.put(loader, hs);
+ }
+ hs.add(helper);
+ }
+ return c;
+ }
+
+ /**
+ * Compile a class given the bytes for it. Returns the Class, or
+ * null if compilation failed or otherwise could not be done.
+ */
+ public static Class compileClass(ClassLoader loader,
+ String name, byte[] data,
+ int offset, int len,
+ ProtectionDomain domain)
+ {
+ if (precompiledMapFiles == null && !precompiles())
+ return null;
+
+ byte digest[];
+
+ try
+ {
+ MD5 md = (MD5) md5Digest.clone();
+ md.update(data);
+ digest = md.digest();
+ }
+ catch (NullPointerException _)
+ {
+ // If md5Digest==null -- but really this should never happen
+ // either, since the MD5 digest is in libgcj.
+ return null;
+ }
+
+ // We use lookaside cache files to determine whether these bytes
+ // correspond to a class file that is part of a precompiled DSO.
+ if (precompiledMapFiles != null)
+ {
+ try
+ {
+ Enumeration elements = precompiledMapFiles.elements();
+ while (elements.hasMoreElements())
+ {
+ PersistentByteMap map = (PersistentByteMap)elements.nextElement();
+ byte[] soName = map.get(digest);
+ if (soName != null)
+ return loadSharedLibrary(loader,
+ new String(soName),
+ domain, name);
+ }
+ }
+ catch (Exception _)
+ {
+ }
+ catch (UnknownError _)
+ {
+ // SharedLibHelper will throw UnknownError if the dlopen
+ // fails for some reason. We ignore it and continue on.
+ }
+ }
+
+ if (!precompiles())
+ return null;
+
+ try
+ {
+ // FIXME: Make sure that the class represented by the
+ // bytes in DATA really is the class named in NAME. Make
+ // sure it's not "java.*".
+ StringBuffer hexBytes = new StringBuffer(gcjJitTmpdir);
+ hexBytes.append(File.separatorChar);
+ int digestLength = digest.length;
+ for (int i = 0; i < digestLength; ++i)
+ {
+ int v = digest[i] & 0xff;
+ if (v < 16)
+ hexBytes.append('0');
+ hexBytes.append(Integer.toHexString(v));
+ }
+
+ // FIXME: use System.mapLibraryName?
+ // I'm thinking we should use that, plus a class specified
+ // via a property that determines lookup policy.
+ File soFile = new File(hexBytes + ".so");
+ if (soFile.isFile())
+ return loadSharedLibrary (loader, soFile.toString(), domain,
+ name);
+
+ File classFile = new File(hexBytes + ".class");
+ classFile.delete();
+ if (classFile.createNewFile() != true)
+ return null;
+
+ FileOutputStream f = new FileOutputStream (classFile);
+ // FIXME: race condition if bytes change... ?
+ f.write(data, offset, len);
+
+ // Invoke the compiler.
+ StringBuffer command = new StringBuffer(gcjJitCompiler);
+ command.append(" ");
+ command.append(classFile);
+ command.append(" ");
+ command.append(gcjJitCompilerOptions);
+ // These options are required.
+ command.append(" -findirect-dispatch -fjni -shared -fPIC -o ");
+ command.append(soFile);
+ Process p = Runtime.getRuntime().exec(command.toString());
+
+ // Read the process' stderr into a string.
+ StringBuffer err = new StringBuffer();
+ InputStreamReader stderr = new InputStreamReader (p.getErrorStream());
+ char[] inBuf = new char[500];
+ int bytesRead;
+ while ((bytesRead = stderr.read (inBuf)) != -1)
+ err.append(inBuf, 0, bytesRead);
+
+ if (p.waitFor() != 0)
+ {
+ // FIXME: we could log err.toString() somewhere...
+ return null;
+ }
+
+ return loadSharedLibrary(loader, soFile.toString(), domain, name);
+ }
+ catch (Exception _)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Compile the class named by <code>oneClass</code>.
+ *
+ * @param oneClass the class to compile
+ * @return <code>false</code> if no compiler is available or
+ * compilation failed, <code>true</code> if compilation succeeded
+ * @throws NullPointerException if oneClass is null
+ */
+ public static boolean compileClass(Class oneClass)
+ {
+ // Never succeed.
+ return false;
+ }
+
+ /**
+ * Compile the classes whose name matches <code>classNames</code>.
+ *
+ * @param classNames the name of classes to compile
+ * @return <code>false</code> if no compiler is available or
+ * compilation failed, <code>true</code> if compilation succeeded
+ * @throws NullPointerException if classNames is null
+ */
+ public static boolean compileClasses(String classNames)
+ {
+ // Note the incredibly lame interface. Always fail.
+ return false;
+ }
+
+ /**
+ * This method examines the argument and performs an operation
+ * according to the compilers documentation. No specific operation
+ * is required.
+ *
+ * @param arg a compiler-specific argument
+ * @return a compiler-specific value, including null
+ * @throws NullPointerException if the compiler doesn't like a null arg
+ */
+ public static Object command(Object arg)
+ {
+ // Our implementation defines this to a no-op.
+ return null;
+ }
+
+ /**
+ * Calling <code>Compiler.enable()</code> will cause the compiler
+ * to resume operation if it was previously disabled; provided that a
+ * compiler even exists.
+ */
+ public static void enable()
+ {
+ useCompiler = true;
+ }
+
+ /**
+ * Calling <code>Compiler.disable()</code> will cause the compiler
+ * to be suspended; provided that a compiler even exists.
+ */
+ public static void disable()
+ {
+ useCompiler = false;
+ }
+}
diff --git a/libjava/java/lang/VMDouble.h b/libjava/java/lang/VMDouble.h
new file mode 100644
index 000000000..76b6d5020
--- /dev/null
+++ b/libjava/java/lang/VMDouble.h
@@ -0,0 +1,25 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_VMDouble__
+#define __java_lang_VMDouble__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::VMDouble : public ::java::lang::Object
+{
+
+public: // actually package-private
+ VMDouble();
+public:
+ static jlong doubleToLongBits(jdouble);
+ static jlong doubleToRawLongBits(jdouble);
+ static jdouble longBitsToDouble(jlong);
+ static ::java::lang::String * toString(jdouble, jboolean);
+ static jdouble parseDouble(::java::lang::String *);
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_VMDouble__
diff --git a/libjava/java/lang/VMDouble.java b/libjava/java/lang/VMDouble.java
new file mode 100644
index 000000000..9205eb3b3
--- /dev/null
+++ b/libjava/java/lang/VMDouble.java
@@ -0,0 +1,111 @@
+/* VMDouble.java -- VM Specific Double methods
+ Copyright (C) 2003, 2005, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import gnu.classpath.Configuration;
+
+/*
+ * This class is a reference version, mainly for compiling a class library
+ * jar. It is likely that VM implementers replace this with their own
+ * version that can communicate effectively with the VM.
+ */
+
+/**
+ * Code relocated from java.lang.Double by
+ * @author Dave Grove (groved@us.ibm.com)
+ */
+final class VMDouble
+{
+ /**
+ * Convert the double to the IEEE 754 floating-point "double format" bit
+ * layout. Bit 63 (the most significant) is the sign bit, bits 62-52
+ * (masked by 0x7ff0000000000000L) represent the exponent, and bits 51-0
+ * (masked by 0x000fffffffffffffL) are the mantissa. This function
+ * collapses all versions of NaN to 0x7ff8000000000000L. The result of this
+ * function can be used as the argument to
+ * <code>Double.longBitsToDouble(long)</code> to obtain the original
+ * <code>double</code> value.
+ *
+ * @param value the <code>double</code> to convert
+ * @return the bits of the <code>double</code>
+ * @see #longBitsToDouble(long)
+ */
+ public static native long doubleToLongBits(double value);
+
+ /**
+ * Convert the double to the IEEE 754 floating-point "double format" bit
+ * layout. Bit 63 (the most significant) is the sign bit, bits 62-52
+ * (masked by 0x7ff0000000000000L) represent the exponent, and bits 51-0
+ * (masked by 0x000fffffffffffffL) are the mantissa. This function
+ * leaves NaN alone, rather than collapsing to a canonical value. The
+ * result of this function can be used as the argument to
+ * <code>Double.longBitsToDouble(long)</code> to obtain the original
+ * <code>double</code> value.
+ *
+ * @param value the <code>double</code> to convert
+ * @return the bits of the <code>double</code>
+ * @see #longBitsToDouble(long)
+ */
+ public static native long doubleToRawLongBits(double value);
+
+ /**
+ * Convert the argument in IEEE 754 floating-point "double format" bit
+ * layout to the corresponding float. Bit 63 (the most significant) is the
+ * sign bit, bits 62-52 (masked by 0x7ff0000000000000L) represent the
+ * exponent, and bits 51-0 (masked by 0x000fffffffffffffL) are the mantissa.
+ * This function leaves NaN alone, so that you can recover the bit pattern
+ * with <code>Double.doubleToRawLongBits(double)</code>.
+ *
+ * @param bits the bits to convert
+ * @return the <code>double</code> represented by the bits
+ * @see #doubleToLongBits(double)
+ * @see #doubleToRawLongBits(double)
+ */
+ public static native double longBitsToDouble(long bits);
+
+ /**
+ * Helper method to convert to string.
+ *
+ * @param d the double to convert
+ * @param isFloat true if the conversion is requested by Float (results in
+ * fewer digits)
+ */
+ public static native String toString(double d, boolean isFloat);
+
+ public static native double parseDouble(String str);
+}
diff --git a/libjava/java/lang/VMFloat.h b/libjava/java/lang/VMFloat.h
new file mode 100644
index 000000000..fec037b2c
--- /dev/null
+++ b/libjava/java/lang/VMFloat.h
@@ -0,0 +1,25 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_VMFloat__
+#define __java_lang_VMFloat__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::VMFloat : public ::java::lang::Object
+{
+
+public: // actually package-private
+ VMFloat();
+ static jint floatToIntBits(jfloat);
+ static jint floatToRawIntBits(jfloat);
+ static jfloat intBitsToFloat(jint);
+ static ::java::lang::String * toString(jfloat);
+ static jfloat parseFloat(::java::lang::String *);
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_VMFloat__
diff --git a/libjava/java/lang/VMFloat.java b/libjava/java/lang/VMFloat.java
new file mode 100644
index 000000000..72a8c3c6b
--- /dev/null
+++ b/libjava/java/lang/VMFloat.java
@@ -0,0 +1,121 @@
+/* VMFloat.java -- VM Specific Float methods
+ Copyright (C) 2003, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import gnu.classpath.Configuration;
+
+/*
+ * This class is a reference version, mainly for compiling a class library
+ * jar. It is likely that VM implementers replace this with their own
+ * version that can communicate effectively with the VM.
+ */
+
+/**
+ * Code relocated from java.lang.Float by
+ * @author Dave Grove <groved@us.ibm.com>
+ */
+final class VMFloat
+{
+ /**
+ * Convert the float to the IEEE 754 floating-point "single format" bit
+ * layout. Bit 31 (the most significant) is the sign bit, bits 30-23
+ * (masked by 0x7f800000) represent the exponent, and bits 22-0
+ * (masked by 0x007fffff) are the mantissa. This function collapses all
+ * versions of NaN to 0x7fc00000. The result of this function can be used
+ * as the argument to <code>Float.intBitsToFloat(int)</code> to obtain the
+ * original <code>float</code> value.
+ *
+ * @param value the <code>float</code> to convert
+ * @return the bits of the <code>float</code>
+ * @see #intBitsToFloat(int)
+ */
+ static native int floatToIntBits(float value);
+
+ /**
+ * Convert the float to the IEEE 754 floating-point "single format" bit
+ * layout. Bit 31 (the most significant) is the sign bit, bits 30-23
+ * (masked by 0x7f800000) represent the exponent, and bits 22-0
+ * (masked by 0x007fffff) are the mantissa. This function leaves NaN alone,
+ * rather than collapsing to a canonical value. The result of this function
+ * can be used as the argument to <code>Float.intBitsToFloat(int)</code> to
+ * obtain the original <code>float</code> value.
+ *
+ * @param value the <code>float</code> to convert
+ * @return the bits of the <code>float</code>
+ * @see #intBitsToFloat(int)
+ */
+ static native int floatToRawIntBits(float value);
+
+ /**
+ * Convert the argument in IEEE 754 floating-point "single format" bit
+ * layout to the corresponding float. Bit 31 (the most significant) is the
+ * sign bit, bits 30-23 (masked by 0x7f800000) represent the exponent, and
+ * bits 22-0 (masked by 0x007fffff) are the mantissa. This function leaves
+ * NaN alone, so that you can recover the bit pattern with
+ * <code>Float.floatToRawIntBits(float)</code>.
+ *
+ * @param bits the bits to convert
+ * @return the <code>float</code> represented by the bits
+ * @see #floatToIntBits(float)
+ * @see #floatToRawIntBits(float)
+ */
+ static native float intBitsToFloat(int bits);
+
+ /**
+ * @param f the <code>float</code> to convert
+ * @return the <code>String</code> representing the <code>float</code>
+ */
+ static String toString(float f)
+ {
+ return VMDouble.toString(f, true);
+ }
+
+ /**
+ * @param str the <code>String</code> to convert
+ * @return the <code>float</code> value of <code>s</code>
+ * @throws NumberFormatException if <code>str</code> cannot be parsed as a
+ * <code>float</code>
+ * @throws NullPointerException if <code>str</code> is null
+ */
+ static float parseFloat(String str)
+ {
+ // XXX Rounding parseDouble() causes some errors greater than 1 ulp from
+ // the infinitely precise decimal.
+ return (float) Double.parseDouble(str);
+ }
+} // class VMFloat
diff --git a/libjava/java/lang/VMProcess.h b/libjava/java/lang/VMProcess.h
new file mode 100644
index 000000000..c0912e5c2
--- /dev/null
+++ b/libjava/java/lang/VMProcess.h
@@ -0,0 +1,24 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_VMProcess__
+#define __java_lang_VMProcess__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::VMProcess : public ::java::lang::Object
+{
+
+public: // actually package-private
+ VMProcess();
+ static ::java::lang::Process * nativeExec(JArray< ::java::lang::String * > *, JArray< ::java::lang::String * > *, ::java::io::File *, jboolean);
+ static ::java::lang::Process * exec(::java::util::List *, ::java::util::Map *, ::java::io::File *, jboolean);
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_VMProcess__
diff --git a/libjava/java/lang/VMProcess.java b/libjava/java/lang/VMProcess.java
new file mode 100644
index 000000000..c0c7bebc1
--- /dev/null
+++ b/libjava/java/lang/VMProcess.java
@@ -0,0 +1,68 @@
+/* java.lang.VMProcess -- VM implementation of java.lang.ProcessBuilder
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+final class VMProcess
+{
+ static native Process nativeExec(String[] cmd, String[] env,
+ File dir, boolean redirect)
+ throws IOException;
+
+ static Process exec(List<String> cmd, Map<String, String> 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 nativeExec(acmd, aenv, dir, redirect);
+ }
+}
diff --git a/libjava/java/lang/VMThrowable.h b/libjava/java/lang/VMThrowable.h
new file mode 100644
index 000000000..1991b6cd8
--- /dev/null
+++ b/libjava/java/lang/VMThrowable.h
@@ -0,0 +1,36 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_VMThrowable__
+#define __java_lang_VMThrowable__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ class RawDataManaged;
+ }
+ }
+}
+
+class java::lang::VMThrowable : public ::java::lang::Object
+{
+
+ VMThrowable();
+public: // actually package-private
+ static ::java::lang::VMThrowable * fillInStackTrace(::java::lang::Throwable *);
+ JArray< ::java::lang::StackTraceElement * > * getStackTrace(::java::lang::Throwable *);
+private:
+ ::gnu::gcj::RawDataManaged * __attribute__((aligned(__alignof__( ::java::lang::Object)))) data;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_VMThrowable__
diff --git a/libjava/java/lang/VMThrowable.java b/libjava/java/lang/VMThrowable.java
new file mode 100644
index 000000000..9dde28d29
--- /dev/null
+++ b/libjava/java/lang/VMThrowable.java
@@ -0,0 +1,82 @@
+/* java.lang.VMThrowable -- VM support methods for Throwable.
+ Copyright (C) 1998, 1999, 2002, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import gnu.gcj.RawDataManaged;
+
+/**
+ * VM dependent state and support methods Throwable.
+ * It is deliberately package local and final and should only be accessed
+ * by the Throwable class.
+ * <p>
+ * This is the version used by libgcj (http://gcc.gnu.org/java/).
+ *
+ * @author Mark Wielaard (mark@klomp.org)
+ */
+final class VMThrowable
+{
+ /**
+ * Private contructor, create VMThrowables with StackTrace();
+ */
+ private VMThrowable() { }
+
+ /**
+ * Fill in the stack trace with the current execution stack.
+ * Called by <code>Throwable.fillInStackTrace()</code> to get the state of
+ * the VM. Can return null when the VM does not support caputing the VM
+ * execution state.
+ *
+ * @return a new VMThrowable containing the current execution stack trace.
+ * @see Throwable#fillInStackTrace()
+ */
+ static native VMThrowable fillInStackTrace(Throwable t);
+
+ /**
+ * Returns an <code>StackTraceElement</code> array based on the execution
+ * state of the VM as captured by <code>fillInStackTrace</code>.
+ * Called by <code>Throwable.getStackTrace()</code>.
+ *
+ * @return a non-null but possible zero length array of StackTraceElement.
+ * @see Throwable#getStackTrace()
+ */
+ native StackTraceElement[] getStackTrace(Throwable t);
+
+ // Native stack data.
+ private RawDataManaged data;
+}
diff --git a/libjava/java/lang/VerifyError.h b/libjava/java/lang/VerifyError.h
new file mode 100644
index 000000000..54aafd27e
--- /dev/null
+++ b/libjava/java/lang/VerifyError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_VerifyError__
+#define __java_lang_VerifyError__
+
+#pragma interface
+
+#include <java/lang/LinkageError.h>
+
+class java::lang::VerifyError : public ::java::lang::LinkageError
+{
+
+public:
+ VerifyError();
+ VerifyError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 7001962396098498785LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_VerifyError__
diff --git a/libjava/java/lang/VirtualMachineError.h b/libjava/java/lang/VirtualMachineError.h
new file mode 100644
index 000000000..9eb04ceaa
--- /dev/null
+++ b/libjava/java/lang/VirtualMachineError.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_VirtualMachineError__
+#define __java_lang_VirtualMachineError__
+
+#pragma interface
+
+#include <java/lang/Error.h>
+
+class java::lang::VirtualMachineError : public ::java::lang::Error
+{
+
+public:
+ VirtualMachineError();
+ VirtualMachineError(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 4161983926571568670LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_VirtualMachineError__
diff --git a/libjava/java/lang/Void.h b/libjava/java/lang/Void.h
new file mode 100644
index 000000000..be277b02a
--- /dev/null
+++ b/libjava/java/lang/Void.h
@@ -0,0 +1,20 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Void__
+#define __java_lang_Void__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::Void : public ::java::lang::Object
+{
+
+ Void();
+public:
+ static ::java::lang::Class * TYPE;
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Void__
diff --git a/libjava/java/lang/Win32Process$EOFInputStream.h b/libjava/java/lang/Win32Process$EOFInputStream.h
new file mode 100644
index 000000000..b0224f332
--- /dev/null
+++ b/libjava/java/lang/Win32Process$EOFInputStream.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Win32Process$EOFInputStream__
+#define __java_lang_Win32Process$EOFInputStream__
+
+#pragma interface
+
+#include <java/io/InputStream.h>
+
+class java::lang::Win32Process$EOFInputStream : public ::java::io::InputStream
+{
+
+ Win32Process$EOFInputStream();
+public:
+ virtual jint read();
+public: // actually package-private
+ static ::java::lang::Win32Process$EOFInputStream * instance;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Win32Process$EOFInputStream__
diff --git a/libjava/java/lang/Win32Process.h b/libjava/java/lang/Win32Process.h
new file mode 100644
index 000000000..5e22934a9
--- /dev/null
+++ b/libjava/java/lang/Win32Process.h
@@ -0,0 +1,37 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_Win32Process__
+#define __java_lang_Win32Process__
+
+#pragma interface
+
+#include <java/lang/Process.h>
+#include <gcj/array.h>
+
+
+class java::lang::Win32Process : public ::java::lang::Process
+{
+
+public:
+ void destroy();
+ jint exitValue();
+ ::java::io::InputStream * getErrorStream();
+ ::java::io::InputStream * getInputStream();
+ ::java::io::OutputStream * getOutputStream();
+ jint waitFor();
+ Win32Process(JArray< ::java::lang::String * > *, JArray< ::java::lang::String * > *, ::java::io::File *, jboolean);
+private:
+ jboolean hasExited();
+ void startProcess(JArray< ::java::lang::String * > *, JArray< ::java::lang::String * > *, ::java::io::File *, jboolean);
+ void cleanup();
+ ::java::io::OutputStream * __attribute__((aligned(__alignof__( ::java::lang::Process)))) outputStream;
+ ::java::io::InputStream * inputStream;
+ ::java::io::InputStream * errorStream;
+ jint procHandle;
+ jint exitCode;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_Win32Process__
diff --git a/libjava/java/lang/Win32Process.java b/libjava/java/lang/Win32Process.java
new file mode 100644
index 000000000..f22b54882
--- /dev/null
+++ b/libjava/java/lang/Win32Process.java
@@ -0,0 +1,97 @@
+// Win32Process.java - Subclass of Process for Win32 systems.
+
+/* Copyright (C) 2002, 2003, 2006, 2007 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * @author Adam Megacz
+ * @date Feb 24, 2002
+ */
+
+// This is entirely internal to our implementation.
+
+final class Win32Process extends Process
+{
+ public native void destroy ();
+
+ public int exitValue ()
+ {
+ if (! hasExited ())
+ throw new IllegalThreadStateException ("Process has not exited");
+
+ return exitCode;
+ }
+
+ public InputStream getErrorStream ()
+ {
+ return errorStream;
+ }
+
+ public InputStream getInputStream ()
+ {
+ return inputStream;
+ }
+
+ public OutputStream getOutputStream ()
+ {
+ return outputStream;
+ }
+
+ public native int waitFor () throws InterruptedException;
+
+ public Win32Process (String[] progarray, String[] envp, File dir,
+ boolean redirect)
+ throws IOException
+ {
+ for (int i = 0; i < progarray.length; i++)
+ {
+ String s = progarray[i];
+
+ if ( (s.indexOf (' ') >= 0) || (s.indexOf ('\t') >= 0))
+ progarray[i] = "\"" + s + "\"";
+ }
+
+ startProcess (progarray, envp, dir, redirect);
+ }
+
+ // The standard streams (stdin, stdout and stderr, respectively)
+ // of the child as seen by the parent process.
+ private OutputStream outputStream;
+ private InputStream inputStream;
+ private InputStream errorStream;
+
+ // Handle to the child process - cast to HANDLE before use.
+ private int procHandle;
+
+ // Exit code of the child if it has exited.
+ private int exitCode;
+
+ private native boolean hasExited ();
+ private native void startProcess (String[] progarray,
+ String[] envp,
+ File dir,
+ boolean redirect)
+ throws IOException;
+ private native void cleanup ();
+
+ private static class EOFInputStream extends InputStream
+ {
+ static EOFInputStream instance = new EOFInputStream();
+ public int read()
+ {
+ return -1;
+ }
+ }
+}
diff --git a/libjava/java/lang/annotation/Annotation.h b/libjava/java/lang/annotation/Annotation.h
new file mode 100644
index 000000000..9c9c3d7ab
--- /dev/null
+++ b/libjava/java/lang/annotation/Annotation.h
@@ -0,0 +1,22 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_annotation_Annotation__
+#define __java_lang_annotation_Annotation__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::annotation::Annotation : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::Class * annotationType() = 0;
+ virtual jboolean equals(::java::lang::Object *) = 0;
+ virtual jint hashCode() = 0;
+ virtual ::java::lang::String * toString() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_annotation_Annotation__
diff --git a/libjava/java/lang/annotation/AnnotationFormatError.h b/libjava/java/lang/annotation/AnnotationFormatError.h
new file mode 100644
index 000000000..f5c43b241
--- /dev/null
+++ b/libjava/java/lang/annotation/AnnotationFormatError.h
@@ -0,0 +1,24 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_annotation_AnnotationFormatError__
+#define __java_lang_annotation_AnnotationFormatError__
+
+#pragma interface
+
+#include <java/lang/Error.h>
+
+class java::lang::annotation::AnnotationFormatError : public ::java::lang::Error
+{
+
+public:
+ AnnotationFormatError(::java::lang::String *);
+ AnnotationFormatError(::java::lang::String *, ::java::lang::Throwable *);
+ AnnotationFormatError(::java::lang::Throwable *);
+private:
+ static const jlong serialVersionUID = -4256701562333669892LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_annotation_AnnotationFormatError__
diff --git a/libjava/java/lang/annotation/AnnotationTypeMismatchException.h b/libjava/java/lang/annotation/AnnotationTypeMismatchException.h
new file mode 100644
index 000000000..082d9f6a3
--- /dev/null
+++ b/libjava/java/lang/annotation/AnnotationTypeMismatchException.h
@@ -0,0 +1,26 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_annotation_AnnotationTypeMismatchException__
+#define __java_lang_annotation_AnnotationTypeMismatchException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::annotation::AnnotationTypeMismatchException : public ::java::lang::RuntimeException
+{
+
+public:
+ AnnotationTypeMismatchException(::java::lang::reflect::Method *, ::java::lang::String *);
+ virtual ::java::lang::reflect::Method * element();
+ virtual ::java::lang::String * foundType();
+private:
+ static const jlong serialVersionUID = 8125925355765570191LL;
+ ::java::lang::reflect::Method * __attribute__((aligned(__alignof__( ::java::lang::RuntimeException)))) element__;
+ ::java::lang::String * foundType__;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_annotation_AnnotationTypeMismatchException__
diff --git a/libjava/java/lang/annotation/Documented.h b/libjava/java/lang/annotation/Documented.h
new file mode 100644
index 000000000..d2a920dc7
--- /dev/null
+++ b/libjava/java/lang/annotation/Documented.h
@@ -0,0 +1,19 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_annotation_Documented__
+#define __java_lang_annotation_Documented__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::annotation::Documented : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::Class * annotationType() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_annotation_Documented__
diff --git a/libjava/java/lang/annotation/ElementType.h b/libjava/java/lang/annotation/ElementType.h
new file mode 100644
index 000000000..c475967ab
--- /dev/null
+++ b/libjava/java/lang/annotation/ElementType.h
@@ -0,0 +1,35 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_annotation_ElementType__
+#define __java_lang_annotation_ElementType__
+
+#pragma interface
+
+#include <java/lang/Enum.h>
+#include <gcj/array.h>
+
+
+class java::lang::annotation::ElementType : public ::java::lang::Enum
+{
+
+ ElementType(::java::lang::String *, jint);
+public:
+ static JArray< ::java::lang::annotation::ElementType * > * values();
+ static ::java::lang::annotation::ElementType * valueOf(::java::lang::String *);
+ static ::java::lang::annotation::ElementType * ANNOTATION_TYPE;
+ static ::java::lang::annotation::ElementType * CONSTRUCTOR;
+ static ::java::lang::annotation::ElementType * FIELD;
+ static ::java::lang::annotation::ElementType * LOCAL_VARIABLE;
+ static ::java::lang::annotation::ElementType * METHOD;
+ static ::java::lang::annotation::ElementType * PACKAGE;
+ static ::java::lang::annotation::ElementType * PARAMETER;
+ static ::java::lang::annotation::ElementType * TYPE;
+private:
+ static const jlong serialVersionUID = 2798216111136361587LL;
+ static JArray< ::java::lang::annotation::ElementType * > * ENUM$VALUES;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_annotation_ElementType__
diff --git a/libjava/java/lang/annotation/IncompleteAnnotationException.h b/libjava/java/lang/annotation/IncompleteAnnotationException.h
new file mode 100644
index 000000000..aff0f7e0b
--- /dev/null
+++ b/libjava/java/lang/annotation/IncompleteAnnotationException.h
@@ -0,0 +1,25 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_annotation_IncompleteAnnotationException__
+#define __java_lang_annotation_IncompleteAnnotationException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::annotation::IncompleteAnnotationException : public ::java::lang::RuntimeException
+{
+
+public:
+ IncompleteAnnotationException(::java::lang::Class *, ::java::lang::String *);
+ virtual ::java::lang::Class * annotationType();
+ virtual ::java::lang::String * elementName();
+private:
+ ::java::lang::Class * __attribute__((aligned(__alignof__( ::java::lang::RuntimeException)))) annotationType__;
+ ::java::lang::String * elementName__;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_annotation_IncompleteAnnotationException__
diff --git a/libjava/java/lang/annotation/Inherited.h b/libjava/java/lang/annotation/Inherited.h
new file mode 100644
index 000000000..b1ebc883e
--- /dev/null
+++ b/libjava/java/lang/annotation/Inherited.h
@@ -0,0 +1,19 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_annotation_Inherited__
+#define __java_lang_annotation_Inherited__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::annotation::Inherited : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::Class * annotationType() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_annotation_Inherited__
diff --git a/libjava/java/lang/annotation/Retention.h b/libjava/java/lang/annotation/Retention.h
new file mode 100644
index 000000000..42fb4a542
--- /dev/null
+++ b/libjava/java/lang/annotation/Retention.h
@@ -0,0 +1,20 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_annotation_Retention__
+#define __java_lang_annotation_Retention__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::annotation::Retention : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::annotation::RetentionPolicy * value() = 0;
+ virtual ::java::lang::Class * annotationType() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_annotation_Retention__
diff --git a/libjava/java/lang/annotation/RetentionPolicy.h b/libjava/java/lang/annotation/RetentionPolicy.h
new file mode 100644
index 000000000..5d642601d
--- /dev/null
+++ b/libjava/java/lang/annotation/RetentionPolicy.h
@@ -0,0 +1,30 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_annotation_RetentionPolicy__
+#define __java_lang_annotation_RetentionPolicy__
+
+#pragma interface
+
+#include <java/lang/Enum.h>
+#include <gcj/array.h>
+
+
+class java::lang::annotation::RetentionPolicy : public ::java::lang::Enum
+{
+
+ RetentionPolicy(::java::lang::String *, jint);
+public:
+ static JArray< ::java::lang::annotation::RetentionPolicy * > * values();
+ static ::java::lang::annotation::RetentionPolicy * valueOf(::java::lang::String *);
+ static ::java::lang::annotation::RetentionPolicy * CLASS;
+ static ::java::lang::annotation::RetentionPolicy * RUNTIME;
+ static ::java::lang::annotation::RetentionPolicy * SOURCE;
+private:
+ static const jlong serialVersionUID = -1700821648800605045LL;
+ static JArray< ::java::lang::annotation::RetentionPolicy * > * ENUM$VALUES;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_annotation_RetentionPolicy__
diff --git a/libjava/java/lang/annotation/Target.h b/libjava/java/lang/annotation/Target.h
new file mode 100644
index 000000000..96ac51788
--- /dev/null
+++ b/libjava/java/lang/annotation/Target.h
@@ -0,0 +1,22 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_annotation_Target__
+#define __java_lang_annotation_Target__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::annotation::Target : public ::java::lang::Object
+{
+
+public:
+ virtual JArray< ::java::lang::annotation::ElementType * > * value() = 0;
+ virtual ::java::lang::Class * annotationType() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_annotation_Target__
diff --git a/libjava/java/lang/instrument/ClassDefinition.h b/libjava/java/lang/instrument/ClassDefinition.h
new file mode 100644
index 000000000..b9106ed8e
--- /dev/null
+++ b/libjava/java/lang/instrument/ClassDefinition.h
@@ -0,0 +1,27 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_instrument_ClassDefinition__
+#define __java_lang_instrument_ClassDefinition__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::instrument::ClassDefinition : public ::java::lang::Object
+{
+
+public:
+ ClassDefinition(::java::lang::Class *, JArray< jbyte > *);
+ ::java::lang::Class * getDefinitionClass();
+ JArray< jbyte > * getDefinitionClassFile();
+private:
+ ::java::lang::Class * __attribute__((aligned(__alignof__( ::java::lang::Object)))) theClass;
+ JArray< jbyte > * theClassFile;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_instrument_ClassDefinition__
diff --git a/libjava/java/lang/instrument/ClassFileTransformer.h b/libjava/java/lang/instrument/ClassFileTransformer.h
new file mode 100644
index 000000000..cda1510b0
--- /dev/null
+++ b/libjava/java/lang/instrument/ClassFileTransformer.h
@@ -0,0 +1,31 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_instrument_ClassFileTransformer__
+#define __java_lang_instrument_ClassFileTransformer__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+extern "Java"
+{
+ namespace java
+ {
+ namespace security
+ {
+ class ProtectionDomain;
+ }
+ }
+}
+
+class java::lang::instrument::ClassFileTransformer : public ::java::lang::Object
+{
+
+public:
+ virtual JArray< jbyte > * transform(::java::lang::ClassLoader *, ::java::lang::String *, ::java::lang::Class *, ::java::security::ProtectionDomain *, JArray< jbyte > *) = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_instrument_ClassFileTransformer__
diff --git a/libjava/java/lang/instrument/IllegalClassFormatException.h b/libjava/java/lang/instrument/IllegalClassFormatException.h
new file mode 100644
index 000000000..c1b8783e7
--- /dev/null
+++ b/libjava/java/lang/instrument/IllegalClassFormatException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_instrument_IllegalClassFormatException__
+#define __java_lang_instrument_IllegalClassFormatException__
+
+#pragma interface
+
+#include <java/lang/Exception.h>
+
+class java::lang::instrument::IllegalClassFormatException : public ::java::lang::Exception
+{
+
+public:
+ IllegalClassFormatException();
+ IllegalClassFormatException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = -3841736710924794009LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_instrument_IllegalClassFormatException__
diff --git a/libjava/java/lang/instrument/Instrumentation.h b/libjava/java/lang/instrument/Instrumentation.h
new file mode 100644
index 000000000..d131d0c69
--- /dev/null
+++ b/libjava/java/lang/instrument/Instrumentation.h
@@ -0,0 +1,27 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_instrument_Instrumentation__
+#define __java_lang_instrument_Instrumentation__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::instrument::Instrumentation : public ::java::lang::Object
+{
+
+public:
+ virtual void addTransformer(::java::lang::instrument::ClassFileTransformer *) = 0;
+ virtual jboolean removeTransformer(::java::lang::instrument::ClassFileTransformer *) = 0;
+ virtual jboolean isRedefineClassesSupported() = 0;
+ virtual void redefineClasses(JArray< ::java::lang::instrument::ClassDefinition * > *) = 0;
+ virtual JArray< ::java::lang::Class * > * getAllLoadedClasses() = 0;
+ virtual JArray< ::java::lang::Class * > * getInitiatedClasses(::java::lang::ClassLoader *) = 0;
+ virtual jlong getObjectSize(::java::lang::Object *) = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_instrument_Instrumentation__
diff --git a/libjava/java/lang/instrument/UnmodifiableClassException.h b/libjava/java/lang/instrument/UnmodifiableClassException.h
new file mode 100644
index 000000000..e5fac3cdd
--- /dev/null
+++ b/libjava/java/lang/instrument/UnmodifiableClassException.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_instrument_UnmodifiableClassException__
+#define __java_lang_instrument_UnmodifiableClassException__
+
+#pragma interface
+
+#include <java/lang/Exception.h>
+
+class java::lang::instrument::UnmodifiableClassException : public ::java::lang::Exception
+{
+
+public:
+ UnmodifiableClassException();
+ UnmodifiableClassException(::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 1716652643585309178LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_instrument_UnmodifiableClassException__
diff --git a/libjava/java/lang/management/ClassLoadingMXBean.h b/libjava/java/lang/management/ClassLoadingMXBean.h
new file mode 100644
index 000000000..371b63d3d
--- /dev/null
+++ b/libjava/java/lang/management/ClassLoadingMXBean.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_ClassLoadingMXBean__
+#define __java_lang_management_ClassLoadingMXBean__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::management::ClassLoadingMXBean : public ::java::lang::Object
+{
+
+public:
+ virtual jint getLoadedClassCount() = 0;
+ virtual jlong getTotalLoadedClassCount() = 0;
+ virtual jlong getUnloadedClassCount() = 0;
+ virtual jboolean isVerbose() = 0;
+ virtual void setVerbose(jboolean) = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_management_ClassLoadingMXBean__
diff --git a/libjava/java/lang/management/CompilationMXBean.h b/libjava/java/lang/management/CompilationMXBean.h
new file mode 100644
index 000000000..bbd1e0a21
--- /dev/null
+++ b/libjava/java/lang/management/CompilationMXBean.h
@@ -0,0 +1,21 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_CompilationMXBean__
+#define __java_lang_management_CompilationMXBean__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::management::CompilationMXBean : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::String * getName() = 0;
+ virtual jboolean isCompilationTimeMonitoringSupported() = 0;
+ virtual jlong getTotalCompilationTime() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_management_CompilationMXBean__
diff --git a/libjava/java/lang/management/GarbageCollectorMXBean.h b/libjava/java/lang/management/GarbageCollectorMXBean.h
new file mode 100644
index 000000000..35222cab0
--- /dev/null
+++ b/libjava/java/lang/management/GarbageCollectorMXBean.h
@@ -0,0 +1,25 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_GarbageCollectorMXBean__
+#define __java_lang_management_GarbageCollectorMXBean__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::management::GarbageCollectorMXBean : public ::java::lang::Object
+{
+
+public:
+ virtual jlong getCollectionCount() = 0;
+ virtual jlong getCollectionTime() = 0;
+ virtual JArray< ::java::lang::String * > * getMemoryPoolNames() = 0;
+ virtual ::java::lang::String * getName() = 0;
+ virtual jboolean isValid() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_management_GarbageCollectorMXBean__
diff --git a/libjava/java/lang/management/LockInfo.h b/libjava/java/lang/management/LockInfo.h
new file mode 100644
index 000000000..ec4291753
--- /dev/null
+++ b/libjava/java/lang/management/LockInfo.h
@@ -0,0 +1,26 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_LockInfo__
+#define __java_lang_management_LockInfo__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::management::LockInfo : public ::java::lang::Object
+{
+
+public:
+ LockInfo(::java::lang::String *, jint);
+ virtual ::java::lang::String * getClassName();
+ virtual jint getIdentityHashCode();
+ virtual ::java::lang::String * toString();
+private:
+ ::java::lang::String * __attribute__((aligned(__alignof__( ::java::lang::Object)))) className;
+ jint identityHashCode;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_management_LockInfo__
diff --git a/libjava/java/lang/management/ManagementFactory$ManagementInvocationHandler.h b/libjava/java/lang/management/ManagementFactory$ManagementInvocationHandler.h
new file mode 100644
index 000000000..33603be20
--- /dev/null
+++ b/libjava/java/lang/management/ManagementFactory$ManagementInvocationHandler.h
@@ -0,0 +1,38 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_ManagementFactory$ManagementInvocationHandler__
+#define __java_lang_management_ManagementFactory$ManagementInvocationHandler__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+extern "Java"
+{
+ namespace javax
+ {
+ namespace management
+ {
+ class MBeanServerConnection;
+ class ObjectName;
+ }
+ }
+}
+
+class java::lang::management::ManagementFactory$ManagementInvocationHandler : public ::java::lang::Object
+{
+
+public:
+ ManagementFactory$ManagementInvocationHandler(::javax::management::MBeanServerConnection *, ::javax::management::ObjectName *);
+ virtual ::java::lang::Object * invoke(::java::lang::Object *, ::java::lang::reflect::Method *, JArray< ::java::lang::Object * > *);
+private:
+ ::java::lang::Object * translate(::java::lang::Object *, ::java::lang::reflect::Method *);
+ ::javax::management::MBeanServerConnection * __attribute__((aligned(__alignof__( ::java::lang::Object)))) conn;
+ ::javax::management::ObjectName * bean;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_management_ManagementFactory$ManagementInvocationHandler__
diff --git a/libjava/java/lang/management/ManagementFactory.h b/libjava/java/lang/management/ManagementFactory.h
new file mode 100644
index 000000000..c51809371
--- /dev/null
+++ b/libjava/java/lang/management/ManagementFactory.h
@@ -0,0 +1,59 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_ManagementFactory__
+#define __java_lang_management_ManagementFactory__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+extern "Java"
+{
+ namespace javax
+ {
+ namespace management
+ {
+ class MBeanServer;
+ class MBeanServerConnection;
+ }
+ }
+}
+
+class java::lang::management::ManagementFactory : public ::java::lang::Object
+{
+
+ ManagementFactory();
+public:
+ static ::java::lang::management::OperatingSystemMXBean * getOperatingSystemMXBean();
+ static ::java::lang::management::RuntimeMXBean * getRuntimeMXBean();
+ static ::java::lang::management::ClassLoadingMXBean * getClassLoadingMXBean();
+ static ::java::lang::management::ThreadMXBean * getThreadMXBean();
+ static ::java::lang::management::MemoryMXBean * getMemoryMXBean();
+ static ::java::lang::management::CompilationMXBean * getCompilationMXBean();
+ static ::java::util::List * getMemoryPoolMXBeans();
+ static ::java::util::List * getMemoryManagerMXBeans();
+ static ::java::util::List * getGarbageCollectorMXBeans();
+ static ::javax::management::MBeanServer * getPlatformMBeanServer();
+ static ::java::lang::Object * newPlatformMXBeanProxy(::javax::management::MBeanServerConnection *, ::java::lang::String *, ::java::lang::Class *);
+ static ::java::lang::String * CLASS_LOADING_MXBEAN_NAME;
+ static ::java::lang::String * COMPILATION_MXBEAN_NAME;
+ static ::java::lang::String * GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE;
+ static ::java::lang::String * MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE;
+ static ::java::lang::String * MEMORY_MXBEAN_NAME;
+ static ::java::lang::String * MEMORY_POOL_MXBEAN_DOMAIN_TYPE;
+ static ::java::lang::String * OPERATING_SYSTEM_MXBEAN_NAME;
+ static ::java::lang::String * RUNTIME_MXBEAN_NAME;
+ static ::java::lang::String * THREAD_MXBEAN_NAME;
+private:
+ static ::java::lang::management::OperatingSystemMXBean * osBean;
+ static ::java::lang::management::RuntimeMXBean * runtimeBean;
+ static ::java::lang::management::ClassLoadingMXBean * classLoadingBean;
+ static ::java::lang::management::ThreadMXBean * threadBean;
+ static ::java::lang::management::MemoryMXBean * memoryBean;
+ static ::java::lang::management::CompilationMXBean * compilationBean;
+ static ::javax::management::MBeanServer * platformServer;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_management_ManagementFactory__
diff --git a/libjava/java/lang/management/ManagementPermission.h b/libjava/java/lang/management/ManagementPermission.h
new file mode 100644
index 000000000..4ac4a4fef
--- /dev/null
+++ b/libjava/java/lang/management/ManagementPermission.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_ManagementPermission__
+#define __java_lang_management_ManagementPermission__
+
+#pragma interface
+
+#include <java/security/BasicPermission.h>
+
+class java::lang::management::ManagementPermission : public ::java::security::BasicPermission
+{
+
+public:
+ ManagementPermission(::java::lang::String *);
+ ManagementPermission(::java::lang::String *, ::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 1897496590799378737LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_management_ManagementPermission__
diff --git a/libjava/java/lang/management/MemoryMXBean.h b/libjava/java/lang/management/MemoryMXBean.h
new file mode 100644
index 000000000..2fb70add2
--- /dev/null
+++ b/libjava/java/lang/management/MemoryMXBean.h
@@ -0,0 +1,24 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_MemoryMXBean__
+#define __java_lang_management_MemoryMXBean__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::management::MemoryMXBean : public ::java::lang::Object
+{
+
+public:
+ virtual void gc() = 0;
+ virtual ::java::lang::management::MemoryUsage * getHeapMemoryUsage() = 0;
+ virtual ::java::lang::management::MemoryUsage * getNonHeapMemoryUsage() = 0;
+ virtual jint getObjectPendingFinalizationCount() = 0;
+ virtual jboolean isVerbose() = 0;
+ virtual void setVerbose(jboolean) = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_management_MemoryMXBean__
diff --git a/libjava/java/lang/management/MemoryManagerMXBean.h b/libjava/java/lang/management/MemoryManagerMXBean.h
new file mode 100644
index 000000000..6509205a9
--- /dev/null
+++ b/libjava/java/lang/management/MemoryManagerMXBean.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_MemoryManagerMXBean__
+#define __java_lang_management_MemoryManagerMXBean__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::management::MemoryManagerMXBean : public ::java::lang::Object
+{
+
+public:
+ virtual JArray< ::java::lang::String * > * getMemoryPoolNames() = 0;
+ virtual ::java::lang::String * getName() = 0;
+ virtual jboolean isValid() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_management_MemoryManagerMXBean__
diff --git a/libjava/java/lang/management/MemoryNotificationInfo.h b/libjava/java/lang/management/MemoryNotificationInfo.h
new file mode 100644
index 000000000..07cfefff3
--- /dev/null
+++ b/libjava/java/lang/management/MemoryNotificationInfo.h
@@ -0,0 +1,43 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_MemoryNotificationInfo__
+#define __java_lang_management_MemoryNotificationInfo__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+extern "Java"
+{
+ namespace javax
+ {
+ namespace management
+ {
+ namespace openmbean
+ {
+ class CompositeData;
+ }
+ }
+ }
+}
+
+class java::lang::management::MemoryNotificationInfo : public ::java::lang::Object
+{
+
+public:
+ MemoryNotificationInfo(::java::lang::String *, ::java::lang::management::MemoryUsage *, jlong);
+ static ::java::lang::management::MemoryNotificationInfo * from(::javax::management::openmbean::CompositeData *);
+ virtual jlong getCount();
+ virtual ::java::lang::String * getPoolName();
+ virtual ::java::lang::management::MemoryUsage * getUsage();
+ static ::java::lang::String * MEMORY_THRESHOLD_EXCEEDED;
+ static ::java::lang::String * MEMORY_COLLECTION_THRESHOLD_EXCEEDED;
+private:
+ ::java::lang::String * __attribute__((aligned(__alignof__( ::java::lang::Object)))) poolName;
+ ::java::lang::management::MemoryUsage * usage;
+ jlong count;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_management_MemoryNotificationInfo__
diff --git a/libjava/java/lang/management/MemoryPoolMXBean.h b/libjava/java/lang/management/MemoryPoolMXBean.h
new file mode 100644
index 000000000..4209d573a
--- /dev/null
+++ b/libjava/java/lang/management/MemoryPoolMXBean.h
@@ -0,0 +1,38 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_MemoryPoolMXBean__
+#define __java_lang_management_MemoryPoolMXBean__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::management::MemoryPoolMXBean : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::management::MemoryUsage * getCollectionUsage() = 0;
+ virtual jlong getCollectionUsageThreshold() = 0;
+ virtual jlong getCollectionUsageThresholdCount() = 0;
+ virtual JArray< ::java::lang::String * > * getMemoryManagerNames() = 0;
+ virtual ::java::lang::String * getName() = 0;
+ virtual ::java::lang::management::MemoryUsage * getPeakUsage() = 0;
+ virtual ::java::lang::management::MemoryType * getType() = 0;
+ virtual ::java::lang::management::MemoryUsage * getUsage() = 0;
+ virtual jlong getUsageThreshold() = 0;
+ virtual jlong getUsageThresholdCount() = 0;
+ virtual jboolean isCollectionUsageThresholdExceeded() = 0;
+ virtual jboolean isCollectionUsageThresholdSupported() = 0;
+ virtual jboolean isUsageThresholdExceeded() = 0;
+ virtual jboolean isUsageThresholdSupported() = 0;
+ virtual jboolean isValid() = 0;
+ virtual void resetPeakUsage() = 0;
+ virtual void setCollectionUsageThreshold(jlong) = 0;
+ virtual void setUsageThreshold(jlong) = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_management_MemoryPoolMXBean__
diff --git a/libjava/java/lang/management/MemoryType.h b/libjava/java/lang/management/MemoryType.h
new file mode 100644
index 000000000..b93587d30
--- /dev/null
+++ b/libjava/java/lang/management/MemoryType.h
@@ -0,0 +1,28 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_MemoryType__
+#define __java_lang_management_MemoryType__
+
+#pragma interface
+
+#include <java/lang/Enum.h>
+#include <gcj/array.h>
+
+
+class java::lang::management::MemoryType : public ::java::lang::Enum
+{
+
+ MemoryType(::java::lang::String *, jint);
+public:
+ static JArray< ::java::lang::management::MemoryType * > * values();
+ static ::java::lang::management::MemoryType * valueOf(::java::lang::String *);
+ static ::java::lang::management::MemoryType * HEAP;
+ static ::java::lang::management::MemoryType * NON_HEAP;
+private:
+ static JArray< ::java::lang::management::MemoryType * > * ENUM$VALUES;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_management_MemoryType__
diff --git a/libjava/java/lang/management/MemoryUsage.h b/libjava/java/lang/management/MemoryUsage.h
new file mode 100644
index 000000000..3b126f818
--- /dev/null
+++ b/libjava/java/lang/management/MemoryUsage.h
@@ -0,0 +1,44 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_MemoryUsage__
+#define __java_lang_management_MemoryUsage__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+extern "Java"
+{
+ namespace javax
+ {
+ namespace management
+ {
+ namespace openmbean
+ {
+ class CompositeData;
+ }
+ }
+ }
+}
+
+class java::lang::management::MemoryUsage : public ::java::lang::Object
+{
+
+public:
+ MemoryUsage(jlong, jlong, jlong, jlong);
+ static ::java::lang::management::MemoryUsage * from(::javax::management::openmbean::CompositeData *);
+ virtual jlong getCommitted();
+ virtual jlong getInit();
+ virtual jlong getMax();
+ virtual jlong getUsed();
+ virtual ::java::lang::String * toString();
+private:
+ jlong __attribute__((aligned(__alignof__( ::java::lang::Object)))) init;
+ jlong used;
+ jlong committed;
+ jlong maximum;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_management_MemoryUsage__
diff --git a/libjava/java/lang/management/MonitorInfo.h b/libjava/java/lang/management/MonitorInfo.h
new file mode 100644
index 000000000..6d2a0f01f
--- /dev/null
+++ b/libjava/java/lang/management/MonitorInfo.h
@@ -0,0 +1,39 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_MonitorInfo__
+#define __java_lang_management_MonitorInfo__
+
+#pragma interface
+
+#include <java/lang/management/LockInfo.h>
+extern "Java"
+{
+ namespace javax
+ {
+ namespace management
+ {
+ namespace openmbean
+ {
+ class CompositeData;
+ }
+ }
+ }
+}
+
+class java::lang::management::MonitorInfo : public ::java::lang::management::LockInfo
+{
+
+public:
+ MonitorInfo(::java::lang::String *, jint, jint, ::java::lang::StackTraceElement *);
+ static ::java::lang::management::MonitorInfo * from(::javax::management::openmbean::CompositeData *);
+ virtual jint getLockedStackDepth();
+ virtual ::java::lang::StackTraceElement * getLockedStackFrame();
+private:
+ jint __attribute__((aligned(__alignof__( ::java::lang::management::LockInfo)))) stackDepth;
+ ::java::lang::StackTraceElement * stackFrame;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_management_MonitorInfo__
diff --git a/libjava/java/lang/management/OperatingSystemMXBean.h b/libjava/java/lang/management/OperatingSystemMXBean.h
new file mode 100644
index 000000000..bbf37070b
--- /dev/null
+++ b/libjava/java/lang/management/OperatingSystemMXBean.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_OperatingSystemMXBean__
+#define __java_lang_management_OperatingSystemMXBean__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::management::OperatingSystemMXBean : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::String * getArch() = 0;
+ virtual jint getAvailableProcessors() = 0;
+ virtual ::java::lang::String * getName() = 0;
+ virtual jdouble getSystemLoadAverage() = 0;
+ virtual ::java::lang::String * getVersion() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_management_OperatingSystemMXBean__
diff --git a/libjava/java/lang/management/RuntimeMXBean.h b/libjava/java/lang/management/RuntimeMXBean.h
new file mode 100644
index 000000000..c26667440
--- /dev/null
+++ b/libjava/java/lang/management/RuntimeMXBean.h
@@ -0,0 +1,34 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_RuntimeMXBean__
+#define __java_lang_management_RuntimeMXBean__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::management::RuntimeMXBean : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::String * getBootClassPath() = 0;
+ virtual ::java::lang::String * getClassPath() = 0;
+ virtual ::java::util::List * getInputArguments() = 0;
+ virtual ::java::lang::String * getLibraryPath() = 0;
+ virtual ::java::lang::String * getManagementSpecVersion() = 0;
+ virtual ::java::lang::String * getName() = 0;
+ virtual ::java::lang::String * getSpecName() = 0;
+ virtual ::java::lang::String * getSpecVendor() = 0;
+ virtual ::java::lang::String * getSpecVersion() = 0;
+ virtual jlong getStartTime() = 0;
+ virtual ::java::util::Map * getSystemProperties() = 0;
+ virtual jlong getUptime() = 0;
+ virtual ::java::lang::String * getVmName() = 0;
+ virtual ::java::lang::String * getVmVendor() = 0;
+ virtual ::java::lang::String * getVmVersion() = 0;
+ virtual jboolean isBootClassPathSupported() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_management_RuntimeMXBean__
diff --git a/libjava/java/lang/management/ThreadInfo.h b/libjava/java/lang/management/ThreadInfo.h
new file mode 100644
index 000000000..4d87277be
--- /dev/null
+++ b/libjava/java/lang/management/ThreadInfo.h
@@ -0,0 +1,77 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_ThreadInfo__
+#define __java_lang_management_ThreadInfo__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+extern "Java"
+{
+ namespace javax
+ {
+ namespace management
+ {
+ namespace openmbean
+ {
+ class CompositeData;
+ class CompositeType;
+ class OpenType;
+ }
+ }
+ }
+}
+
+class java::lang::management::ThreadInfo : public ::java::lang::Object
+{
+
+ ThreadInfo(jlong, ::java::lang::String *, ::java::lang::Thread$State *, jlong, jlong, ::java::lang::String *, jlong, ::java::lang::String *, jlong, jlong, jboolean, jboolean, JArray< ::java::lang::StackTraceElement * > *, JArray< ::java::lang::management::MonitorInfo * > *, JArray< ::java::lang::management::LockInfo * > *);
+public: // actually package-private
+ static void checkAttribute(::javax::management::openmbean::CompositeType *, ::java::lang::String *, ::javax::management::openmbean::OpenType *);
+ static ::javax::management::openmbean::CompositeType * getStackTraceType();
+public:
+ static ::java::lang::management::ThreadInfo * from(::javax::management::openmbean::CompositeData *);
+ virtual jlong getBlockedCount();
+ virtual jlong getBlockedTime();
+ virtual JArray< ::java::lang::management::MonitorInfo * > * getLockedMonitors();
+ virtual JArray< ::java::lang::management::LockInfo * > * getLockedSynchronizers();
+ virtual ::java::lang::management::LockInfo * getLockInfo();
+ virtual ::java::lang::String * getLockName();
+ virtual jlong getLockOwnerId();
+ virtual ::java::lang::String * getLockOwnerName();
+ virtual JArray< ::java::lang::StackTraceElement * > * getStackTrace();
+ virtual jlong getThreadId();
+ virtual ::java::lang::String * getThreadName();
+ virtual ::java::lang::Thread$State * getThreadState();
+ virtual jlong getWaitedCount();
+ virtual jlong getWaitedTime();
+ virtual jboolean isInNative();
+ virtual jboolean isSuspended();
+ virtual ::java::lang::String * toString();
+private:
+ jboolean isThreadBlocked();
+ jlong __attribute__((aligned(__alignof__( ::java::lang::Object)))) threadId;
+ ::java::lang::String * threadName;
+ ::java::lang::Thread$State * threadState;
+ jlong blockedCount;
+ jlong blockedTime;
+ ::java::lang::String * lockName;
+ jlong lockOwnerId;
+ ::java::lang::String * lockOwnerName;
+ jlong waitedCount;
+ jlong waitedTime;
+ jboolean isInNative__;
+ jboolean isSuspended__;
+ JArray< ::java::lang::StackTraceElement * > * trace;
+ JArray< ::java::lang::management::MonitorInfo * > * lockedMonitors;
+ JArray< ::java::lang::management::LockInfo * > * lockedSynchronizers;
+ static ::java::lang::management::ThreadMXBean * bean;
+ static ::javax::management::openmbean::CompositeType * seType;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_management_ThreadInfo__
diff --git a/libjava/java/lang/management/ThreadMXBean.h b/libjava/java/lang/management/ThreadMXBean.h
new file mode 100644
index 000000000..a1d4636c9
--- /dev/null
+++ b/libjava/java/lang/management/ThreadMXBean.h
@@ -0,0 +1,47 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_ThreadMXBean__
+#define __java_lang_management_ThreadMXBean__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::management::ThreadMXBean : public ::java::lang::Object
+{
+
+public:
+ virtual JArray< ::java::lang::management::ThreadInfo * > * dumpAllThreads(jboolean, jboolean) = 0;
+ virtual JArray< jlong > * findDeadlockedThreads() = 0;
+ virtual JArray< jlong > * findMonitorDeadlockedThreads() = 0;
+ virtual JArray< jlong > * getAllThreadIds() = 0;
+ virtual jlong getCurrentThreadCpuTime() = 0;
+ virtual jlong getCurrentThreadUserTime() = 0;
+ virtual jint getDaemonThreadCount() = 0;
+ virtual jint getPeakThreadCount() = 0;
+ virtual jint getThreadCount() = 0;
+ virtual jlong getThreadCpuTime(jlong) = 0;
+ virtual ::java::lang::management::ThreadInfo * getThreadInfo(jlong) = 0;
+ virtual JArray< ::java::lang::management::ThreadInfo * > * getThreadInfo(JArray< jlong > *) = 0;
+ virtual JArray< ::java::lang::management::ThreadInfo * > * getThreadInfo(JArray< jlong > *, jboolean, jboolean) = 0;
+ virtual ::java::lang::management::ThreadInfo * getThreadInfo(jlong, jint) = 0;
+ virtual JArray< ::java::lang::management::ThreadInfo * > * getThreadInfo(JArray< jlong > *, jint) = 0;
+ virtual jlong getThreadUserTime(jlong) = 0;
+ virtual jlong getTotalStartedThreadCount() = 0;
+ virtual jboolean isCurrentThreadCpuTimeSupported() = 0;
+ virtual jboolean isObjectMonitorUsageSupported() = 0;
+ virtual jboolean isSynchronizerUsageSupported() = 0;
+ virtual jboolean isThreadContentionMonitoringEnabled() = 0;
+ virtual jboolean isThreadContentionMonitoringSupported() = 0;
+ virtual jboolean isThreadCpuTimeEnabled() = 0;
+ virtual jboolean isThreadCpuTimeSupported() = 0;
+ virtual void resetPeakThreadCount() = 0;
+ virtual void setThreadContentionMonitoringEnabled(jboolean) = 0;
+ virtual void setThreadCpuTimeEnabled(jboolean) = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_management_ThreadMXBean__
diff --git a/libjava/java/lang/management/VMManagementFactory.h b/libjava/java/lang/management/VMManagementFactory.h
new file mode 100644
index 000000000..e712cbfc8
--- /dev/null
+++ b/libjava/java/lang/management/VMManagementFactory.h
@@ -0,0 +1,25 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_management_VMManagementFactory__
+#define __java_lang_management_VMManagementFactory__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::management::VMManagementFactory : public ::java::lang::Object
+{
+
+public: // actually package-private
+ VMManagementFactory();
+ static JArray< ::java::lang::String * > * getMemoryPoolNames();
+ static JArray< ::java::lang::String * > * getMemoryManagerNames();
+ static JArray< ::java::lang::String * > * getGarbageCollectorNames();
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_management_VMManagementFactory__
diff --git a/libjava/java/lang/management/VMManagementFactory.java b/libjava/java/lang/management/VMManagementFactory.java
new file mode 100644
index 000000000..35b15e360
--- /dev/null
+++ b/libjava/java/lang/management/VMManagementFactory.java
@@ -0,0 +1,87 @@
+/* VMManagementFactory.java - VM interface for obtaining system beans.
+ Copyright (C) 2006, 2007 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang.management;
+
+/**
+ * Provides lists of resources required by the
+ * {@link java.lang.management.ManagementFactory} for
+ * creating beans.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMManagementFactory
+{
+
+ /**
+ * Return a list of the names of the currently available
+ * memory pools within the virtual machine.
+ *
+ * @return a list of memory pool names.
+ */
+ static String[] getMemoryPoolNames()
+ {
+ String[] result = {"Heap"};
+ return result;
+ }
+
+ /**
+ * Return a list of the names of the currently available
+ * memory managers within the virtual machine. This should
+ * not include the garbage collectors listed below.
+ *
+ * @return a list of memory manager names.
+ */
+ static String[] getMemoryManagerNames()
+ {
+ String[] result = {};
+ return result;
+ }
+
+ /**
+ * Return a list of the names of the currently available
+ * garbage collectors within the virtual machine.
+ *
+ * @return a list of garbage collector names.
+ */
+ static String[] getGarbageCollectorNames()
+ {
+ String[] result = {"BoehmGC"};
+ return result;
+ }
+}
diff --git a/libjava/java/lang/natAbstractStringBuffer.cc b/libjava/java/lang/natAbstractStringBuffer.cc
new file mode 100644
index 000000000..b2df69cc3
--- /dev/null
+++ b/libjava/java/lang/natAbstractStringBuffer.cc
@@ -0,0 +1,41 @@
+// natStringBuffer.cc - Implementation of java.lang.StringBuffer native methods.
+
+/* Copyright (C) 2001, 2003 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <gcj/cni.h>
+#include <java/lang/AbstractStringBuffer.h>
+
+java::lang::AbstractStringBuffer*
+java::lang::AbstractStringBuffer::append (jint num)
+{
+ // Use an array large enough for "-2147483648"; i.e. 11 chars.
+ jchar buffer[11];
+ int i = _Jv_FormatInt (buffer+11, num);
+ jint needed = count + i;
+ ensureCapacity_unsynchronized (needed);
+ jchar* dst = elements (value) + count;
+ jchar* src = buffer+11-i;
+ while (--i >= 0)
+ *dst++ = *src++;
+ count = needed;
+ return this;
+}
+
+jboolean
+java::lang::AbstractStringBuffer::regionMatches(jint toffset, jstring other)
+{
+ jint len = other->count;
+ jchar *tptr = elements(value) + toffset;
+ jchar *optr = JvGetStringChars(other);
+ while (--len >= 0)
+ if (*tptr++ != *optr++)
+ return false;
+ return true;
+}
diff --git a/libjava/java/lang/natCharacter.cc b/libjava/java/lang/natCharacter.cc
new file mode 100644
index 000000000..dea2086eb
--- /dev/null
+++ b/libjava/java/lang/natCharacter.cc
@@ -0,0 +1,235 @@
+/* java.lang.Character -- Wrapper class for char, and Unicode subsets
+ Copyright (C) 1998, 1999, 2001, 2002, 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/lang/Character.h>
+
+#include <java-chartables.h>
+
+
+
+// These constants define the return values for characters that are unassigned
+// or reserved for private use.
+#define UNASSIGNED_TYPE 0
+#define UNASSIGNED_DIGIT -1
+#define UNASSIGNED_DIRECTION -1
+#define UNASSIGNED_NUMERIC_VALUE -1
+
+#define PRIVATE_TYPE 18
+#define PRIVATE_DIRECTION 0
+
+// The methods that take a char as an argument all have counterparts that
+// take ints. The ones that take chars only work for the BMP or plane 0 of the
+// Unicode standard but the ones that take ints work for all Unicode code
+// points. However, the ones that take chars don't simply redirect the calls
+// because the BMP is by far the most used plane so saving a little time on
+// each call makes sense.
+
+jchar
+java::lang::Character::readChar(jchar ch)
+{
+ // Perform 16-bit addition to find the correct entry in data.
+ return data[0][(jchar) (blocks[0][ch >> shift[0]] + ch)];
+}
+
+jchar
+java::lang::Character::readCodePoint(jint codePoint)
+{
+ jint plane = codePoint >> 16;
+ jchar offset = (jchar)(codePoint & 0xffff);
+ // Be careful not to call this method with an unassigned character. The only
+ // characters assigned as of Unicode 4.0.0 belong to planes 0, 1, 2, and 14.
+ return data[plane][(jchar) (blocks[plane][offset >> shift[plane]] + offset)];
+}
+
+jint
+java::lang::Character::getType(jchar ch)
+{
+ // Perform 16-bit addition to find the correct entry in data.
+ return (jint) (data[0][(jchar) (blocks[0][ch >> shift[0]] + ch)] & TYPE_MASK);
+}
+
+jint
+java::lang::Character::getType(jint codePoint)
+{
+ jint plane = codePoint >> 16;
+ if (plane < 0 || (plane > 2 && plane != 14))
+ {
+ if (plane > 14 && ((codePoint & 0xffff) < 0xfffe))
+ return (jint) PRIVATE_TYPE;
+ return (jint) UNASSIGNED_TYPE;
+ }
+ jint offset = codePoint & 0xffff;
+ return (jint)
+ (data[plane]
+ [(jchar) (blocks[plane][offset >> shift[plane]] + offset)] & TYPE_MASK);
+}
+
+jchar
+java::lang::Character::toLowerCase(jchar ch)
+{
+ return (jchar) (ch + lower[0][readChar(ch) >> 7]);
+}
+
+jint
+java::lang::Character::toLowerCase(jint codePoint)
+{
+ jint plane = codePoint >> 16;
+ if (plane < 0 || (plane > 2 && plane != 14))
+ return codePoint;
+ return (lower[plane][readCodePoint(codePoint) >> 7]) + codePoint;
+}
+
+jchar
+java::lang::Character::toUpperCase(jchar ch)
+{
+ return (jchar) (ch + upper[0][readChar(ch) >> 7]);
+}
+
+jint
+java::lang::Character::toUpperCase(jint codePoint)
+{
+ jint plane = codePoint >> 16;
+ if (plane < 0 || (plane > 2 && plane != 14))
+ return codePoint;
+ return (upper[plane][readCodePoint(codePoint) >> 7]) + codePoint;
+}
+
+jchar
+java::lang::Character::toTitleCase(jchar ch)
+{
+ // As title is short, it doesn't hurt to exhaustively iterate over it.
+ for (int i = title_length - 2; i >= 0; i -= 2)
+ if (title[i] == ch)
+ return title[i + 1];
+ return toUpperCase(ch);
+}
+
+jint
+java::lang::Character::toTitleCase(jint codePoint)
+{
+ // As of Unicode 4.0.0 no characters outside of plane 0 have titlecase
+ // mappings that are different from their uppercase mapping.
+ if (codePoint >= 0 && codePoint < 0x10000)
+ return toTitleCase((jchar)codePoint);
+ return toUpperCase(codePoint);
+}
+
+jint
+java::lang::Character::digit(jchar ch, jint radix)
+{
+ if (radix < MIN_RADIX || radix > MAX_RADIX)
+ return (jint) -1;
+ jchar attr = readChar(ch);
+ if (((1 << (attr & TYPE_MASK))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << DECIMAL_DIGIT_NUMBER))))
+ {
+ // Signedness doesn't matter; 0xffff vs. -1 are both rejected.
+ jint digit = (jint) numValue[0][attr >> 7];
+ return (digit >= 0 && digit < radix) ? digit : (jint) -1;
+ }
+ return (jint) -1;
+}
+
+jint
+java::lang::Character::digit(jint codePoint, jint radix)
+{
+ if (radix < MIN_RADIX || radix > MAX_RADIX)
+ return (jint) -1;
+
+ jint plane = codePoint >> 16;
+ if (plane < 0 || (plane > 2 && plane != 14))
+ return UNASSIGNED_DIGIT;
+
+ jchar attr = readCodePoint(codePoint);
+ if (((1 << (attr & TYPE_MASK))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << DECIMAL_DIGIT_NUMBER))))
+ {
+ // Signedness doesn't matter; 0xffff vs. -1 are both rejected.
+ jint digit = (jint) numValue[plane][attr >> 7];
+ if (digit <= -3)
+ digit = largenums[-digit -3];
+ return (digit >= 0 && digit < radix) ? digit : (jint) -1;
+ }
+ return (jint) -1;
+
+}
+
+jint
+java::lang::Character::getNumericValue(jchar ch)
+{
+ // numValue is stored as an array of jshort, since 10000 is the maximum.
+ return (jint) numValue[0][readChar(ch) >> 7];
+}
+
+jint
+java::lang::Character::getNumericValue(jint codePoint)
+{
+ jint plane = codePoint >> 16;
+ if (plane < 0 || (plane > 2 && plane != 14))
+ return UNASSIGNED_NUMERIC_VALUE;
+ jshort num = numValue[plane][readCodePoint(codePoint) >> 7];
+ if (num <= -3)
+ return largenums[-num - 3];
+ return num;
+}
+
+jbyte
+java::lang::Character::getDirectionality(jchar ch)
+{
+ return direction[0][readChar(ch) >> 7];
+}
+
+jbyte
+java::lang::Character::getDirectionality(jint codePoint)
+{
+ jint plane = codePoint >> 16;
+ if (plane < 0 || (plane > 2 && plane != 14))
+ {
+ if (plane > 14 && ((codePoint & 0xffff) < 0xfffe))
+ return (jint) PRIVATE_DIRECTION;
+ return (jint) UNASSIGNED_DIRECTION;
+ }
+ return direction[plane][readCodePoint(codePoint) >> 7];
+}
diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc
new file mode 100644
index 000000000..d6969d49b
--- /dev/null
+++ b/libjava/java/lang/natClass.cc
@@ -0,0 +1,2089 @@
+// natClass.cc - Implementation of java.lang.Class native methods.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+ 2010 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <limits.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#pragma implementation "Class.h"
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-threads.h>
+
+#include <java/lang/Class.h>
+#include <java/lang/ClassLoader.h>
+#include <java/lang/String.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/reflect/Member.h>
+#include <java/lang/reflect/Method.h>
+#include <java/lang/reflect/Field.h>
+#include <java/lang/reflect/Proxy.h>
+#include <java/lang/reflect/Constructor.h>
+#include <java/lang/AbstractMethodError.h>
+#include <java/lang/ArrayStoreException.h>
+#include <java/lang/ClassCastException.h>
+#include <java/lang/ClassNotFoundException.h>
+#include <java/lang/ExceptionInInitializerError.h>
+#include <java/lang/IllegalAccessException.h>
+#include <java/lang/IllegalAccessError.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/NoSuchFieldError.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/InstantiationException.h>
+#include <java/lang/NoClassDefFoundError.h>
+#include <java/lang/NoSuchFieldException.h>
+#include <java/lang/NoSuchMethodError.h>
+#include <java/lang/NoSuchMethodException.h>
+#include <java/lang/Thread.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/RuntimePermission.h>
+#include <java/lang/System.h>
+#include <java/lang/SecurityException.h>
+#include <java/lang/SecurityManager.h>
+#include <java/lang/StringBuffer.h>
+#include <java/lang/VMClassLoader.h>
+#include <gcj/method.h>
+#include <gnu/gcj/RawData.h>
+#include <java/lang/VerifyError.h>
+#include <java/lang/InternalError.h>
+#include <java/lang/TypeNotPresentException.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Long.h>
+#include <java/lang/Character.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/annotation/Annotation.h>
+#include <java/util/HashMap.h>
+#include <java/util/Map.h>
+#include <sun/reflect/annotation/AnnotationInvocationHandler.h>
+#include <java/lang/Enum.h>
+
+#include <java-cpool.h>
+#include <java-interp.h>
+#include <java-assert.h>
+#include <java-stack.h>
+#include <execution.h>
+
+
+
+using namespace gcj;
+
+jclass
+java::lang::Class::forName (jstring className, jboolean initialize,
+ java::lang::ClassLoader *loader)
+{
+ if (! className)
+ throw new java::lang::NullPointerException;
+
+ jsize length = _Jv_GetStringUTFLength (className);
+ char buffer[length];
+ _Jv_GetStringUTFRegion (className, 0, className->length(), buffer);
+
+ _Jv_Utf8Const *name = _Jv_makeUtf8Const (buffer, length);
+
+ if (! _Jv_VerifyClassName (name))
+ throw new java::lang::ClassNotFoundException (className);
+
+ jclass klass = (buffer[0] == '['
+ ? _Jv_FindClassFromSignature (name->chars(), loader)
+ : _Jv_FindClass (name, loader));
+
+ if (klass == NULL)
+ throw new java::lang::ClassNotFoundException (className);
+
+ if (initialize)
+ _Jv_InitClass (klass);
+
+ return klass;
+}
+
+jclass
+java::lang::Class::forName (jstring className)
+{
+ java::lang::ClassLoader *loader = NULL;
+
+ jclass caller = _Jv_StackTrace::GetCallingClass (&Class::class$);
+ if (caller)
+ loader = caller->getClassLoaderInternal();
+
+ return forName (className, true, loader);
+}
+
+java::lang::ClassLoader *
+java::lang::Class::getClassLoader (void)
+{
+ java::lang::SecurityManager *s = java::lang::System::getSecurityManager();
+ if (s != NULL)
+ {
+ jclass caller = _Jv_StackTrace::GetCallingClass (&Class::class$);
+ return getClassLoader (caller);
+ }
+
+ return loader;
+}
+
+java::lang::ClassLoader *
+java::lang::Class::getClassLoader (jclass caller)
+{
+ java::lang::SecurityManager *s = java::lang::System::getSecurityManager();
+ if (s != NULL)
+ {
+ ClassLoader *caller_loader = caller->getClassLoaderInternal();
+
+ // If the caller has a non-null class loader, and that loader
+ // is not this class' loader or an ancestor thereof, then do a
+ // security check.
+ if (caller_loader != NULL && ! caller_loader->isAncestorOf(loader))
+ s->checkPermission (new RuntimePermission (JvNewStringLatin1 ("getClassLoader")));
+ }
+
+ return loader;
+}
+
+java::lang::reflect::Constructor *
+java::lang::Class::getConstructor (JArray<jclass> *param_types)
+{
+ memberAccessCheck(java::lang::reflect::Member::PUBLIC);
+
+ jstring partial_sig = getSignature (param_types, true);
+ jint hash = partial_sig->hashCode ();
+
+ int i = isPrimitive () ? 0 : method_count;
+ while (--i >= 0)
+ {
+ if (_Jv_equalUtf8Consts (methods[i].name, init_name)
+ && _Jv_equal (methods[i].signature, partial_sig, hash))
+ {
+ // Found it. For getConstructor, the constructor must be
+ // public.
+ using namespace java::lang::reflect;
+ if (! Modifier::isPublic(methods[i].accflags))
+ break;
+ Constructor *cons = new Constructor ();
+ cons->offset = (char *) (&methods[i]) - (char *) methods;
+ cons->declaringClass = this;
+ return cons;
+ }
+ }
+ throw new java::lang::NoSuchMethodException (_Jv_NewStringUtf8Const (init_name));
+}
+
+JArray<java::lang::reflect::Constructor *> *
+java::lang::Class::getDeclaredConstructors (jboolean publicOnly)
+{
+ int numConstructors = 0;
+ int max = isPrimitive () ? 0 : method_count;
+ int i;
+ for (i = max; --i >= 0; )
+ {
+ _Jv_Method *method = &methods[i];
+ if (method->name == NULL
+ || ! _Jv_equalUtf8Consts (method->name, init_name))
+ continue;
+ if (publicOnly
+ && ! java::lang::reflect::Modifier::isPublic(method->accflags))
+ continue;
+ numConstructors++;
+ }
+ JArray<java::lang::reflect::Constructor *> *result
+ = (JArray<java::lang::reflect::Constructor *> *)
+ JvNewObjectArray (numConstructors,
+ &java::lang::reflect::Constructor::class$,
+ NULL);
+ java::lang::reflect::Constructor** cptr = elements (result);
+ for (i = 0; i < max; i++)
+ {
+ _Jv_Method *method = &methods[i];
+ if (method->name == NULL
+ || ! _Jv_equalUtf8Consts (method->name, init_name))
+ continue;
+ if (publicOnly
+ && ! java::lang::reflect::Modifier::isPublic(method->accflags))
+ continue;
+ java::lang::reflect::Constructor *cons
+ = new java::lang::reflect::Constructor ();
+ cons->offset = (char *) method - (char *) methods;
+ cons->declaringClass = this;
+ *cptr++ = cons;
+ }
+ return result;
+}
+
+java::lang::reflect::Constructor *
+java::lang::Class::getDeclaredConstructor (JArray<jclass> *param_types)
+{
+ memberAccessCheck(java::lang::reflect::Member::DECLARED);
+
+ jstring partial_sig = getSignature (param_types, true);
+ jint hash = partial_sig->hashCode ();
+
+ int i = isPrimitive () ? 0 : method_count;
+ while (--i >= 0)
+ {
+ if (_Jv_equalUtf8Consts (methods[i].name, init_name)
+ && _Jv_equal (methods[i].signature, partial_sig, hash))
+ {
+ // Found it.
+ using namespace java::lang::reflect;
+ Constructor *cons = new Constructor ();
+ cons->offset = (char *) (&methods[i]) - (char *) methods;
+ cons->declaringClass = this;
+ return cons;
+ }
+ }
+ throw new java::lang::NoSuchMethodException (_Jv_NewStringUtf8Const (init_name));
+}
+
+java::lang::reflect::Field *
+java::lang::Class::getField (jstring name, jint hash)
+{
+ java::lang::reflect::Field* rfield;
+ for (int i = 0; i < field_count; i++)
+ {
+ _Jv_Field *field = &fields[i];
+ if (! _Jv_equal (field->name, name, hash))
+ continue;
+ if (! (field->getModifiers() & java::lang::reflect::Modifier::PUBLIC))
+ continue;
+ rfield = new java::lang::reflect::Field ();
+ rfield->offset = (char*) field - (char*) fields;
+ rfield->declaringClass = this;
+ rfield->name = name;
+ return rfield;
+ }
+ jclass superclass = getSuperclass();
+ if (superclass == NULL)
+ return NULL;
+ rfield = superclass->getField(name, hash);
+ for (int i = 0; i < interface_count && rfield == NULL; ++i)
+ rfield = interfaces[i]->getField (name, hash);
+ return rfield;
+}
+
+java::lang::reflect::Field *
+java::lang::Class::getDeclaredField (jstring name)
+{
+ memberAccessCheck(java::lang::reflect::Member::DECLARED);
+ int hash = name->hashCode();
+ for (int i = 0; i < field_count; i++)
+ {
+ _Jv_Field *field = &fields[i];
+ if (! _Jv_equal (field->name, name, hash))
+ continue;
+ java::lang::reflect::Field* rfield = new java::lang::reflect::Field ();
+ rfield->offset = (char*) field - (char*) fields;
+ rfield->declaringClass = this;
+ rfield->name = name;
+ return rfield;
+ }
+ throw new java::lang::NoSuchFieldException (name);
+}
+
+JArray<java::lang::reflect::Field *> *
+java::lang::Class::getDeclaredFields (jboolean public_only)
+{
+ int size;
+ if (public_only)
+ {
+ size = 0;
+ for (int i = 0; i < field_count; ++i)
+ {
+ _Jv_Field *field = &fields[i];
+ if ((field->flags & java::lang::reflect::Modifier::PUBLIC))
+ ++size;
+ }
+ }
+ else
+ size = field_count;
+
+ JArray<java::lang::reflect::Field *> *result
+ = (JArray<java::lang::reflect::Field *> *)
+ JvNewObjectArray (size, &java::lang::reflect::Field::class$, NULL);
+ java::lang::reflect::Field** fptr = elements (result);
+ for (int i = 0; i < field_count; i++)
+ {
+ _Jv_Field *field = &fields[i];
+ if (public_only
+ && ! (field->flags & java::lang::reflect::Modifier::PUBLIC))
+ continue;
+ java::lang::reflect::Field* rfield = new java::lang::reflect::Field ();
+ rfield->offset = (char*) field - (char*) fields;
+ rfield->declaringClass = this;
+ *fptr++ = rfield;
+ }
+ return result;
+}
+
+void
+java::lang::Class::getSignature (java::lang::StringBuffer *buffer)
+{
+ if (isPrimitive())
+ buffer->append((jchar) method_count);
+ else
+ {
+ jstring name = getName();
+ if (name->charAt(0) != '[')
+ buffer->append((jchar) 'L');
+ buffer->append(name);
+ if (name->charAt(0) != '[')
+ buffer->append((jchar) ';');
+ }
+}
+
+// This doesn't have to be native. It is an implementation detail
+// only called from the C++ code, though, so maybe this is clearer.
+jstring
+java::lang::Class::getSignature (JArray<jclass> *param_types,
+ jboolean is_constructor)
+{
+ java::lang::StringBuffer *buf = new java::lang::StringBuffer ();
+ buf->append((jchar) '(');
+ // A NULL param_types means "no parameters".
+ if (param_types != NULL)
+ {
+ jclass *v = elements (param_types);
+ for (int i = 0; i < param_types->length; ++i)
+ v[i]->getSignature(buf);
+ }
+ buf->append((jchar) ')');
+ if (is_constructor)
+ buf->append((jchar) 'V');
+ return buf->toString();
+}
+
+java::lang::reflect::Method *
+java::lang::Class::_getDeclaredMethod (jstring name,
+ JArray<jclass> *param_types)
+{
+ jstring partial_sig = getSignature (param_types, false);
+ jint p_len = partial_sig->length();
+ _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
+ int i = isPrimitive () ? 0 : method_count;
+ while (--i >= 0)
+ {
+ if (_Jv_equalUtf8Consts (methods[i].name, utf_name)
+ && _Jv_equaln (methods[i].signature, partial_sig, p_len)
+ && (methods[i].accflags
+ & java::lang::reflect::Modifier::INVISIBLE) == 0)
+ {
+ // Found it.
+ using namespace java::lang::reflect;
+ Method *rmethod = new Method ();
+ rmethod->offset = (char*) (&methods[i]) - (char*) methods;
+ rmethod->declaringClass = this;
+ return rmethod;
+ }
+ }
+ return NULL;
+}
+
+JArray<java::lang::reflect::Method *> *
+java::lang::Class::getDeclaredMethods (void)
+{
+ memberAccessCheck(java::lang::reflect::Member::DECLARED);
+
+ int numMethods = 0;
+ int max = isPrimitive () ? 0 : method_count;
+ int i;
+ for (i = max; --i >= 0; )
+ {
+ _Jv_Method *method = &methods[i];
+ if (method->name == NULL
+ || _Jv_equalUtf8Consts (method->name, clinit_name)
+ || _Jv_equalUtf8Consts (method->name, init_name)
+ || _Jv_equalUtf8Consts (method->name, finit_name)
+ || (methods[i].accflags
+ & java::lang::reflect::Modifier::INVISIBLE) != 0)
+ continue;
+ numMethods++;
+ }
+ JArray<java::lang::reflect::Method *> *result
+ = (JArray<java::lang::reflect::Method *> *)
+ JvNewObjectArray (numMethods, &java::lang::reflect::Method::class$, NULL);
+ java::lang::reflect::Method** mptr = elements (result);
+ for (i = 0; i < max; i++)
+ {
+ _Jv_Method *method = &methods[i];
+ if (method->name == NULL
+ || _Jv_equalUtf8Consts (method->name, clinit_name)
+ || _Jv_equalUtf8Consts (method->name, init_name)
+ || _Jv_equalUtf8Consts (method->name, finit_name)
+ || (methods[i].accflags
+ & java::lang::reflect::Modifier::INVISIBLE) != 0)
+ continue;
+ java::lang::reflect::Method* rmethod
+ = new java::lang::reflect::Method ();
+ rmethod->offset = (char*) method - (char*) methods;
+ rmethod->declaringClass = this;
+ *mptr++ = rmethod;
+ }
+ return result;
+}
+
+jstring
+java::lang::Class::getName (void)
+{
+ return name->toString();
+}
+
+JArray<jclass> *
+java::lang::Class::getInterfaces (void)
+{
+ jobjectArray r = JvNewObjectArray (interface_count, getClass (), NULL);
+ jobject *data = elements (r);
+ for (int i = 0; i < interface_count; ++i)
+ {
+ typedef unsigned int uaddr __attribute__ ((mode (pointer)));
+ data[i] = interfaces[i];
+ if ((uaddr)data[i] < (uaddr)constants.size)
+ fprintf (stderr, "ERROR !!!\n");
+ }
+ return reinterpret_cast<JArray<jclass> *> (r);
+}
+
+java::lang::reflect::Method *
+java::lang::Class::_getMethod (jstring name, JArray<jclass> *param_types)
+{
+ jstring partial_sig = getSignature (param_types, false);
+ jint p_len = partial_sig->length();
+ _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
+
+ for (Class *klass = this; klass; klass = klass->getSuperclass())
+ {
+ int i = klass->isPrimitive () ? 0 : klass->method_count;
+ while (--i >= 0)
+ {
+ if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
+ && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len)
+ && (klass->methods[i].accflags
+ & java::lang::reflect::Modifier::INVISIBLE) == 0)
+ {
+ // Found it.
+ using namespace java::lang::reflect;
+
+ // Method must be public.
+ if (! Modifier::isPublic (klass->methods[i].accflags))
+ break;
+
+ Method *rmethod = new Method ();
+ rmethod->offset = ((char *) (&klass->methods[i])
+ - (char *) klass->methods);
+ rmethod->declaringClass = klass;
+ return rmethod;
+ }
+ }
+ }
+
+ // If we haven't found a match, and this class is an interface, then
+ // check all the superinterfaces.
+ if (isInterface())
+ {
+ for (int i = 0; i < interface_count; ++i)
+ {
+ using namespace java::lang::reflect;
+ Method *rmethod = interfaces[i]->_getMethod (name, param_types);
+ if (rmethod != NULL)
+ return rmethod;
+ }
+ }
+
+ return NULL;
+}
+
+// This is a very slow implementation, since it re-scans all the
+// methods we've already listed to make sure we haven't duplicated a
+// method. It also over-estimates the required size, so we have to
+// shrink the result array later.
+jint
+java::lang::Class::_getMethods (JArray<java::lang::reflect::Method *> *result,
+ jint offset)
+{
+ jint count = 0;
+
+ // First examine all local methods
+ for (int i = isPrimitive () ? 0 : method_count; --i >= 0; )
+ {
+ _Jv_Method *method = &methods[i];
+ if (method->name == NULL
+ || _Jv_equalUtf8Consts (method->name, clinit_name)
+ || _Jv_equalUtf8Consts (method->name, init_name)
+ || _Jv_equalUtf8Consts (method->name, finit_name)
+ || (method->accflags
+ & java::lang::reflect::Modifier::INVISIBLE) != 0)
+ continue;
+ // Only want public methods.
+ if (! java::lang::reflect::Modifier::isPublic (method->accflags))
+ continue;
+
+ // This is where we over-count the slots required if we aren't
+ // filling the result for real.
+ if (result != NULL)
+ {
+ jboolean add = true;
+ java::lang::reflect::Method **mp = elements (result);
+ // If we already have a method with this name and signature,
+ // then ignore this one. This can happen with virtual
+ // methods.
+ for (int j = 0; j < offset; ++j)
+ {
+ _Jv_Method *meth_2 = _Jv_FromReflectedMethod (mp[j]);
+ if (_Jv_equalUtf8Consts (method->name, meth_2->name)
+ && _Jv_equalUtf8Consts (method->signature,
+ meth_2->signature))
+ {
+ add = false;
+ break;
+ }
+ }
+ if (! add)
+ continue;
+ }
+
+ if (result != NULL)
+ {
+ using namespace java::lang::reflect;
+ Method *rmethod = new Method ();
+ rmethod->offset = (char *) method - (char *) methods;
+ rmethod->declaringClass = this;
+ Method **mp = elements (result);
+ mp[offset + count] = rmethod;
+ }
+ ++count;
+ }
+ offset += count;
+
+ // Now examine superclasses.
+ if (getSuperclass () != NULL)
+ {
+ jint s_count = getSuperclass()->_getMethods (result, offset);
+ offset += s_count;
+ count += s_count;
+ }
+
+ // Finally, examine interfaces.
+ for (int i = 0; i < interface_count; ++i)
+ {
+ int f_count = interfaces[i]->_getMethods (result, offset);
+ count += f_count;
+ offset += f_count;
+ }
+
+ return count;
+}
+
+JArray<java::lang::reflect::Method *> *
+java::lang::Class::getMethods (void)
+{
+ using namespace java::lang::reflect;
+
+ memberAccessCheck(Member::PUBLIC);
+
+ // This will overestimate the size we need.
+ jint count = _getMethods (NULL, 0);
+
+ JArray<Method *> *result
+ = ((JArray<Method *> *) JvNewObjectArray (count,
+ &Method::class$,
+ NULL));
+
+ // When filling the array for real, we get the actual count. Then
+ // we resize the array.
+ jint real_count = _getMethods (result, 0);
+
+ if (real_count != count)
+ {
+ JArray<Method *> *r2
+ = ((JArray<Method *> *) JvNewObjectArray (real_count,
+ &Method::class$,
+ NULL));
+
+ Method **destp = elements (r2);
+ Method **srcp = elements (result);
+
+ for (int i = 0; i < real_count; ++i)
+ *destp++ = *srcp++;
+
+ result = r2;
+ }
+
+ return result;
+}
+
+jboolean
+java::lang::Class::isAssignableFrom (jclass klass)
+{
+ // Arguments may not have been initialized, given ".class" syntax.
+ // This ensures we can at least look at their superclasses.
+ _Jv_Linker::wait_for_state (this, JV_STATE_LOADING);
+ _Jv_Linker::wait_for_state (klass, JV_STATE_LOADING);
+ return _Jv_IsAssignableFrom (klass, this);
+}
+
+jboolean
+java::lang::Class::isInstance (jobject obj)
+{
+ if (! obj)
+ return false;
+ return _Jv_IsAssignableFrom (JV_CLASS (obj), this);
+}
+
+jobject
+java::lang::Class::newInstance (void)
+{
+ memberAccessCheck(java::lang::reflect::Member::PUBLIC);
+
+ if (isPrimitive ()
+ || isInterface ()
+ || isArray ()
+ || java::lang::reflect::Modifier::isAbstract(accflags))
+ throw new java::lang::InstantiationException (getName ());
+
+ _Jv_InitClass (this);
+
+ _Jv_Method *meth = _Jv_GetMethodLocal (this, init_name, void_signature);
+ if (! meth)
+ throw new java::lang::InstantiationException (getName());
+
+ jobject r = _Jv_AllocObject (this);
+ ((void (*) (jobject)) meth->ncode) (r);
+ return r;
+}
+
+void
+java::lang::Class::finalize (void)
+{
+ // Array classes don't have an engine, and don't need to be finalized.
+ if (engine)
+ engine->unregister(this);
+}
+
+#ifdef INTERPRETER
+void
+_Jv_ClosureList::releaseClosures (_Jv_ClosureList **closures)
+{
+ if (!closures)
+ return;
+
+ while (_Jv_ClosureList *current = *closures)
+ {
+ *closures = current->next;
+ ffi_closure_free (current->ptr);
+ }
+}
+
+void
+_Jv_ClosureList::registerClosure (jclass klass, void *ptr)
+{
+ _Jv_ClosureList **closures = klass->engine->get_closure_list (klass);
+ if (closures)
+ {
+ this->ptr = ptr;
+ this->next = *closures;
+ *closures = this;
+ }
+}
+#endif
+
+// This implements the initialization process for a class. From Spec
+// section 12.4.2.
+void
+java::lang::Class::initializeClass (void)
+{
+ // Short-circuit to avoid needless locking (expression includes
+ // JV_STATE_PHANTOM and JV_STATE_DONE).
+ if (state >= JV_STATE_PHANTOM)
+ return;
+
+ // Step 1. We introduce a new scope so we can synchronize more
+ // easily.
+ {
+ JvSynchronize sync (this);
+
+ if (state < JV_STATE_LINKED)
+ {
+ try
+ {
+ _Jv_Linker::wait_for_state(this, JV_STATE_LINKED);
+ }
+ catch (java::lang::SecurityException *x)
+ {
+ throw x;
+ }
+ catch (java::lang::Throwable *x)
+ {
+ // Turn into a NoClassDefFoundError.
+ java::lang::NoClassDefFoundError *result
+ = new java::lang::NoClassDefFoundError(getName());
+ result->initCause(x);
+ throw result;
+ }
+ }
+
+ // Step 2.
+ java::lang::Thread *self = java::lang::Thread::currentThread();
+ self = (java::lang::Thread *) ((long) self | 1);
+ while (state == JV_STATE_IN_PROGRESS && thread && thread != self)
+ wait ();
+
+ // Steps 3 & 4.
+ if (state == JV_STATE_DONE || state == JV_STATE_IN_PROGRESS)
+ return;
+
+ // Step 5.
+ if (state == JV_STATE_ERROR)
+ throw new java::lang::NoClassDefFoundError (getName());
+
+ // Step 6.
+ thread = self;
+ _Jv_Linker::wait_for_state (this, JV_STATE_LINKED);
+ state = JV_STATE_IN_PROGRESS;
+ }
+
+ // Step 7.
+ if (! isInterface () && superclass)
+ {
+ try
+ {
+ _Jv_InitClass (superclass);
+ }
+ catch (java::lang::SecurityException *x)
+ {
+ throw x;
+ }
+ catch (java::lang::Throwable *except)
+ {
+ // Caught an exception.
+ JvSynchronize sync (this);
+ state = JV_STATE_ERROR;
+ notifyAll ();
+ throw except;
+ }
+ }
+
+ // Steps 8, 9, 10, 11.
+ try
+ {
+ _Jv_Method *meth = _Jv_GetMethodLocal (this, clinit_name,
+ void_signature);
+ if (meth)
+ ((void (*) (void)) meth->ncode) ();
+ }
+ catch (java::lang::SecurityException *x)
+ {
+ throw x;
+ }
+ catch (java::lang::Throwable *except)
+ {
+ if (! java::lang::Error::class$.isInstance(except))
+ {
+ try
+ {
+ except = new ExceptionInInitializerError (except);
+ }
+ catch (java::lang::Throwable *t)
+ {
+ except = t;
+ }
+ }
+
+ JvSynchronize sync (this);
+ state = JV_STATE_ERROR;
+ notifyAll ();
+ throw except;
+ }
+
+ JvSynchronize sync (this);
+ state = JV_STATE_DONE;
+ notifyAll ();
+}
+
+// Only used by serialization
+java::lang::reflect::Field *
+java::lang::Class::getPrivateField (jstring name)
+{
+ int hash = name->hashCode ();
+
+ java::lang::reflect::Field* rfield;
+ for (int i = 0; i < field_count; i++)
+ {
+ _Jv_Field *field = &fields[i];
+ if (! _Jv_equal (field->name, name, hash))
+ continue;
+ rfield = new java::lang::reflect::Field ();
+ rfield->offset = (char*) field - (char*) fields;
+ rfield->declaringClass = this;
+ rfield->name = name;
+ return rfield;
+ }
+ jclass superclass = getSuperclass();
+ if (superclass == NULL)
+ return NULL;
+ rfield = superclass->getPrivateField(name);
+ for (int i = 0; i < interface_count && rfield == NULL; ++i)
+ rfield = interfaces[i]->getPrivateField (name);
+ return rfield;
+}
+
+// Only used by serialization
+java::lang::reflect::Method *
+java::lang::Class::getPrivateMethod (jstring name, JArray<jclass> *param_types)
+{
+ jstring partial_sig = getSignature (param_types, false);
+ jint p_len = partial_sig->length();
+ _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
+ for (Class *klass = this; klass; klass = klass->getSuperclass())
+ {
+ int i = klass->isPrimitive () ? 0 : klass->method_count;
+ while (--i >= 0)
+ {
+ if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
+ && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len))
+ {
+ // Found it.
+ using namespace java::lang::reflect;
+
+ Method *rmethod = new Method ();
+ rmethod->offset = ((char *) (&klass->methods[i])
+ - (char *) klass->methods);
+ rmethod->declaringClass = klass;
+ return rmethod;
+ }
+ }
+ }
+ throw new java::lang::NoSuchMethodException (name);
+}
+
+// Private accessor method for Java code to retrieve the protection domain.
+java::security::ProtectionDomain *
+java::lang::Class::getProtectionDomain0 ()
+{
+ return protectionDomain;
+}
+
+JArray<jobject> *
+java::lang::Class::getSigners()
+{
+ return hack_signers;
+}
+
+void
+java::lang::Class::setSigners(JArray<jobject> *s)
+{
+ hack_signers = s;
+}
+
+
+
+static unsigned char
+read_u1 (unsigned char *&p)
+{
+ return *p++;
+}
+
+static unsigned char
+read_u1 (unsigned char *&p, unsigned char *next)
+{
+ if (next - p < 1)
+ throw new java::lang::InternalError();
+ return *p++;
+}
+
+static unsigned int
+read_u2 (unsigned char *&p)
+{
+ unsigned int b1 = *p++;
+ unsigned int b2 = *p++;
+ return (b1 << 8) | b2;
+}
+
+static unsigned int
+read_u2 (unsigned char *&p, unsigned char *next)
+{
+ if (next - p < 2)
+ throw new java::lang::InternalError();
+ return read_u2 (p);
+}
+
+static int
+read_4 (unsigned char *&p)
+{
+ int b1 = *p++;
+ int b2 = *p++;
+ int b3 = *p++;
+ int b4 = *p++;
+ return (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
+}
+
+jstring
+java::lang::Class::getReflectionSignature (jint /*jv_attr_type*/ type,
+ jint obj_index)
+{
+ // We just re-parse the bytecode for this data each time. If
+ // necessary we can cache results, but I suspect this is not
+ // performance sensitive.
+ unsigned char *bytes = reflection_data;
+ if (bytes == NULL)
+ return NULL;
+ while (true)
+ {
+ int kind = read_u1 (bytes);
+ if (kind == JV_DONE_ATTR)
+ return NULL;
+ int len = read_4 (bytes);
+ unsigned char *next = bytes + len;
+ if (kind != type)
+ {
+ bytes = next;
+ continue;
+ }
+ if (type != JV_CLASS_ATTR)
+ {
+ unsigned short index = read_u2 (bytes, next);
+ if (index != obj_index)
+ {
+ bytes = next;
+ continue;
+ }
+ }
+ int nt = read_u1 (bytes, next);
+ if (nt != JV_SIGNATURE_KIND)
+ {
+ bytes = next;
+ continue;
+ }
+ unsigned int cpool_idx = read_u2 (bytes, next);
+ if (cpool_idx >= (unsigned int) constants.size
+ || constants.tags[cpool_idx] != JV_CONSTANT_Utf8)
+ {
+ // We just ignore errors for now. It isn't clear what is
+ // best to do here, as an encoding error here means a bug
+ // either in the compiler or in defineclass.cc.
+ return NULL;
+ }
+ return _Jv_NewStringUtf8Const (constants.data[cpool_idx].utf8);
+ }
+}
+
+jstring
+java::lang::Class::getReflectionSignature (::java::lang::reflect::Constructor *c)
+{
+ _Jv_Method *meth = _Jv_FromReflectedConstructor (c);
+ unsigned short meth_index = meth - methods;
+ return getReflectionSignature (JV_METHOD_ATTR, meth_index);
+}
+
+jstring
+java::lang::Class::getReflectionSignature (::java::lang::reflect::Method *m)
+{
+ _Jv_Method *meth = _Jv_FromReflectedMethod (m);
+ unsigned short meth_index = meth - methods;
+ return getReflectionSignature (JV_METHOD_ATTR, meth_index);
+}
+
+jstring
+java::lang::Class::getReflectionSignature (::java::lang::reflect::Field *f)
+{
+ _Jv_Field *fld = _Jv_FromReflectedField (f);
+ unsigned short fld_index = fld - fields;
+ return getReflectionSignature (JV_FIELD_ATTR, fld_index);
+}
+
+jstring
+java::lang::Class::getClassSignature()
+{
+ return getReflectionSignature (JV_CLASS_ATTR, 0);
+}
+
+jint
+java::lang::Class::getEnclosingMethodData()
+{
+ unsigned char *bytes = reflection_data;
+ if (bytes == NULL)
+ return 0;
+ while (true)
+ {
+ int kind = read_u1 (bytes);
+ if (kind == JV_DONE_ATTR)
+ return 0;
+ int len = read_4 (bytes);
+ unsigned char *next = bytes + len;
+ if (kind != JV_CLASS_ATTR)
+ {
+ bytes = next;
+ continue;
+ }
+ int type = read_u1 (bytes, next);
+ if (type != JV_ENCLOSING_METHOD_KIND)
+ {
+ bytes = next;
+ continue;
+ }
+ int class_index = read_u2 (bytes, next);
+ int method_index = read_u2 (bytes, next);
+ _Jv_word result;
+ _Jv_storeIndexes (&result, class_index, method_index);
+ return result.i;
+ }
+}
+
+jclass
+java::lang::Class::getEnclosingClass()
+{
+ _Jv_word indexes;
+ indexes.i = getEnclosingMethodData();
+ if (indexes.i == 0)
+ // No enclosing method, but perhaps a member or anonymous class
+ return getDeclaringClass();
+ _Jv_ushort class_index, method_index;
+ _Jv_loadIndexes (&indexes, class_index, method_index);
+ return _Jv_Linker::resolve_pool_entry (this, class_index).clazz;
+}
+
+::java::lang::reflect::Method *
+java::lang::Class::getEnclosingMethod()
+{
+ _Jv_word indexes;
+ indexes.i = getEnclosingMethodData();
+ if (indexes.i == 0)
+ return NULL;
+ _Jv_ushort class_index, method_index;
+ _Jv_loadIndexes (&indexes, class_index, method_index);
+ jclass found_class;
+ _Jv_Method *method = _Jv_Linker::resolve_method_entry (this, found_class,
+ class_index,
+ method_index,
+ false, false);
+ using namespace java::lang::reflect;
+ Method *rmethod = new Method ();
+ rmethod->offset = (char *) method - (char *) found_class->methods;
+ rmethod->declaringClass = found_class;
+ return rmethod;
+}
+
+::java::lang::reflect::Constructor *
+java::lang::Class::getEnclosingConstructor()
+{
+ _Jv_word indexes;
+ indexes.i = getEnclosingMethodData();
+ if (indexes.i == 0)
+ return NULL;
+ _Jv_ushort class_index, method_index;
+ _Jv_loadIndexes (&indexes, class_index, method_index);
+ jclass found_class;
+ _Jv_Method *method = _Jv_Linker::resolve_method_entry (this, found_class,
+ class_index,
+ method_index,
+ false, false);
+ using namespace java::lang::reflect;
+ Constructor *cons = new Constructor ();
+ cons->offset = (char *) method - (char *) found_class->methods;
+ cons->declaringClass = this;
+ return cons;
+}
+
+static void
+check_constant (_Jv_Constants *pool, jint cpool_index, jint type)
+{
+ if (cpool_index <= 0 || cpool_index >= pool->size)
+ throw new InternalError(JvNewStringLatin1("invalid constant pool index"));
+ if ((pool->tags[cpool_index] &
+ ~(JV_CONSTANT_ResolvedFlag|JV_CONSTANT_LazyFlag)) != type)
+ {
+ ::java::lang::StringBuffer *sb = new ::java::lang::StringBuffer();
+ sb->append(JvNewStringLatin1("expected pool constant "));
+ sb->append(type);
+ sb->append(JvNewStringLatin1(" but got "));
+ sb->append(jint (pool->tags[cpool_index]));
+ throw new InternalError(sb->toString());
+ }
+}
+
+// Forward declaration
+static ::java::lang::annotation::Annotation *
+parseAnnotation(jclass klass, _Jv_Constants *pool,
+ unsigned char *&bytes, unsigned char *last);
+
+static jobject
+parseAnnotationElement(jclass klass, _Jv_Constants *pool,
+ unsigned char *&bytes, unsigned char *last)
+{
+ int tag = read_u1 (bytes, last);
+ jobject result;
+ switch (tag)
+ {
+ case 'B':
+ {
+ int cindex = read_u2 (bytes, last);
+ check_constant (pool, cindex, JV_CONSTANT_Integer);
+ result = Byte::valueOf (pool->data[cindex].i);
+ }
+ break;
+ case 'C':
+ {
+ int cindex = read_u2 (bytes, last);
+ check_constant (pool, cindex, JV_CONSTANT_Integer);
+ result = Character::valueOf (pool->data[cindex].i);
+ }
+ break;
+ case 'S':
+ {
+ int cindex = read_u2 (bytes, last);
+ check_constant (pool, cindex, JV_CONSTANT_Integer);
+ result = Short::valueOf (pool->data[cindex].i);
+ }
+ break;
+ case 'Z':
+ {
+ int cindex = read_u2 (bytes, last);
+ check_constant (pool, cindex, JV_CONSTANT_Integer);
+ result = Boolean::valueOf (jboolean (pool->data[cindex].i));
+ }
+ break;
+ case 'I':
+ {
+ int cindex = read_u2 (bytes, last);
+ check_constant (pool, cindex, JV_CONSTANT_Integer);
+ result = Integer::valueOf (pool->data[cindex].i);
+ }
+ break;
+ case 'D':
+ {
+ int cindex = read_u2 (bytes, last);
+ check_constant (pool, cindex, JV_CONSTANT_Double);
+ _Jv_word2 word;
+ memcpy (&word, &pool->data[cindex], 2 * sizeof (_Jv_word));
+ result = Double::valueOf (word.d);
+ }
+ break;
+ case 'F':
+ {
+ int cindex = read_u2 (bytes, last);
+ check_constant (pool, cindex, JV_CONSTANT_Float);
+ result = Float::valueOf (pool->data[cindex].f);
+ }
+ break;
+ case 'J':
+ {
+ int cindex = read_u2 (bytes, last);
+ check_constant (pool, cindex, JV_CONSTANT_Long);
+ _Jv_word2 word;
+ memcpy (&word, &pool->data[cindex], 2 * sizeof (_Jv_word));
+ result = Long::valueOf (word.l);
+ }
+ break;
+ case 's':
+ {
+ int cindex = read_u2 (bytes, last);
+ // Despite what the JVM spec says, compilers generate a Utf8
+ // constant here, not a String.
+ check_constant (pool, cindex, JV_CONSTANT_Utf8);
+ result = pool->data[cindex].utf8->toString();
+ }
+ break;
+ case 'e':
+ {
+ int type_name_index = read_u2 (bytes, last);
+ check_constant (pool, type_name_index, JV_CONSTANT_Utf8);
+ int const_name_index = read_u2 (bytes, last);
+ check_constant (pool, const_name_index, JV_CONSTANT_Utf8);
+
+ _Jv_Utf8Const *u_name = pool->data[type_name_index].utf8;
+ _Jv_Utf8Const *e_name = pool->data[const_name_index].utf8;
+
+ // FIXME: throw correct exceptions at the correct times.
+ jclass e_class = _Jv_FindClassFromSignature(u_name->chars(),
+ klass->getClassLoaderInternal());
+ result = ::java::lang::Enum::valueOf(e_class, e_name->toString());
+ }
+ break;
+ case 'c':
+ {
+ int cindex = read_u2 (bytes, last);
+ check_constant (pool, cindex, JV_CONSTANT_Utf8);
+ _Jv_Utf8Const *u_name = pool->data[cindex].utf8;
+ jclass anno_class
+ = _Jv_FindClassFromSignatureNoException(u_name->chars(),
+ klass->getClassLoaderInternal());
+ // FIXME: not correct: we should lazily do this when trying to
+ // read the element. This means that
+ // AnnotationInvocationHandler needs to have a special case.
+ if (! anno_class)
+ // FIXME: original exception...
+ throw new TypeNotPresentException(u_name->toString(), NULL);
+ result = anno_class;
+ }
+ break;
+ case '@':
+ result = parseAnnotation (klass, pool, bytes, last);
+ break;
+ case '[':
+ {
+ int n_array_elts = read_u2 (bytes, last);
+ jobjectArray aresult = _Jv_NewObjectArray (n_array_elts,
+ &Object::class$, NULL);
+ jobject *elts = elements (aresult);
+ for (int i = 0; i < n_array_elts; ++i)
+ elts[i] = parseAnnotationElement(klass, pool, bytes, last);
+ result = aresult;
+ }
+ break;
+ default:
+ throw new java::lang::InternalError();
+ }
+ return result;
+}
+
+static ::java::lang::annotation::Annotation *
+parseAnnotation(jclass klass, _Jv_Constants *pool,
+ unsigned char *&bytes, unsigned char *last)
+{
+ int type_index = read_u2 (bytes, last);
+ check_constant (pool, type_index, JV_CONSTANT_Utf8);
+
+ _Jv_Utf8Const *u_name = pool->data[type_index].utf8;
+ jclass anno_class = _Jv_FindClassFromSignatureNoException(u_name->chars(),
+ klass->getClassLoaderInternal());
+ // FIXME: what to do if anno_class==NULL?
+
+ ::java::util::HashMap *hmap = new ::java::util::HashMap();
+ int npairs = read_u2 (bytes, last);
+ for (int i = 0; i < npairs; ++i)
+ {
+ int name_index = read_u2 (bytes, last);
+ check_constant (pool, name_index, JV_CONSTANT_Utf8);
+ jstring name = _Jv_NewStringUtf8Const (pool->data[name_index].utf8);
+ jobject value = parseAnnotationElement (klass, pool, bytes, last);
+ // FIXME: any checks needed for name?
+ hmap->put(name, value);
+ }
+ using namespace ::sun::reflect::annotation;
+ return AnnotationInvocationHandler::create (anno_class,
+ (::java::util::Map *) hmap);
+}
+
+static jobjectArray
+parseAnnotations(jclass klass, _Jv_Constants *pool,
+ unsigned char *&bytes, unsigned char *last)
+{
+ int num = read_u2 (bytes, last);
+ jobjectArray result = _Jv_NewObjectArray (num,
+ &::java::lang::annotation::Annotation::class$,
+ NULL);
+ jobject *elts = elements (result);
+ for (int i = 0; i < num; ++i)
+ elts[i] = parseAnnotation(klass, pool, bytes, last);
+ return result;
+}
+
+static jobjectArray
+parseParameterAnnotations(jclass klass, _Jv_Constants *pool,
+ unsigned char *&bytes, unsigned char *last)
+{
+ jclass anno = &::java::lang::annotation::Annotation::class$;
+ jclass annoary = _Jv_GetArrayClass (anno, anno->getClassLoaderInternal());
+
+ // FIXME: something should check the number of params versus the
+ // method
+ int n_params = read_u1 (bytes, last);
+ jobjectArray result = _Jv_NewObjectArray (n_params, annoary, NULL);
+ jobject *elts = elements (result);
+ for (int i = 0; i < n_params; ++i)
+ elts[i] = parseAnnotations(klass, pool, bytes, last);
+ return result;
+}
+
+jobject
+java::lang::Class::getMethodDefaultValue(::java::lang::reflect::Method *meth)
+{
+ // FIXME: could cache the value here...
+
+ unsigned char *bytes = reflection_data;
+ if (bytes == NULL)
+ return 0;
+
+ unsigned short meth_index = _Jv_FromReflectedMethod (meth) - methods;
+
+ while (true)
+ {
+ int type = read_u1 (bytes);
+ if (type == JV_DONE_ATTR)
+ return NULL;
+ int len = read_4 (bytes);
+ unsigned char *next = bytes + len;
+ if (type != JV_METHOD_ATTR)
+ {
+ bytes = next;
+ continue;
+ }
+ int kind = read_u1 (bytes, next);
+ if (kind != JV_ANNOTATION_DEFAULT_KIND)
+ {
+ bytes = next;
+ continue;
+ }
+ int index = read_u2 (bytes, next);
+ if (meth_index != index)
+ {
+ bytes = next;
+ continue;
+ }
+
+ // FIXME: could cache here. If we do then we have to clone any
+ // array result.
+ return parseAnnotationElement(this, &this->constants, bytes, next);
+ }
+}
+
+jobjectArray
+java::lang::Class::getDeclaredAnnotations(jint /* jv_attr_type */ member_type,
+ jint member_index,
+ jint /* jv_attr_kind */ kind_req)
+{
+ using namespace java::lang::annotation;
+ jobjectArray result;
+
+ unsigned char *bytes = reflection_data;
+ if (bytes == NULL)
+ return 0;
+
+ if (loader == NULL)
+ loader = (ClassLoader *)VMClassLoader::bootLoader;
+
+ result = (loader->getDeclaredAnnotations
+ (this, member_type, member_index, kind_req));
+ if (result)
+ return result;
+
+ for (;;)
+ {
+ int type = read_u1 (bytes);
+ if (type == JV_DONE_ATTR)
+ return NULL;
+ int len = read_4 (bytes);
+ unsigned char *next = bytes + len;
+ if (type != member_type)
+ {
+ bytes = next;
+ continue;
+ }
+ int kind = read_u1 (bytes, next);
+ if (kind != kind_req)
+ {
+ bytes = next;
+ continue;
+ }
+ if (member_type != JV_CLASS_ATTR)
+ {
+ int index = read_u2 (bytes, next);
+ if (member_index != index)
+ {
+ bytes = next;
+ continue;
+ }
+ }
+
+ if (kind_req == JV_PARAMETER_ANNOTATIONS_KIND)
+ result = ((parseParameterAnnotations
+ (this, &this->constants, bytes, next)));
+ else
+ result = ((parseAnnotations (this, &this->constants, bytes, next)));
+ break;
+ }
+
+ return (loader->putDeclaredAnnotations
+ (this, member_type, member_index, kind_req, result));
+}
+
+jobjectArray
+java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Method *meth,
+ jboolean is_param)
+{
+ unsigned short meth_index = _Jv_FromReflectedMethod (meth) - methods;
+ return getDeclaredAnnotations(JV_METHOD_ATTR, meth_index,
+ (is_param
+ ? JV_PARAMETER_ANNOTATIONS_KIND
+ : JV_ANNOTATIONS_KIND));
+}
+
+jobjectArray
+java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Constructor *cons,
+ jboolean is_param)
+{
+ unsigned short meth_index = _Jv_FromReflectedConstructor (cons) - methods;
+ return getDeclaredAnnotations(JV_METHOD_ATTR, meth_index,
+ (is_param
+ ? JV_PARAMETER_ANNOTATIONS_KIND
+ : JV_ANNOTATIONS_KIND));
+}
+
+jobjectArray
+java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Field *fld)
+{
+ unsigned short field_index = _Jv_FromReflectedField (fld) - fields;
+ return getDeclaredAnnotations(JV_FIELD_ATTR, field_index,
+ JV_ANNOTATIONS_KIND);
+}
+
+JArray< ::java::lang::annotation::Annotation *> *
+java::lang::Class::getDeclaredAnnotationsInternal()
+{
+ return (JArray< ::java::lang::annotation::Annotation *> *) getDeclaredAnnotations(JV_CLASS_ATTR, 0, JV_ANNOTATIONS_KIND);
+}
+
+static jclass
+resolve_class_constant (jclass klass, _Jv_Constants *pool, int cpool_index)
+{
+ check_constant (pool, cpool_index, JV_CONSTANT_Class);
+ // FIXME: what is the correct thing to do with an exception here?
+ return _Jv_Linker::resolve_pool_entry (klass, cpool_index, false).clazz;
+}
+
+jint
+java::lang::Class::findInnerClassAttribute()
+{
+ unsigned char *bytes = reflection_data;
+ if (bytes == NULL)
+ return -1;
+ while (true)
+ {
+ int type = read_u1 (bytes);
+ if (type == JV_DONE_ATTR)
+ break;
+ // After the type but before the length.
+ unsigned char *save = bytes;
+ int len = read_4 (bytes);
+ unsigned char *next = bytes + len;
+ if (type != JV_CLASS_ATTR)
+ {
+ bytes = next;
+ continue;
+ }
+ int kind = read_u1 (bytes, next);
+ if (kind != JV_INNER_CLASSES_KIND)
+ {
+ bytes = next;
+ continue;
+ }
+ return save - reflection_data;
+ }
+ return -1;
+}
+
+jint
+java::lang::Class::findDeclaredClasses(JArray<jclass> *result,
+ jboolean publicOnly,
+ jint offset)
+{
+ unsigned char *bytes = reflection_data + offset;
+ int len = read_4 (bytes);
+ unsigned char *next = bytes + len;
+ // Skip a byte.
+ read_u1 (bytes, next);
+ int n_classes = read_u2 (bytes, next);
+ int count = 0;
+ for (int i = 0; i < n_classes; ++i)
+ {
+ int inner_class_index = read_u2 (bytes, next);
+ int outer_class_index = read_u2 (bytes, next);
+ /*int inner_name_index = */ read_u2 (bytes, next);
+ int inner_flags = read_u2 (bytes, next);
+
+ if (inner_class_index == 0 || outer_class_index == 0)
+ continue;
+ if (resolve_class_constant (this, &constants, outer_class_index) == this)
+ {
+ jclass inner = resolve_class_constant (this, &constants,
+ inner_class_index);
+ if (! publicOnly
+ || ((inner_flags
+ & java::lang::reflect::Modifier::PUBLIC) != 0))
+ {
+ if (result)
+ {
+ jclass *elts = elements (result);
+ elts[count] = inner;
+ }
+ ++count;
+ }
+ }
+ }
+
+ return count;
+}
+
+JArray<jclass> *
+java::lang::Class::getDeclaredClasses (jboolean publicOnly)
+{
+ int offset = findInnerClassAttribute();
+ int count;
+ if (offset == -1)
+ {
+ // No InnerClasses attribute, so no declared classes.
+ count = 0;
+ }
+ else
+ count = findDeclaredClasses(NULL, publicOnly, offset);
+ JArray<jclass> *result
+ = (JArray<jclass> *) JvNewObjectArray (count, &java::lang::Class::class$,
+ NULL);
+ if (count > 0)
+ findDeclaredClasses(result, publicOnly, offset);
+ return result;
+}
+
+jclass
+java::lang::Class::getDeclaringClass (void)
+{
+ int offset = findInnerClassAttribute();
+ if (offset == -1)
+ return NULL;
+
+ unsigned char *bytes = reflection_data + offset;
+ int len = read_4 (bytes);
+ unsigned char *next = bytes + len;
+ // Skip a byte.
+ read_u1 (bytes, next);
+ int n_classes = read_u2 (bytes, next);
+ for (int i = 0; i < n_classes; ++i)
+ {
+ int inner_class_index = read_u2 (bytes, next);
+ int outer_class_index = read_u2 (bytes, next);
+ /*int inner_name_index = */read_u2 (bytes, next);
+ /*int inner_flags = */read_u2 (bytes, next);
+
+ if (inner_class_index == 0 || outer_class_index == 0)
+ continue;
+ if (resolve_class_constant (this, &constants, inner_class_index) == this)
+ return resolve_class_constant (this, &constants, outer_class_index);
+ }
+
+ return NULL;
+}
+
+jboolean
+java::lang::Class::isAnonymousClass()
+{
+ int offset = findInnerClassAttribute();
+ if (offset == -1)
+ return false;
+
+ unsigned char *bytes = reflection_data + offset;
+ int len = read_4 (bytes);
+ unsigned char *next = bytes + len;
+ // Skip a byte.
+ read_u1 (bytes, next);
+ int n_classes = read_u2 (bytes, next);
+ for (int i = 0; i < n_classes; ++i)
+ {
+ int inner_class_index = read_u2 (bytes, next);
+ /*int outer_class_index = */read_u2 (bytes, next);
+ int inner_name_index = read_u2 (bytes, next);
+ /*int inner_flags = */read_u2 (bytes, next);
+
+ if (inner_class_index == 0)
+ continue;
+ if (resolve_class_constant (this, &constants, inner_class_index) == this)
+ return inner_name_index == 0;
+ }
+
+ return false;
+}
+
+jboolean
+java::lang::Class::isLocalClass()
+{
+ _Jv_word indexes;
+ indexes.i = getEnclosingMethodData();
+ return indexes.i != 0;
+}
+
+jboolean
+java::lang::Class::isMemberClass()
+{
+ // FIXME: is this correct?
+ return !isLocalClass() && getDeclaringClass() != NULL;
+}
+
+
+
+//
+// Some class-related convenience functions.
+//
+
+// Find a method declared in the class. If it is not declared locally
+// (or if it is inherited), return NULL.
+_Jv_Method *
+_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature)
+{
+ for (int i = 0; i < klass->method_count; ++i)
+ {
+ if (_Jv_equalUtf8Consts (name, klass->methods[i].name)
+ && _Jv_equalUtf8Consts (signature, klass->methods[i].signature))
+ return &klass->methods[i];
+ }
+ return NULL;
+}
+
+_Jv_Method *
+_Jv_LookupDeclaredMethod (jclass klass, _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature,
+ jclass *declarer_result)
+{
+ for (; klass; klass = klass->getSuperclass())
+ {
+ _Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
+
+ if (meth)
+ {
+ if (declarer_result)
+ *declarer_result = klass;
+ return meth;
+ }
+ }
+
+ return NULL;
+}
+
+java::lang::reflect::Method *
+_Jv_GetReflectedMethod (jclass klass, _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature)
+{
+ for (; klass; klass = klass->getSuperclass())
+ {
+ _Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
+ if (meth)
+ {
+ using namespace java::lang::reflect;
+ Method *rmethod = new Method ();
+ rmethod->offset = (char*) meth - (char*) klass->methods;
+ rmethod->declaringClass = klass;
+ return rmethod;
+ }
+ }
+
+ return NULL;
+}
+
+#ifdef HAVE_TLS
+
+// NOTE: MCACHE_SIZE should be a power of 2 minus one.
+#define MCACHE_SIZE 31
+
+struct _Jv_mcache
+{
+ jclass klass;
+ _Jv_Method *method;
+};
+
+static __thread _Jv_mcache *method_cache;
+#endif // HAVE_TLS
+
+static void *
+_Jv_FindMethodInCache (jclass klass MAYBE_UNUSED,
+ _Jv_Utf8Const *name MAYBE_UNUSED,
+ _Jv_Utf8Const *signature MAYBE_UNUSED)
+{
+#ifdef HAVE_TLS
+ _Jv_mcache *cache = method_cache;
+ if (cache)
+ {
+ int index = name->hash16 () & MCACHE_SIZE;
+ _Jv_mcache *mc = &cache[index];
+ _Jv_Method *m = mc->method;
+
+ if (mc->klass == klass
+ && _Jv_equalUtf8Consts (m->name, name)
+ && _Jv_equalUtf8Consts (m->signature, signature))
+ return mc->method->ncode;
+ }
+#endif // HAVE_TLS
+ return NULL;
+}
+
+static void
+_Jv_AddMethodToCache (jclass klass MAYBE_UNUSED,
+ _Jv_Method *method MAYBE_UNUSED)
+{
+#ifdef HAVE_TLS
+ if (method_cache == NULL)
+ method_cache = (_Jv_mcache *) _Jv_MallocUnchecked((MCACHE_SIZE + 1)
+ * sizeof (_Jv_mcache));
+ // If the allocation failed, just keep going.
+ if (method_cache != NULL)
+ {
+ int index = method->name->hash16 () & MCACHE_SIZE;
+ method_cache[index].method = method;
+ method_cache[index].klass = klass;
+ }
+#endif // HAVE_TLS
+}
+
+// Free this thread's method cache. We explicitly manage this memory
+// as the GC does not yet know how to scan TLS on all platforms.
+void
+_Jv_FreeMethodCache ()
+{
+#ifdef HAVE_TLS
+ if (method_cache != NULL)
+ {
+ _Jv_Free(method_cache);
+ method_cache = NULL;
+ }
+#endif // HAVE_TLS
+}
+
+void *
+_Jv_LookupInterfaceMethod (jclass klass, _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature)
+{
+ using namespace java::lang::reflect;
+
+ void *ncode = _Jv_FindMethodInCache (klass, name, signature);
+ if (ncode != 0)
+ return ncode;
+
+ for (; klass; klass = klass->getSuperclass())
+ {
+ _Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
+ if (! meth)
+ continue;
+
+ if (Modifier::isStatic(meth->accflags))
+ throw new java::lang::IncompatibleClassChangeError
+ (_Jv_GetMethodString (klass, meth));
+ if (Modifier::isAbstract(meth->accflags))
+ throw new java::lang::AbstractMethodError
+ (_Jv_GetMethodString (klass, meth));
+ if (! Modifier::isPublic(meth->accflags))
+ throw new java::lang::IllegalAccessError
+ (_Jv_GetMethodString (klass, meth));
+
+ _Jv_AddMethodToCache (klass, meth);
+
+ return meth->ncode;
+ }
+ throw new java::lang::IncompatibleClassChangeError;
+}
+
+// Fast interface method lookup by index.
+void *
+_Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface, int method_idx)
+{
+ _Jv_IDispatchTable *cldt = klass->idt;
+ int idx = iface->ioffsets[cldt->iindex] + method_idx;
+ return cldt->itable[idx];
+}
+
+jboolean
+_Jv_IsAssignableFrom (jclass source, jclass target)
+{
+ if (source == target)
+ return true;
+
+ // If target is array, so must source be.
+ while (target->isArray ())
+ {
+ if (! source->isArray())
+ return false;
+ target = target->getComponentType();
+ source = source->getComponentType();
+ }
+
+ if (target->isInterface())
+ {
+ // Abstract classes have no IDT, and IDTs provide no way to check
+ // two interfaces for assignability.
+ if (__builtin_expect
+ (source->idt == NULL || source->isInterface(), false))
+ return _Jv_InterfaceAssignableFrom (source, target);
+
+ _Jv_IDispatchTable *cl_idt = source->idt;
+
+ if (__builtin_expect ((target->ioffsets == NULL), false))
+ return false; // No class implementing TARGET has been loaded.
+ jshort cl_iindex = cl_idt->iindex;
+ if (cl_iindex < target->ioffsets[0])
+ {
+ jshort offset = target->ioffsets[cl_iindex];
+ if (offset != -1 && offset < cl_idt->itable_length
+ && cl_idt->itable[offset] == target)
+ return true;
+ }
+ return false;
+ }
+
+ // Primitive TYPE classes are only assignable to themselves.
+ if (__builtin_expect (target->isPrimitive() || source->isPrimitive(), false))
+ return false;
+
+ if (target == &java::lang::Object::class$)
+ return true;
+ else if (source->ancestors == NULL || target->ancestors == NULL)
+ {
+ // We need this case when either SOURCE or TARGET has not has
+ // its constant-time tables prepared.
+
+ // At this point we know that TARGET can't be Object, so it is
+ // safe to use that as the termination point.
+ while (source && source != &java::lang::Object::class$)
+ {
+ if (source == target)
+ return true;
+ source = source->getSuperclass();
+ }
+ }
+ else if (source->depth >= target->depth
+ && source->ancestors[source->depth - target->depth] == target)
+ return true;
+
+ return false;
+}
+
+// Interface type checking, the slow way. Returns TRUE if IFACE is a
+// superinterface of SOURCE. This is used when SOURCE is also an interface,
+// or a class with no interface dispatch table.
+jboolean
+_Jv_InterfaceAssignableFrom (jclass source, jclass iface)
+{
+ for (int i = 0; i < source->interface_count; i++)
+ {
+ jclass interface = source->interfaces[i];
+ if (iface == interface
+ || _Jv_InterfaceAssignableFrom (interface, iface))
+ return true;
+ }
+
+ if (!source->isInterface()
+ && source->superclass
+ && _Jv_InterfaceAssignableFrom (source->superclass, iface))
+ return true;
+
+ return false;
+}
+
+jboolean
+_Jv_IsInstanceOf(jobject obj, jclass cl)
+{
+ if (__builtin_expect (!obj, false))
+ return false;
+ return _Jv_IsAssignableFrom (JV_CLASS (obj), cl);
+}
+
+void *
+_Jv_CheckCast (jclass c, jobject obj)
+{
+ if (__builtin_expect
+ (obj != NULL && ! _Jv_IsAssignableFrom(JV_CLASS (obj), c), false))
+ throw new java::lang::ClassCastException
+ ((new java::lang::StringBuffer
+ (obj->getClass()->getName()))->append
+ (JvNewStringUTF(" cannot be cast to "))->append
+ (c->getName())->toString());
+
+ return obj;
+}
+
+void
+_Jv_CheckArrayStore (jobject arr, jobject obj)
+{
+ if (obj)
+ {
+ JvAssert (arr != NULL);
+ jclass elt_class = (JV_CLASS (arr))->getComponentType();
+ if (elt_class == &java::lang::Object::class$)
+ return;
+ jclass obj_class = JV_CLASS (obj);
+ if (__builtin_expect
+ (! _Jv_IsAssignableFrom (obj_class, elt_class), false))
+ throw new java::lang::ArrayStoreException
+ ((new java::lang::StringBuffer
+ (JvNewStringUTF("Cannot store ")))->append
+ (obj_class->getName())->append
+ (JvNewStringUTF(" in array of type "))->append
+ (elt_class->getName())->toString());
+ }
+}
+
+jboolean
+_Jv_IsAssignableFromSlow (jclass source, jclass target)
+{
+ // First, strip arrays.
+ while (target->isArray ())
+ {
+ // If target is array, source must be as well.
+ if (! source->isArray ())
+ return false;
+ target = target->getComponentType ();
+ source = source->getComponentType ();
+ }
+
+ // Quick success.
+ if (target == &java::lang::Object::class$)
+ return true;
+
+ // Ensure that the classes have their supers installed.
+ _Jv_Linker::wait_for_state (source, JV_STATE_LOADING);
+ _Jv_Linker::wait_for_state (target, JV_STATE_LOADING);
+
+ do
+ {
+ if (source == target)
+ return true;
+
+ if (target->isPrimitive () || source->isPrimitive ())
+ return false;
+
+ if (target->isInterface ())
+ {
+ for (int i = 0; i < source->interface_count; ++i)
+ {
+ // We use a recursive call because we also need to
+ // check superinterfaces.
+ if (_Jv_IsAssignableFromSlow (source->getInterface (i), target))
+ return true;
+ }
+ }
+ source = source->getSuperclass ();
+ }
+ while (source != NULL);
+
+ return false;
+}
+
+// Lookup an interface method by name. This is very similar to
+// purpose to _getMethod, but the interfaces are quite different. It
+// might be a good idea for _getMethod to call this function.
+//
+// Return true of the method is found, with the class in FOUND_CLASS
+// and the index in INDEX.
+bool
+_Jv_getInterfaceMethod (jclass search_class, jclass &found_class, int &index,
+ const _Jv_Utf8Const *utf_name,
+ const _Jv_Utf8Const *utf_sig)
+{
+ for (jclass klass = search_class; klass; klass = klass->getSuperclass())
+ {
+ // FIXME: Throw an exception?
+ if (!klass->isInterface ())
+ return false;
+
+ int max = klass->method_count;
+ int offset = 0;
+ for (int i = 0; i < max; ++i)
+ {
+ // Skip <clinit> here, as it will not be in the IDT.
+ if (klass->methods[i].name->first() == '<')
+ continue;
+
+ if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
+ && _Jv_equalUtf8Consts (klass->methods[i].signature, utf_sig))
+ {
+ // Found it.
+ using namespace java::lang::reflect;
+
+ // FIXME: Method must be public. Throw an exception?
+ if (! Modifier::isPublic (klass->methods[i].accflags))
+ break;
+
+ found_class = klass;
+ // Interface method indexes count from 1.
+ index = offset + 1;
+ return true;
+ }
+
+ ++offset;
+ }
+ }
+
+ // If we haven't found a match, and this class is an interface, then
+ // check all the superinterfaces.
+ if (search_class->isInterface())
+ {
+ for (int i = 0; i < search_class->interface_count; ++i)
+ {
+ using namespace java::lang::reflect;
+ bool found = _Jv_getInterfaceMethod (search_class->interfaces[i],
+ found_class, index,
+ utf_name, utf_sig);
+ if (found)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+#ifdef INTERPRETER
+_Jv_MethodBase *
+_Jv_FindInterpreterMethod (jclass klass, jmethodID desired_method)
+{
+ using namespace java::lang::reflect;
+
+ _Jv_InterpClass *iclass
+ = reinterpret_cast<_Jv_InterpClass *> (klass->aux_info);
+ _Jv_MethodBase **imethods = _Jv_GetFirstMethod (iclass);
+
+ for (int i = 0; i < JvNumMethods (klass); ++i)
+ {
+ _Jv_MethodBase *imeth = imethods[i];
+ if (imeth->get_method () == desired_method)
+ return imeth;
+ }
+
+ return NULL;
+}
+#endif
+
+// Return Utf8 name of a class. This function is here for code that
+// can't access klass->name directly.
+_Jv_Utf8Const*
+_Jv_GetClassNameUtf8 (jclass klass)
+{
+ return klass->name;
+}
+
+jclass
+_Jv_GetMethodDeclaringClass (jmethodID method)
+{
+ _Jv_StackTrace::UpdateNCodeMap ();
+ jobject obj = reinterpret_cast<jobject> (method->ncode);
+ return reinterpret_cast<jclass> (_Jv_StackTrace::ncodeMap->get (obj));
+}
+
+jbyte
+_Jv_GetClassState (jclass klass)
+{
+ return klass->state;
+}
+
+#ifdef INTERPRETER
+jstring
+_Jv_GetInterpClassSourceFile (jclass klass)
+{
+ if (_Jv_IsInterpretedClass (klass))
+ {
+ _Jv_InterpClass *iclass =
+ reinterpret_cast<_Jv_InterpClass *> (klass->aux_info);
+ return iclass->source_file_name;
+ }
+
+ return NULL;
+}
+#endif
diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc
new file mode 100644
index 000000000..237e038d1
--- /dev/null
+++ b/libjava/java/lang/natClassLoader.cc
@@ -0,0 +1,734 @@
+// natClassLoader.cc - Implementation of java.lang.ClassLoader native methods.
+
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+/* Author: Kresten Krab Thorup <krab@gnu.org> */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <execution.h>
+
+#include <java-threads.h>
+#include <java-interp.h>
+
+#include <java/lang/Character.h>
+#include <java/lang/Thread.h>
+#include <java/lang/ClassLoader.h>
+#include <java/lang/InternalError.h>
+#include <java/lang/IllegalAccessError.h>
+#include <java/lang/LinkageError.h>
+#include <java/lang/NoClassDefFoundError.h>
+#include <java/lang/ClassNotFoundException.h>
+#include <java/lang/ClassCircularityError.h>
+#include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/ClassFormatError.h>
+#include <java/lang/VirtualMachineError.h>
+#include <java/lang/VMClassLoader.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/Runtime.h>
+#include <java/lang/StringBuffer.h>
+#include <java/io/Serializable.h>
+#include <java/lang/Cloneable.h>
+#include <java/lang/ref/WeakReference.h>
+#include <java/util/HashMap.h>
+#include <gnu/gcj/runtime/BootClassLoader.h>
+#include <gnu/gcj/runtime/SystemClassLoader.h>
+
+// Size of local hash table.
+#define HASH_LEN 1013
+
+// Hash function for Utf8Consts.
+#define HASH_UTF(Utf) ((Utf)->hash16() % HASH_LEN)
+
+// This records classes which will be registered with the system class
+// loader when it is initialized.
+static jclass system_class_list;
+
+// This is used as the value of system_class_list after we have
+// initialized the system class loader; it lets us know that we should
+// no longer pay attention to the system abi flag.
+#define SYSTEM_LOADER_INITIALIZED ((jclass) -1)
+
+static jclass loaded_classes[HASH_LEN];
+
+// This is the root of a linked list of classes
+static jclass stack_head;
+
+// While bootstrapping we keep a list of classes we found, so that we
+// can register their packages. There aren't many of these so we
+// just keep a small buffer here and abort if we overflow.
+#define BOOTSTRAP_CLASS_LIST_SIZE 20
+static jclass bootstrap_class_list[BOOTSTRAP_CLASS_LIST_SIZE];
+static int bootstrap_index;
+
+
+
+
+jclass
+java::lang::ClassLoader::loadClassFromSig(jstring name)
+{
+ int len = _Jv_GetStringUTFLength (name);
+ char sig[len + 1];
+ _Jv_GetStringUTFRegion (name, 0, name->length(), sig);
+ jclass result = _Jv_FindClassFromSignature(sig, this);
+ if (result == NULL)
+ throw new ClassNotFoundException(name);
+ return result;
+}
+
+
+
+// This tries to find a class in our built-in cache. This cache is
+// used only for classes which are linked in to the executable or
+// loaded via dlopen().
+jclass
+_Jv_FindClassInCache (_Jv_Utf8Const *name)
+{
+ JvSynchronize sync (&java::lang::Class::class$);
+ jint hash = HASH_UTF (name);
+
+ jclass klass;
+ for (klass = loaded_classes[hash]; klass; klass = klass->next_or_version)
+ {
+ if (_Jv_equalUtf8Consts (name, klass->name))
+ break;
+ }
+
+ return klass;
+}
+
+void
+_Jv_UnregisterClass (jclass the_class)
+{
+ // This can happen if the class could not be defined properly.
+ if (! the_class->name)
+ return;
+
+ JvSynchronize sync (&java::lang::Class::class$);
+ jint hash = HASH_UTF(the_class->name);
+
+ jclass *klass = &(loaded_classes[hash]);
+ for ( ; *klass; klass = &((*klass)->next_or_version))
+ {
+ if (*klass == the_class)
+ {
+ *klass = (*klass)->next_or_version;
+ break;
+ }
+ }
+}
+
+// Register an initiating class loader for a given class.
+void
+_Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
+{
+ if (! loader)
+ loader = java::lang::VMClassLoader::bootLoader;
+ if (! loader)
+ {
+ // Very early in the bootstrap process, the Bootstrap classloader may
+ // not exist yet.
+ // FIXME: We could maintain a list of these and come back and register
+ // them later.
+ return;
+ }
+
+ JvSynchronize sync (loader->loadingConstraints);
+
+ using namespace java::lang::ref;
+
+ jstring name = klass->getName();
+ WeakReference *ref = (WeakReference *) loader->loadingConstraints->get (name);
+ if (ref)
+ {
+ jclass constraint = (jclass) ref->get();
+ if (constraint && constraint != klass)
+ throw new java::lang::LinkageError(JvNewStringLatin1("loading constraint violated"));
+ }
+ loader->loadingConstraints->put(name, new WeakReference(klass));
+ loader->loadedClasses->put(name, klass);
+}
+
+// If we found an error while defining an interpreted class, we must
+// go back and unregister it.
+void
+_Jv_UnregisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
+{
+ if (! loader)
+ loader = java::lang::VMClassLoader::bootLoader;
+ loader->loadedClasses->remove(klass->name->toString());
+}
+
+// Check a loading constraint. In particular check that, if there is
+// a constraint for the name of KLASS in LOADER, that it maps to
+// KLASS. If there is no such constraint, make a new one. If the
+// constraint is violated, throw an exception. Do nothing for
+// primitive types.
+void
+_Jv_CheckOrCreateLoadingConstraint (jclass klass,
+ java::lang::ClassLoader *loader)
+{
+ // Strip arrays.
+ while (klass->isArray())
+ klass = klass->getComponentType();
+ // Ignore primitive types.
+ if (klass->isPrimitive())
+ return;
+
+ if (! loader)
+ loader = java::lang::VMClassLoader::bootLoader;
+ jstring name = klass->getName();
+
+ JvSynchronize sync (loader->loadingConstraints);
+
+ using namespace java::lang::ref;
+
+ WeakReference *ref = (WeakReference *) loader->loadingConstraints->get (name);
+ if (ref)
+ {
+ jclass constraint = (jclass) ref->get();
+ if (constraint)
+ {
+ if (klass != constraint)
+ throw new java::lang::LinkageError(JvNewStringLatin1("loading constraint violated"));
+ // Otherwise, all is ok.
+ return;
+ }
+ }
+ // No constraint (or old constraint GC'd). Make a new one.
+ loader->loadingConstraints->put(name, new WeakReference(klass));
+}
+
+
+// Class registration.
+//
+// There are two kinds of functions that register classes.
+//
+// Type 1:
+//
+// These take the address of a class that is in an object file.
+// Because these classes are not allocated on the heap, It is also
+// necessary to register the address of the object for garbage
+// collection. This is used with the "old" C++ ABI and with
+// -findirect-dispatch -fno-indirect-classes.
+//
+// Type 2:
+//
+// These take an initializer struct, create the class, and return the
+// address of the newly created class to their caller. These are used
+// with -findirect-dispatch.
+//
+// _Jv_RegisterClasses() and _Jv_RegisterClasses_Counted() are
+// functions of Type 1, and _Jv_NewClassFromInitializer() and
+// _Jv_RegisterNewClasses() are of Type 2.
+
+
+// Check that the file we're trying to load has been compiled with a
+// compatible version of gcj. In previous versions of libgcj we
+// silently failed to register classes of an incompatible ABI version,
+// but this was totally bogus.
+void
+_Jv_CheckABIVersion (unsigned long value)
+{
+ // We are compatible with GCJ 4.0.0 BC-ABI classes. This release used a
+ // different format for the version ID string.
+ if (value == OLD_GCJ_40_BC_ABI_VERSION)
+ return;
+
+ // The 20 low-end bits are used for the version number.
+ unsigned long version = value & 0xfffff;
+
+ if (value & FLAG_BINARYCOMPAT_ABI)
+ {
+ int abi_rev = version % 100;
+ int abi_ver = version - abi_rev;
+ // We are compatible with abi_rev 0 and 1.
+ if (abi_ver == GCJ_40_BC_ABI_VERSION && abi_rev <= 1)
+ return;
+ }
+ else
+ {
+ // C++ ABI
+ if (version == GCJ_CXX_ABI_VERSION)
+ return;
+
+ // If we've loaded a library that uses the C++ ABI, and this
+ // library is an incompatible version, then we're dead. There's
+ // no point throwing an exception: that will crash.
+ JvFail ("gcj linkage error.\n"
+ "Incorrect library ABI version detected. Aborting.\n");
+ }
+
+ throw new ::java::lang::ClassFormatError
+ (JvNewStringLatin1 ("Library compiled with later ABI version than"
+ " this version of libgcj supports"));
+}
+
+// This function is called many times during startup, before main() is
+// run. At that point in time we know for certain we are running
+// single-threaded, so we don't need to lock when adding classes to the
+// class chain. At all other times, the caller should synchronize on
+// Class::class$.
+void
+_Jv_RegisterClasses (const jclass *classes)
+{
+ _Jv_RegisterLibForGc (classes);
+
+ for (; *classes; ++classes)
+ {
+ jclass klass = *classes;
+
+ _Jv_CheckABIVersion ((unsigned long) klass->next_or_version);
+ (*_Jv_RegisterClassHook) (klass);
+ }
+}
+
+// This is a version of _Jv_RegisterClasses that takes a count.
+void
+_Jv_RegisterClasses_Counted (const jclass * classes, size_t count)
+{
+ size_t i;
+
+ _Jv_RegisterLibForGc (classes);
+
+ for (i = 0; i < count; i++)
+ {
+ jclass klass = classes[i];
+
+ _Jv_CheckABIVersion ((unsigned long) klass->next_or_version);
+ (*_Jv_RegisterClassHook) (klass);
+ }
+}
+
+// Create a class on the heap from an initializer struct.
+inline jclass
+_Jv_NewClassFromInitializer (const char *class_initializer)
+{
+ const unsigned long version
+ = ((unsigned long)
+ ((::java::lang::Class *)class_initializer)->next_or_version);
+ _Jv_CheckABIVersion (version);
+
+ /* We create an instance of java::lang::Class and copy all of its
+ fields except the first word (the vtable pointer) from
+ CLASS_INITIALIZER. This first word is pre-initialized by
+ _Jv_AllocObj, and we don't want to overwrite it. */
+
+ jclass new_class
+ = (jclass)_Jv_AllocObj (sizeof (::java::lang::Class),
+ &::java::lang::Class::class$);
+ const char *src = class_initializer + sizeof (void*);
+ char *dst = (char*)new_class + sizeof (void*);
+ size_t len = (::java::lang::Class::initializerSize (version)
+ - sizeof (void*));
+ memcpy (dst, src, len);
+
+ new_class->engine = &_Jv_soleIndirectCompiledEngine;
+
+ /* FIXME: Way back before the dawn of time, we overloaded the
+ SYNTHETIC class access modifier to mean INTERPRETED. This was a
+ Bad Thing, but it didn't matter then because classes were never
+ marked synthetic. However, it is possible to redeem the
+ situation: _Jv_NewClassFromInitializer is only called from
+ compiled classes, so we clear the INTERPRETED flag. This is a
+ kludge! */
+ new_class->accflags &= ~java::lang::reflect::Modifier::INTERPRETED;
+
+ (*_Jv_RegisterClassHook) (new_class);
+
+ return new_class;
+}
+
+// Called by compiler-generated code at DSO initialization. CLASSES
+// is an array of pairs: the first item of each pair is a pointer to
+// the initialized data that is a class initializer in a DSO, and the
+// second is a pointer to a class reference.
+// _Jv_NewClassFromInitializer() creates the new class (on the Java
+// heap) and we write the address of the new class into the address
+// pointed to by the second word.
+void
+_Jv_RegisterNewClasses (char **classes)
+{
+ _Jv_InitGC ();
+
+ const char *initializer;
+
+ while ((initializer = *classes++))
+ {
+ jclass *class_ptr = (jclass *)*classes++;
+ *class_ptr = _Jv_NewClassFromInitializer (initializer);
+ }
+}
+
+void
+_Jv_RegisterClassHookDefault (jclass klass)
+{
+ // This is bogus, but there doesn't seem to be a better place to do
+ // it.
+ if (! klass->engine)
+ klass->engine = &_Jv_soleCompiledEngine;
+
+ /* FIXME: Way back before the dawn of time, we overloaded the
+ SYNTHETIC class access modifier to mean INTERPRETED. This was a
+ Bad Thing, but it didn't matter then because classes were never
+ marked synthetic. However, it is possible to redeem the
+ situation: _Jv_RegisterClassHookDefault is only called from
+ compiled classes, so we clear the INTERPRETED flag. This is a
+ kludge! */
+ klass->accflags &= ~java::lang::reflect::Modifier::INTERPRETED;
+
+ if (system_class_list != SYSTEM_LOADER_INITIALIZED)
+ {
+ unsigned long abi = (unsigned long) klass->next_or_version;
+ if (! _Jv_ClassForBootstrapLoader (abi))
+ {
+ klass->next_or_version = system_class_list;
+ system_class_list = klass;
+ return;
+ }
+ }
+
+ jint hash = HASH_UTF (klass->name);
+
+ // If the class is already registered, don't re-register it.
+ for (jclass check_class = loaded_classes[hash];
+ check_class != NULL;
+ check_class = check_class->next_or_version)
+ {
+ if (check_class == klass)
+ {
+ // If you get this, it means you have the same class in two
+ // different libraries.
+#define TEXT "Duplicate class registration: "
+ // We size-limit MESSAGE so that you can't trash the stack.
+ char message[200];
+ strcpy (message, TEXT);
+ strncpy (message + sizeof (TEXT) - 1, klass->name->chars(),
+ sizeof (message) - sizeof (TEXT));
+ message[sizeof (message) - 1] = '\0';
+ if (! gcj::runtimeInitialized)
+ JvFail (message);
+ else
+ {
+ java::lang::String *str = JvNewStringLatin1 (message);
+ throw new java::lang::VirtualMachineError (str);
+ }
+ }
+ }
+
+ klass->next_or_version = loaded_classes[hash];
+ loaded_classes[hash] = klass;
+}
+
+// A pointer to a function that actually registers a class.
+// Normally _Jv_RegisterClassHookDefault, but could be some other function
+// that registers the class in e.g. a ClassLoader-local table.
+// Should synchronize on Class:class$ while setting/restore this variable.
+
+void (*_Jv_RegisterClassHook) (jclass cl) = _Jv_RegisterClassHookDefault;
+
+void
+_Jv_RegisterClass (jclass klass)
+{
+ jclass classes[2];
+ classes[0] = klass;
+ classes[1] = NULL;
+ _Jv_RegisterClasses (classes);
+}
+
+// This is used during initialization to register all compiled-in
+// classes that are not part of the core with the system class loader.
+void
+_Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::SystemClassLoader *loader)
+{
+ for (jclass klass = system_class_list;
+ klass;
+ klass = klass->next_or_version)
+ {
+ klass->loader = loader;
+ loader->addClass(klass);
+ }
+ system_class_list = SYSTEM_LOADER_INITIALIZED;
+}
+
+// An internal variant of _Jv_FindClass which simply swallows a
+// NoClassDefFoundError or a ClassNotFoundException. This gives the
+// caller a chance to evaluate the situation and behave accordingly.
+jclass
+_Jv_FindClassNoException (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
+{
+ jclass klass;
+
+ try
+ {
+ klass = _Jv_FindClass(name, loader);
+ }
+ catch ( java::lang::NoClassDefFoundError *ncdfe )
+ {
+ return NULL;
+ }
+ catch ( java::lang::ClassNotFoundException *cnfe )
+ {
+ return NULL;
+ }
+
+ return klass;
+}
+
+jclass
+_Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
+{
+ // See if the class was already loaded by this loader. This handles
+ // initiating loader checks, as we register classes with their
+ // initiating loaders.
+
+ java::lang::ClassLoader *boot = java::lang::VMClassLoader::bootLoader;
+ java::lang::ClassLoader *real = loader;
+ if (! real)
+ real = boot;
+ jstring sname = name->toString();
+ // We might still be bootstrapping the VM, in which case there
+ // won't be a bootstrap class loader yet.
+ jclass klass = real ? real->findLoadedClass (sname) : NULL;
+
+ if (! klass)
+ {
+ if (loader)
+ {
+ // Load using a user-defined loader, jvmspec 5.3.2.
+ // Note that we explicitly must call the single-argument form.
+ klass = loader->loadClass(sname);
+
+ // If "loader" delegated the loadClass operation to another
+ // loader, explicitly register that it is also an initiating
+ // loader of the given class.
+ java::lang::ClassLoader *delegate = (loader == boot
+ ? NULL
+ : loader);
+ if (klass && klass->getClassLoaderInternal () != delegate)
+ _Jv_RegisterInitiatingLoader (klass, loader);
+ }
+ else if (boot)
+ {
+ // Load using the bootstrap loader jvmspec 5.3.1.
+ klass = java::lang::VMClassLoader::loadClass (sname, false);
+
+ // Register that we're an initiating loader.
+ if (klass)
+ _Jv_RegisterInitiatingLoader (klass, 0);
+ }
+ else
+ {
+ // Not even a bootstrap loader, try the built-in cache.
+ klass = _Jv_FindClassInCache (name);
+
+ if (klass)
+ {
+ bool found = false;
+ for (int i = 0; i < bootstrap_index; ++i)
+ {
+ if (bootstrap_class_list[i] == klass)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (! found)
+ {
+ if (bootstrap_index == BOOTSTRAP_CLASS_LIST_SIZE)
+ abort ();
+ bootstrap_class_list[bootstrap_index++] = klass;
+ }
+ }
+ }
+ }
+
+ return klass;
+}
+
+void
+_Jv_RegisterBootstrapPackages ()
+{
+ for (int i = 0; i < bootstrap_index; ++i)
+ java::lang::VMClassLoader::definePackageForNative(bootstrap_class_list[i]->getName());
+}
+
+jclass
+_Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
+ java::lang::ClassLoader *loader)
+{
+ jclass ret = (jclass) _Jv_AllocObject (&java::lang::Class::class$);
+ ret->name = name;
+ ret->superclass = superclass;
+ ret->loader = loader;
+
+ _Jv_RegisterInitiatingLoader (ret, loader);
+
+ return ret;
+}
+
+static _Jv_IDispatchTable *array_idt = NULL;
+static jshort array_depth = 0;
+static jclass *array_ancestors = NULL;
+
+static jclass interfaces[] =
+{
+ &java::lang::Cloneable::class$,
+ &java::io::Serializable::class$
+};
+
+// Create a class representing an array of ELEMENT and store a pointer to it
+// in element->arrayclass. LOADER is the ClassLoader which _initiated_ the
+// instantiation of this array. ARRAY_VTABLE is the vtable to use for the new
+// array class. This parameter is optional.
+void
+_Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader,
+ _Jv_VTable *array_vtable)
+{
+ JvSynchronize sync (element);
+
+ _Jv_Utf8Const *array_name;
+ int len;
+
+ if (element->arrayclass)
+ return;
+
+ if (element->isPrimitive())
+ {
+ if (element == JvPrimClass (void))
+ throw new java::lang::ClassNotFoundException ();
+ len = 3;
+ }
+ else
+ len = element->name->len() + 5;
+
+ {
+ char signature[len];
+ int index = 0;
+ signature[index++] = '[';
+ // Compute name of array class.
+ if (element->isPrimitive())
+ {
+ signature[index++] = (char) element->method_count;
+ }
+ else
+ {
+ size_t length = element->name->len();
+ const char *const name = element->name->chars();
+ if (name[0] != '[')
+ signature[index++] = 'L';
+ memcpy (&signature[index], name, length);
+ index += length;
+ if (name[0] != '[')
+ signature[index++] = ';';
+ }
+ array_name = _Jv_makeUtf8Const (signature, index);
+ }
+
+ // Create new array class.
+ jclass array_class = _Jv_NewClass (array_name, &java::lang::Object::class$,
+ element->loader);
+
+ // Note that `vtable_method_count' doesn't include the initial
+ // gc_descr slot.
+ int dm_count = java::lang::Object::class$.vtable_method_count;
+
+ // Create a new vtable by copying Object's vtable.
+ _Jv_VTable *vtable;
+ if (array_vtable)
+ vtable = array_vtable;
+ else
+ vtable = _Jv_VTable::new_vtable (dm_count);
+ vtable->clas = array_class;
+ vtable->gc_descr = java::lang::Object::class$.vtable->gc_descr;
+ for (int i = 0; i < dm_count; ++i)
+ vtable->set_method (i, java::lang::Object::class$.vtable->get_method (i));
+
+ array_class->vtable = vtable;
+ array_class->vtable_method_count
+ = java::lang::Object::class$.vtable_method_count;
+
+ // Stash the pointer to the element type.
+ array_class->element_type = element;
+
+ // Register our interfaces.
+ array_class->interfaces = interfaces;
+ array_class->interface_count = sizeof interfaces / sizeof interfaces[0];
+
+ // Since all array classes have the same interface dispatch table, we can
+ // cache one and reuse it. It is not necessary to synchronize this.
+ if (!array_idt)
+ {
+ _Jv_Linker::wait_for_state(array_class, JV_STATE_PREPARED);
+ array_idt = array_class->idt;
+ array_depth = array_class->depth;
+ array_ancestors = array_class->ancestors;
+ }
+ else
+ {
+ array_class->idt = array_idt;
+ array_class->depth = array_depth;
+ array_class->ancestors = array_ancestors;
+ }
+
+ using namespace java::lang::reflect;
+ {
+ // Array classes are "abstract final" and inherit accessibility
+ // from element type, per vmspec 5.3.3.2
+ _Jv_ushort accflags = (Modifier::FINAL | Modifier::ABSTRACT
+ | (element->accflags
+ & (Modifier::PUBLIC | Modifier::PROTECTED
+ | Modifier::PRIVATE)));
+ array_class->accflags = accflags;
+ }
+
+ // An array class has no visible instance fields. "length" is invisible to
+ // reflection.
+
+ // Say this class is initialized and ready to go!
+ array_class->state = JV_STATE_DONE;
+
+ // vmspec, section 5.3.3 describes this
+ if (element->loader != loader)
+ _Jv_RegisterInitiatingLoader (array_class, loader);
+
+ element->arrayclass = array_class;
+}
+
+// These two functions form a stack of classes. When a class is loaded
+// it is pushed onto the stack by the class loader; this is so that
+// StackTrace can quickly determine which classes have been loaded.
+
+jclass
+_Jv_PopClass (void)
+{
+ JvSynchronize sync (&java::lang::Class::class$);
+ if (stack_head)
+ {
+ jclass tmp = stack_head;
+ stack_head = tmp->chain;
+ return tmp;
+ }
+ return NULL;
+}
+
+void
+_Jv_PushClass (jclass k)
+{
+ JvSynchronize sync (&java::lang::Class::class$);
+ jclass tmp = stack_head;
+ stack_head = k;
+ k->chain = tmp;
+}
diff --git a/libjava/java/lang/natEcosProcess.cc b/libjava/java/lang/natEcosProcess.cc
new file mode 100644
index 000000000..7d8edfb0e
--- /dev/null
+++ b/libjava/java/lang/natEcosProcess.cc
@@ -0,0 +1,25 @@
+// natEcosProcess.cc - Native side of eCos processes.
+
+/* Copyright (C) 1998, 1999, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// The configury system needs this file to exist, since we can't
+// really conditionally link files (an autoconf bug). To avoid having
+// an empty translation unit, we make a single method native. FIXME.
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/lang/EcosProcess.h>
+
+void
+java::lang::EcosProcess::destroy (void)
+{
+}
diff --git a/libjava/java/lang/natMath.cc b/libjava/java/lang/natMath.cc
new file mode 100644
index 000000000..d86d6307d
--- /dev/null
+++ b/libjava/java/lang/natMath.cc
@@ -0,0 +1,184 @@
+/* Copyright (C) 1998, 1999, 2000, 2002, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+/**
+ * @author Andrew Haley <aph@cygnus.com>
+ * @date Tue Sep 22 1998 */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+#include <config.h>
+
+#include <java/lang/String.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Math.h>
+#include <gcj/array.h>
+
+#include "fdlibm.h"
+
+jdouble java::lang::Math::cos(jdouble x)
+{
+ return (jdouble)::cos((double)x);
+}
+
+jdouble java::lang::Math::sin(jdouble x)
+{
+ return (jdouble)::sin((double)x);
+}
+
+jdouble java::lang::Math::tan(jdouble x)
+{
+ return (jdouble)::tan((double)x);
+}
+
+jdouble java::lang::Math::asin(jdouble x)
+{
+ return (jdouble)::asin((double)x);
+}
+
+jdouble java::lang::Math::acos(jdouble x)
+{
+ return (jdouble)::acos((double)x);
+}
+
+jdouble java::lang::Math::atan(jdouble x)
+{
+ return (jdouble)::atan((double)x);
+}
+
+jdouble java::lang::Math::atan2(jdouble y, jdouble x)
+{
+ return (jdouble)::atan2((double)y, (double)x);
+}
+
+jdouble java::lang::Math::log(jdouble x)
+{
+ return (jdouble)::log((double)x);
+}
+
+jdouble java::lang::Math::exp(jdouble x)
+{
+ return (jdouble)::exp((double)x);
+}
+
+jdouble java::lang::Math::sqrt(jdouble x)
+{
+ return (jdouble)::sqrt((double)x);
+}
+
+jdouble java::lang::Math::pow(jdouble y, jdouble x)
+{
+ return (jdouble)::pow((double)y, (double)x);
+}
+
+jdouble java::lang::Math::IEEEremainder(jdouble y, jdouble x)
+{
+ return (jdouble)::__ieee754_remainder((double)y, (double)x);
+}
+
+jdouble java::lang::Math::rint(jdouble x)
+{
+ return (jdouble)::rint((double)x);
+}
+
+jdouble java::lang::Math::floor(jdouble x)
+{
+ return (jdouble)::floor((double)x);
+}
+
+jdouble java::lang::Math::ceil(jdouble x)
+{
+ return (jdouble)::ceil((double)x);
+}
+
+jdouble java::lang::Math::log10(jdouble x)
+{
+ return (jdouble)::log10((double)x);
+}
+
+jdouble java::lang::Math::cbrt(jdouble x)
+{
+ return (jdouble)::cbrt((double)x);
+}
+
+jdouble java::lang::Math::cosh(jdouble x)
+{
+ return (jdouble)::cosh((double)x);
+}
+
+jdouble java::lang::Math::expm1(jdouble x)
+{
+ return (jdouble)::expm1((double)x);
+}
+
+jdouble java::lang::Math::hypot(jdouble x, jdouble y)
+{
+ return (jdouble)::hypot((double)x, (double)y);
+}
+
+jdouble java::lang::Math::log1p(jdouble x)
+{
+ return (jdouble)::log1p((double)x);
+}
+
+jdouble java::lang::Math::sinh(jdouble x)
+{
+ return (jdouble)::sinh((double)x);
+}
+
+jdouble java::lang::Math::tanh(jdouble x)
+{
+ return (jdouble)::tanh((double)x);
+}
+
+static inline int
+floatToIntBits (jfloat value)
+{
+ union {
+ jint l;
+ jfloat d;
+ } u;
+ u.d = value;
+ return u.l;
+}
+
+static inline bool
+isNaN (jint bits)
+{
+ jint e = bits & 0x7f800000;
+ jint f = bits & 0x007fffff;
+
+ return e == 0x7f800000 && f != 0;
+}
+
+static inline jlong
+doubleToLongBits (jdouble value)
+{
+ union {
+ jlong l;
+ jdouble d;
+ } u;
+ u.d = value;
+ return u.l;
+}
+
+static inline bool
+isNaN (jlong bits)
+{
+ jlong e = bits & 0x7ff0000000000000LL;
+ jlong f = bits & 0x000fffffffffffffLL;
+
+ return e == 0x7ff0000000000000LL && f != 0LL;
+}
+
diff --git a/libjava/java/lang/natObject.cc b/libjava/java/lang/natObject.cc
new file mode 100644
index 000000000..87f2044dd
--- /dev/null
+++ b/libjava/java/lang/natObject.cc
@@ -0,0 +1,1457 @@
+// natObject.cc - Implementation of the Object class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+#include <string.h>
+
+#pragma implementation "Object.h"
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/lang/Object.h>
+#include <java-threads.h>
+#include <java-signal.h>
+#include <java/lang/CloneNotSupportedException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IllegalMonitorStateException.h>
+#include <java/lang/InterruptedException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Class.h>
+#include <java/lang/Cloneable.h>
+#include <java/lang/Thread.h>
+
+#ifdef LOCK_DEBUG
+# include <stdio.h>
+#endif
+
+
+
+using namespace java::lang;
+
+// This is used to represent synchronization information.
+struct _Jv_SyncInfo
+{
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+ // We only need to keep track of initialization state if we can
+ // possibly finalize this object.
+ bool init;
+#endif
+ _Jv_ConditionVariable_t condition;
+ _Jv_Mutex_t mutex;
+};
+
+
+
+jclass
+java::lang::Object::getClass (void)
+{
+ _Jv_VTable **dt = (_Jv_VTable **) this;
+ return (*dt)->clas;
+}
+
+jint
+java::lang::Object::hashCode (void)
+{
+ return _Jv_HashCode (this);
+}
+
+jobject
+java::lang::Object::clone (void)
+{
+ jclass klass = getClass ();
+ jobject r;
+ jint size;
+
+ // We also clone arrays here. If we put the array code into
+ // __JArray, then we'd have to figure out a way to find the array
+ // vtbl when creating a new array class. This is easier, if uglier.
+ if (klass->isArray())
+ {
+ __JArray *array = (__JArray *) this;
+ jclass comp = getClass()->getComponentType();
+ jint eltsize;
+ if (comp->isPrimitive())
+ {
+ r = _Jv_NewPrimArray (comp, array->length);
+ eltsize = comp->size();
+ }
+ else
+ {
+ r = _Jv_NewObjectArray (array->length, comp, NULL);
+ eltsize = sizeof (jobject);
+ }
+ // We can't use sizeof on __JArray because we must account for
+ // alignment of the element type.
+ size = (_Jv_GetArrayElementFromElementType (array, comp) - (char *) array
+ + array->length * eltsize);
+ }
+ else
+ {
+ if (! java::lang::Cloneable::class$.isAssignableFrom(klass))
+ throw new CloneNotSupportedException;
+
+ size = klass->size();
+ r = _Jv_AllocObject (klass);
+ }
+
+ memcpy ((void *) r, (void *) this, size);
+#ifndef JV_HASH_SYNCHRONIZATION
+ // Guarantee that the locks associated to the two objects are
+ // distinct.
+ r->sync_info = NULL;
+#endif
+ return r;
+}
+
+void
+_Jv_FinalizeObject (jobject obj)
+{
+ // Ignore exceptions. From section 12.6 of the Java Language Spec.
+ try
+ {
+ obj->finalize ();
+ }
+ catch (java::lang::Throwable *t)
+ {
+ // Ignore.
+ }
+}
+
+
+//
+// Synchronization code.
+//
+
+#ifndef JV_HASH_SYNCHRONIZATION
+// This global is used to make sure that only one thread sets an
+// object's `sync_info' field.
+static _Jv_Mutex_t sync_mutex;
+
+// This macro is used to see if synchronization initialization is
+// needed.
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+# define INIT_NEEDED(Obj) (! (Obj)->sync_info \
+ || ! ((_Jv_SyncInfo *) ((Obj)->sync_info))->init)
+#else
+# define INIT_NEEDED(Obj) (! (Obj)->sync_info)
+#endif
+
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+// If we have to run a destructor for a sync_info member, then this
+// function is registered as a finalizer for the sync_info.
+static void
+finalize_sync_info (jobject obj)
+{
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj;
+#if defined (_Jv_HaveCondDestroy)
+ _Jv_CondDestroy (&si->condition);
+#endif
+#if defined (_Jv_HaveMutexDestroy)
+ _Jv_MutexDestroy (&si->mutex);
+#endif
+ si->init = false;
+}
+#endif
+
+// This is called to initialize the sync_info element of an object.
+void
+java::lang::Object::sync_init (void)
+{
+ _Jv_MutexLock (&sync_mutex);
+ // Check again to see if initialization is needed now that we have
+ // the lock.
+ if (INIT_NEEDED (this))
+ {
+ // We assume there are no pointers in the sync_info
+ // representation.
+ _Jv_SyncInfo *si;
+ // We always create a new sync_info, even if there is already
+ // one available. Any given object can only be finalized once.
+ // If we get here and sync_info is not null, then it has already
+ // been finalized. So if we just reinitialize the old one,
+ // we'll never be able to (re-)destroy the mutex and/or
+ // condition variable.
+ si = (_Jv_SyncInfo *) _Jv_AllocBytes (sizeof (_Jv_SyncInfo));
+ _Jv_MutexInit (&si->mutex);
+ _Jv_CondInit (&si->condition);
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+ // Register a finalizer.
+ si->init = true;
+ _Jv_RegisterFinalizer (si, finalize_sync_info);
+#endif
+ sync_info = (jobject) si;
+ }
+ _Jv_MutexUnlock (&sync_mutex);
+}
+
+void
+java::lang::Object::notify (void)
+{
+ if (__builtin_expect (INIT_NEEDED (this), false))
+ sync_init ();
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
+ if (__builtin_expect (_Jv_CondNotify (&si->condition, &si->mutex), false))
+ throw new IllegalMonitorStateException(JvNewStringLatin1
+ ("current thread not owner"));
+}
+
+void
+java::lang::Object::notifyAll (void)
+{
+ if (__builtin_expect (INIT_NEEDED (this), false))
+ sync_init ();
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
+ if (__builtin_expect (_Jv_CondNotifyAll (&si->condition, &si->mutex), false))
+ throw new IllegalMonitorStateException(JvNewStringLatin1
+ ("current thread not owner"));
+}
+
+void
+java::lang::Object::wait (jlong timeout, jint nanos)
+{
+ if (__builtin_expect (INIT_NEEDED (this), false))
+ sync_init ();
+ if (__builtin_expect (timeout < 0 || nanos < 0 || nanos > 999999, false))
+ throw new IllegalArgumentException;
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
+ switch (_Jv_CondWait (&si->condition, &si->mutex, timeout, nanos))
+ {
+ case _JV_NOT_OWNER:
+ throw new IllegalMonitorStateException (JvNewStringLatin1
+ ("current thread not owner"));
+ case _JV_INTERRUPTED:
+ if (Thread::interrupted ())
+ throw new InterruptedException;
+ }
+}
+
+//
+// Some runtime code.
+//
+
+// This function is called at system startup to initialize the
+// `sync_mutex'.
+void
+_Jv_InitializeSyncMutex (void)
+{
+ _Jv_MutexInit (&sync_mutex);
+}
+
+void
+_Jv_MonitorEnter (jobject obj)
+{
+#ifndef HANDLE_SEGV
+ if (__builtin_expect (! obj, false))
+ throw new java::lang::NullPointerException;
+#endif
+ if (__builtin_expect (INIT_NEEDED (obj), false))
+ obj->sync_init ();
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
+ _Jv_MutexLock (&si->mutex);
+ // FIXME: In the Windows case, this can return a nonzero error code.
+ // We should turn that into some exception ...
+}
+
+void
+_Jv_MonitorExit (jobject obj)
+{
+ JvAssert (obj);
+ JvAssert (! INIT_NEEDED (obj));
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
+ if (__builtin_expect (_Jv_MutexUnlock (&si->mutex), false))
+ throw new java::lang::IllegalMonitorStateException;
+}
+
+bool
+_Jv_ObjectCheckMonitor (jobject obj)
+{
+ if (__builtin_expect (INIT_NEEDED (obj), false))
+ obj->sync_init ();
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
+ return _Jv_MutexCheckMonitor (&si->mutex);
+}
+
+#else /* JV_HASH_SYNCHRONIZATION */
+
+// FIXME: We shouldn't be calling GC_register_finalizer directly.
+#ifndef HAVE_BOEHM_GC
+# error Hash synchronization currently requires boehm-gc
+// That's actually a bit of a lie: It should also work with the null GC,
+// probably even better than the alternative.
+// To really support alternate GCs here, we would need to widen the
+// interface to finalization, since we sometimes have to register a
+// second finalizer for an object that already has one.
+// We might also want to move the GC interface to a .h file, since
+// the number of procedure call levels involved in some of these
+// operations is already ridiculous, and would become worse if we
+// went through the proper intermediaries.
+#else
+# ifdef LIBGCJ_GC_DEBUG
+# define GC_DEBUG
+# endif
+# include "gc.h"
+#endif
+
+// What follows currenly assumes a Linux-like platform.
+// Some of it specifically assumes X86 or IA64 Linux, though that
+// should be easily fixable.
+
+// A Java monitor implemention based on a table of locks.
+// Each entry in the table describes
+// locks held for objects that hash to that location.
+// This started out as a reimplementation of the technique used in SGIs JVM,
+// for which we obtained permission from SGI.
+// But in fact, this ended up quite different, though some ideas are
+// still shared with the original.
+// It was also influenced by some of the published IBM work,
+// though it also differs in many ways from that.
+// We could speed this up if we had a way to atomically update
+// an entire cache entry, i.e. 2 contiguous words of memory.
+// That would usually be the case with a 32 bit ABI on a 64 bit processor.
+// But we don't currently go out of our way to target those.
+// I don't know how to do much better with a N bit ABI on a processor
+// that can atomically update only N bits at a time.
+// Author: Hans-J. Boehm (Hans_Boehm@hp.com, boehm@acm.org)
+
+#include <limits.h>
+#include <unistd.h> // for usleep, sysconf.
+#include <gcj/javaprims.h>
+#include <sysdep/locks.h>
+#include <java/lang/Thread.h>
+
+// Try to determine whether we are on a multiprocessor, i.e. whether
+// spinning may be profitable.
+// This should really use a suitable autoconf macro.
+// False is the conservative answer, though the right one is much better.
+static bool
+is_mp()
+{
+#ifdef _SC_NPROCESSORS_ONLN
+ long nprocs = sysconf(_SC_NPROCESSORS_ONLN);
+ return (nprocs > 1);
+#else
+ return false;
+#endif
+}
+
+// A call to keep_live(p) forces p to be accessible to the GC
+// at this point.
+inline static void
+keep_live(obj_addr_t p)
+{
+ __asm__ __volatile__("" : : "rm"(p) : "memory");
+}
+
+// Each hash table entry holds a single preallocated "lightweight" lock.
+// In addition, it holds a chain of "heavyweight" locks. Lightweight
+// locks do not support Object.wait(), and are converted to heavyweight
+// status in response to contention. Unlike the SGI scheme, both
+// ligtweight and heavyweight locks in one hash entry can be simultaneously
+// in use. (The SGI scheme requires that we be able to acquire a heavyweight
+// lock on behalf of another thread, and can thus convert a lock we don't
+// hold to heavyweight status. Here we don't insist on that, and thus
+// let the original holder of the lighweight lock keep it.)
+
+struct heavy_lock {
+ void * reserved_for_gc;
+ struct heavy_lock *next; // Hash chain link.
+ // Traced by GC.
+ void * old_client_data; // The only other field traced by GC.
+ GC_finalization_proc old_finalization_proc;
+ obj_addr_t address; // Object to which this lock corresponds.
+ // Should not be traced by GC.
+ // Cleared as heavy_lock is destroyed.
+ // Together with the rest of the heavy lock
+ // chain, this is protected by the lock
+ // bit in the hash table entry to which
+ // the chain is attached.
+ _Jv_SyncInfo si;
+ // The remaining fields save prior finalization info for
+ // the object, which we needed to replace in order to arrange
+ // for cleanup of the lock structure.
+};
+
+#ifdef LOCK_DEBUG
+void
+print_hl_list(heavy_lock *hl)
+{
+ heavy_lock *p = hl;
+ for (; 0 != p; p = p->next)
+ fprintf (stderr, "(hl = %p, addr = %p)", p, (void *)(p -> address));
+}
+#endif /* LOCK_DEBUG */
+
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+// If we have to run a destructor for a sync_info member, then this
+// function could be registered as a finalizer for the sync_info.
+// In fact, we now only invoke it explicitly.
+static inline void
+heavy_lock_finalization_proc (heavy_lock *hl)
+{
+#if defined (_Jv_HaveCondDestroy)
+ _Jv_CondDestroy (&hl->si.condition);
+#endif
+#if defined (_Jv_HaveMutexDestroy)
+ _Jv_MutexDestroy (&hl->si.mutex);
+#endif
+ hl->si.init = false;
+}
+#endif /* defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy) */
+
+// We convert the lock back to lightweight status when
+// we exit, so that a single contention episode doesn't doom the lock
+// forever. But we also need to make sure that lock structures for dead
+// objects are eventually reclaimed. We do that in a an additional
+// finalizer on the underlying object.
+// Note that if the corresponding object is dead, it is safe to drop
+// the heavy_lock structure from its list. It is not necessarily
+// safe to deallocate it, since the unlock code could still be running.
+
+struct hash_entry {
+ volatile obj_addr_t address; // Address of object for which lightweight
+ // k is held.
+ // We assume the 3 low order bits are zero.
+ // With the Boehm collector and bitmap
+ // allocation, objects of size 4 bytes are
+ // broken anyway. Thus this is primarily
+ // a constraint on statically allocated
+ // objects used for synchronization.
+ // This allows us to use the low order
+ // bits as follows:
+# define LOCKED 1 // This hash entry is locked, and its
+ // state may be invalid.
+ // The lock protects both the hash_entry
+ // itself (except for the light_count
+ // and light_thr_id fields, which
+ // are protected by the lightweight
+ // lock itself), and any heavy_monitor
+ // structures attached to it.
+# define HEAVY 2 // Heavyweight locks associated with this
+ // hash entry may be held.
+ // The lightweight entry is still valid,
+ // if the leading bits of the address
+ // field are nonzero.
+ // If the LOCKED bit is clear, then this is
+ // set exactly when heavy_count is > 0 .
+ // Stored redundantly so a single
+ // compare-and-swap works in the easy case.
+ // If HEAVY is not set, it is safe to use
+ // an available lightweight lock entry
+ // without checking if there is an existing
+ // heavyweight lock for the same object.
+ // (There may be one, but it won't be held
+ // or waited for.)
+# define REQUEST_CONVERSION 4 // The lightweight lock is held. But
+ // one or more other threads have tried
+ // to acquire the lock, and hence request
+ // conversion to heavyweight status.
+ // The heavyweight lock is already allocated.
+ // Threads requesting conversion are
+ // waiting on the condition variable associated
+ // with the heavyweight lock.
+ // Not used for conversion due to
+ // Object.wait() calls.
+# define FLAGS (LOCKED | HEAVY | REQUEST_CONVERSION)
+ volatile _Jv_ThreadId_t light_thr_id;
+ // Thr_id of holder of lightweight lock.
+ // Only updated by lightweight lock holder.
+ // Must be recognizably invalid if the
+ // lightweight lock is not held.
+# define INVALID_THREAD_ID 0 // Works for Linux?
+ // If zero doesn't work, we have to
+ // initialize lock table.
+ volatile unsigned short light_count;
+ // Number of times the lightweight lock
+ // is held minus one. Zero if lightweight
+ // lock is not held. Only updated by
+ // lightweight lock holder or, in one
+ // case, while holding the LOCKED bit in
+ // a state in which there can be no
+ // lightweight lock holder.
+ unsigned short heavy_count; // Total number of times heavyweight locks
+ // associated with this hash entry are held
+ // or waiting to be acquired.
+ // Threads in wait() are included eventhough
+ // they have temporarily released the lock.
+ // Protected by LOCKED bit.
+ // Threads requesting conversion to heavyweight
+ // status are also included.
+ struct heavy_lock * heavy_locks;
+ // Chain of heavy locks. Protected
+ // by lockbit for he. Locks may
+ // remain allocated here even if HEAVY
+ // is not set and heavy_count is 0.
+ // If a lightweight and heavyweight lock
+ // correspond to the same address, the
+ // lightweight lock is the right one.
+};
+
+#ifndef JV_SYNC_TABLE_SZ
+# define JV_SYNC_TABLE_SZ 2048 // Must be power of 2.
+#endif
+
+hash_entry light_locks[JV_SYNC_TABLE_SZ];
+
+#define JV_SYNC_HASH(p) (((long)p ^ ((long)p >> 10)) & (JV_SYNC_TABLE_SZ-1))
+
+// Note that the light_locks table is scanned conservatively by the
+// collector. It is essential the the heavy_locks field is scanned.
+// Currently the address field may or may not cause the associated object
+// to be retained, depending on whether flag bits are set.
+// This means that we can conceivable get an unexpected deadlock if
+// 1) Object at address A is locked.
+// 2) The client drops A without unlocking it.
+// 3) Flag bits in the address entry are set, so the collector reclaims
+// the object at A.
+// 4) A is reallocated, and an attempt is made to lock the result.
+// This could be fixed by scanning light_locks in a more customized
+// manner that ignores the flag bits. But it can only happen with hand
+// generated semi-illegal .class files, and then it doesn't present a
+// security hole.
+
+#ifdef LOCK_DEBUG
+ void print_he(hash_entry *he)
+ {
+ fprintf(stderr, "lock hash entry = %p, index = %d, address = 0x%lx\n"
+ "\tlight_thr_id = 0x%lx, light_count = %d, "
+ "heavy_count = %d\n\theavy_locks:", he,
+ he - light_locks, (unsigned long)(he -> address),
+ (unsigned long)(he -> light_thr_id),
+ he -> light_count, he -> heavy_count);
+ print_hl_list(he -> heavy_locks);
+ fprintf(stderr, "\n");
+ }
+#endif /* LOCK_DEBUG */
+
+#ifdef LOCK_LOG
+ // Log locking operations. For debugging only.
+ // Logging is intended to be as unintrusive as possible.
+ // Log calls are made after an operation completes, and hence
+ // may not completely reflect actual synchronization ordering.
+ // The choice of events to log is currently a bit haphazard.
+ // The intent is that if we have to track down any other bugs
+ // inthis code, we extend the logging as appropriate.
+ typedef enum
+ {
+ ACQ_LIGHT, ACQ_LIGHT2, ACQ_HEAVY, ACQ_HEAVY2, PROMOTE, REL_LIGHT,
+ REL_HEAVY, REQ_CONV, PROMOTE2, WAIT_START, WAIT_END, NOTIFY, NOTIFY_ALL
+ } event_type;
+
+ struct lock_history
+ {
+ event_type tp;
+ obj_addr_t addr; // Often includes flags.
+ _Jv_ThreadId_t thr;
+ };
+
+ const int LOG_SIZE = 128; // Power of 2.
+
+ lock_history lock_log[LOG_SIZE];
+
+ volatile obj_addr_t log_next = 0;
+ // Next location in lock_log.
+ // Really an int, but we need compare_and_swap.
+
+ static void add_log_entry(event_type t, obj_addr_t a, _Jv_ThreadId_t th)
+ {
+ obj_addr_t my_entry;
+ obj_addr_t next_entry;
+ do
+ {
+ my_entry = log_next;
+ next_entry = ((my_entry + 1) & (LOG_SIZE - 1));
+ }
+ while (!compare_and_swap(&log_next, my_entry, next_entry));
+ lock_log[my_entry].tp = t;
+ lock_log[my_entry].addr = a;
+ lock_log[my_entry].thr = th;
+ }
+
+# define LOG(t, a, th) add_log_entry(t, a, th)
+#else /* !LOCK_LOG */
+# define LOG(t, a, th)
+#endif
+
+static bool mp = false; // Known multiprocesssor.
+
+// Wait for roughly 2^n units, touching as little memory as possible.
+static void
+spin(unsigned n)
+{
+ const unsigned MP_SPINS = 10;
+ const unsigned YIELDS = 4;
+ const unsigned SPINS_PER_UNIT = 30;
+ const unsigned MIN_SLEEP_USECS = 2001; // Shorter times spin under Linux.
+ const unsigned MAX_SLEEP_USECS = 200000;
+ static unsigned spin_limit = 0;
+ static unsigned yield_limit = YIELDS;
+ static bool spin_initialized = false;
+
+ if (!spin_initialized)
+ {
+ mp = is_mp();
+ if (mp)
+ {
+ spin_limit = MP_SPINS;
+ yield_limit = MP_SPINS + YIELDS;
+ }
+ spin_initialized = true;
+ }
+ if (n < spin_limit)
+ {
+ unsigned i = SPINS_PER_UNIT << n;
+ for (; i > 0; --i)
+ __asm__ __volatile__("");
+ }
+ else if (n < yield_limit)
+ {
+ _Jv_ThreadYield();
+ }
+ else
+ {
+ unsigned duration = MIN_SLEEP_USECS << (n - yield_limit);
+ if (n >= 15 + yield_limit || duration > MAX_SLEEP_USECS)
+ duration = MAX_SLEEP_USECS;
+ _Jv_platform_usleep(duration);
+ }
+}
+
+// Wait for a hash entry to become unlocked.
+static void
+wait_unlocked (hash_entry *he)
+{
+ unsigned i = 0;
+ while (he -> address & LOCKED)
+ spin (i++);
+}
+
+// Return the heavy lock for addr if it was already allocated.
+// The client passes in the appropriate hash_entry.
+// We hold the lock for he.
+static inline heavy_lock *
+find_heavy (obj_addr_t addr, hash_entry *he)
+{
+ heavy_lock *hl = he -> heavy_locks;
+ while (hl != 0 && hl -> address != addr) hl = hl -> next;
+ return hl;
+}
+
+// Unlink the heavy lock for the given address from its hash table chain.
+// Dies miserably and conspicuously if it's not there, since that should
+// be impossible.
+static inline void
+unlink_heavy (obj_addr_t addr, hash_entry *he)
+{
+ heavy_lock **currentp = &(he -> heavy_locks);
+ while ((*currentp) -> address != addr)
+ currentp = &((*currentp) -> next);
+ *currentp = (*currentp) -> next;
+}
+
+// Finalization procedure for objects that have associated heavy-weight
+// locks. This may replace the real finalization procedure.
+static void
+heavy_lock_obj_finalization_proc (void *obj, void *cd)
+{
+ heavy_lock *hl = (heavy_lock *)cd;
+
+// This only addresses misalignment of statics, not heap objects. It
+// works only because registering statics for finalization is a noop,
+// no matter what the least significant bits are.
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+ obj_addr_t addr = (obj_addr_t)obj & ~((obj_addr_t)0x7);
+#else
+ obj_addr_t addr = (obj_addr_t)obj;
+#endif
+ hash_entry *he = light_locks + JV_SYNC_HASH(addr);
+ obj_addr_t he_address = (he -> address & ~LOCKED);
+
+ // Acquire lock bit immediately. It's possible that the hl was already
+ // destroyed while we were waiting for the finalizer to run. If it
+ // was, the address field was set to zero. The address filed access is
+ // protected by the lock bit to ensure that we do this exactly once.
+ // The lock bit also protects updates to the objects finalizer.
+ while (!compare_and_swap(&(he -> address), he_address, he_address|LOCKED ))
+ {
+ // Hash table entry is currently locked. We can't safely
+ // touch the list of heavy locks.
+ wait_unlocked(he);
+ he_address = (he -> address & ~LOCKED);
+ }
+ if (0 == hl -> address)
+ {
+ // remove_all_heavy destroyed hl, and took care of the real finalizer.
+ release_set(&(he -> address), he_address);
+ return;
+ }
+ JvAssert(hl -> address == addr);
+ GC_finalization_proc old_finalization_proc = hl -> old_finalization_proc;
+ if (old_finalization_proc != 0)
+ {
+ // We still need to run a real finalizer. In an idealized
+ // world, in which people write thread-safe finalizers, that is
+ // likely to require synchronization. Thus we reregister
+ // ourselves as the only finalizer, and simply run the real one.
+ // Thus we don't clean up the lock yet, but we're likely to do so
+ // on the next GC cycle.
+ // It's OK if remove_all_heavy actually destroys the heavy lock,
+ // since we've updated old_finalization_proc, and thus the user's
+ // finalizer won't be rerun.
+ void * old_client_data = hl -> old_client_data;
+ hl -> old_finalization_proc = 0;
+ hl -> old_client_data = 0;
+# ifdef HAVE_BOEHM_GC
+ GC_REGISTER_FINALIZER_NO_ORDER(obj, heavy_lock_obj_finalization_proc, cd, 0, 0);
+# endif
+ release_set(&(he -> address), he_address);
+ old_finalization_proc(obj, old_client_data);
+ }
+ else
+ {
+ // The object is really dead, although it's conceivable that
+ // some thread may still be in the process of releasing the
+ // heavy lock. Unlink it and, if necessary, register a finalizer
+ // to destroy sync_info.
+ unlink_heavy(addr, he);
+ hl -> address = 0; // Don't destroy it again.
+ release_set(&(he -> address), he_address);
+# if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+ // Make sure lock is not held and then destroy condvar and mutex.
+ _Jv_MutexLock(&(hl->si.mutex));
+ _Jv_MutexUnlock(&(hl->si.mutex));
+ heavy_lock_finalization_proc (hl);
+# endif
+ }
+}
+
+// We hold the lock on he, and heavy_count is 0.
+// Release the lock by replacing the address with new_address_val.
+// Remove all heavy locks on the list. Note that the only possible way
+// in which a lock may still be in use is if it's in the process of
+// being unlocked.
+// FIXME: Why does this unlock the hash entry? I think that
+// could now be done more cleanly in MonitorExit.
+static void
+remove_all_heavy (hash_entry *he, obj_addr_t new_address_val)
+{
+ JvAssert(he -> heavy_count == 0);
+ JvAssert(he -> address & LOCKED);
+ heavy_lock *hl = he -> heavy_locks;
+ he -> heavy_locks = 0;
+ // We would really like to release the lock bit here. Unfortunately, that
+ // Creates a race between or finalizer removal, and the potential
+ // reinstallation of a new finalizer as a new heavy lock is created.
+ // This may need to be revisited.
+ for(; 0 != hl; hl = hl->next)
+ {
+ obj_addr_t obj = hl -> address;
+ JvAssert(0 != obj); // If this was previously finalized, it should no
+ // longer appear on our list.
+ hl -> address = 0; // Finalization proc might still see it after we
+ // finish.
+ GC_finalization_proc old_finalization_proc = hl -> old_finalization_proc;
+ void * old_client_data = hl -> old_client_data;
+# ifdef HAVE_BOEHM_GC
+ // Remove our finalization procedure.
+ // Reregister the clients if applicable.
+ GC_REGISTER_FINALIZER_NO_ORDER((GC_PTR)obj, old_finalization_proc,
+ old_client_data, 0, 0);
+ // Note that our old finalization procedure may have been
+ // previously determined to be runnable, and may still run.
+ // FIXME - direct dependency on boehm GC.
+# endif
+# if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+ // Wait for a possible lock holder to finish unlocking it.
+ // This is only an issue if we have to explicitly destroy the mutex
+ // or possibly if we have to destroy a condition variable that is
+ // still being notified.
+ _Jv_MutexLock(&(hl->si.mutex));
+ _Jv_MutexUnlock(&(hl->si.mutex));
+ heavy_lock_finalization_proc (hl);
+# endif
+ }
+ release_set(&(he -> address), new_address_val);
+}
+
+// We hold the lock on he and heavy_count is 0.
+// We release it by replacing the address field with new_address_val.
+// Remove all heavy locks on the list if the list is sufficiently long.
+// This is called periodically to avoid very long lists of heavy locks.
+// This seems to otherwise become an issue with SPECjbb, for example.
+static inline void
+maybe_remove_all_heavy (hash_entry *he, obj_addr_t new_address_val)
+{
+ static const int max_len = 5;
+ heavy_lock *hl = he -> heavy_locks;
+
+ for (int i = 0; i < max_len; ++i)
+ {
+ if (0 == hl)
+ {
+ release_set(&(he -> address), new_address_val);
+ return;
+ }
+ hl = hl -> next;
+ }
+ remove_all_heavy(he, new_address_val);
+}
+
+// Allocate a new heavy lock for addr, returning its address.
+// Assumes we already have the hash_entry locked, and there
+// is currently no lightweight or allocated lock for addr.
+// We register a finalizer for addr, which is responsible for
+// removing the heavy lock when addr goes away, in addition
+// to the responsibilities of any prior finalizer.
+// This unfortunately holds the lock bit for the hash entry while it
+// allocates two objects (on for the finalizer).
+// It would be nice to avoid that somehow ...
+static heavy_lock *
+alloc_heavy(obj_addr_t addr, hash_entry *he)
+{
+ heavy_lock * hl = (heavy_lock *) _Jv_AllocTraceTwo(sizeof (heavy_lock));
+
+ hl -> address = addr;
+ _Jv_MutexInit (&(hl -> si.mutex));
+ _Jv_CondInit (&(hl -> si.condition));
+# if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+ hl->si.init = true; // needed ?
+# endif
+ hl -> next = he -> heavy_locks;
+ he -> heavy_locks = hl;
+ // FIXME: The only call that cheats and goes directly to the GC interface.
+# ifdef HAVE_BOEHM_GC
+ GC_REGISTER_FINALIZER_NO_ORDER(
+ (void *)addr, heavy_lock_obj_finalization_proc,
+ hl, &hl->old_finalization_proc,
+ &hl->old_client_data);
+# endif /* HAVE_BOEHM_GC */
+ return hl;
+}
+
+// Return the heavy lock for addr, allocating if necessary.
+// Assumes we have the cache entry locked, and there is no lightweight
+// lock for addr.
+static heavy_lock *
+get_heavy(obj_addr_t addr, hash_entry *he)
+{
+ heavy_lock *hl = find_heavy(addr, he);
+ if (0 == hl)
+ hl = alloc_heavy(addr, he);
+ return hl;
+}
+
+void
+_Jv_MonitorEnter (jobject obj)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+ obj_addr_t addr = (obj_addr_t)obj & ~((obj_addr_t)FLAGS);
+#else
+ obj_addr_t addr = (obj_addr_t)obj;
+#endif
+ obj_addr_t address;
+ unsigned hash = JV_SYNC_HASH(addr);
+ hash_entry * he = light_locks + hash;
+ _Jv_ThreadId_t self = _Jv_ThreadSelf();
+ unsigned count;
+ const unsigned N_SPINS = 18;
+
+ // We need to somehow check that addr is not NULL on the fast path.
+ // A very predictable
+ // branch on a register value is probably cheaper than dereferencing addr.
+ // We could also permanently lock the NULL entry in the hash table.
+ // But it's not clear that's cheaper either.
+ if (__builtin_expect(!addr, false))
+ throw new java::lang::NullPointerException;
+
+ JvAssert(!(addr & FLAGS));
+retry:
+ if (__builtin_expect(compare_and_swap(&(he -> address),
+ 0, addr),true))
+ {
+ JvAssert(he -> light_thr_id == INVALID_THREAD_ID);
+ JvAssert(he -> light_count == 0);
+ he -> light_thr_id = self;
+ // Count fields are set correctly. Heavy_count was also zero,
+ // but can change asynchronously.
+ // This path is hopefully both fast and the most common.
+ LOG(ACQ_LIGHT, addr, self);
+ return;
+ }
+ address = he -> address;
+ if ((address & ~(HEAVY | REQUEST_CONVERSION)) == addr)
+ {
+ if (he -> light_thr_id == self)
+ {
+ // We hold the lightweight lock, and it's for the right
+ // address.
+ count = he -> light_count;
+ if (count == USHRT_MAX)
+ {
+ // I think most JVMs don't check for this.
+ // But I'm not convinced I couldn't turn this into a security
+ // hole, even with a 32 bit counter.
+ throw new java::lang::IllegalMonitorStateException(
+ JvNewStringLatin1("maximum monitor nesting level exceeded"));
+ }
+ he -> light_count = count + 1;
+ return;
+ }
+ else
+ {
+ JvAssert(!(address & LOCKED));
+ // Lightweight lock is held, but by somone else.
+ // Spin a few times. This avoids turning this into a heavyweight
+ // lock if the current holder is about to release it.
+ // FIXME: Does this make sense on a uniprocessor, where
+ // it actually yields? It's probably cheaper to convert.
+ for (unsigned int i = 0; i < N_SPINS; ++i)
+ {
+ if ((he -> address & ~LOCKED) != address) goto retry;
+ spin(i);
+ }
+ if (!compare_and_swap(&(he -> address), address, address | LOCKED ))
+ {
+ wait_unlocked(he);
+ goto retry;
+ }
+ heavy_lock *hl = get_heavy(addr, he);
+ ++ (he -> heavy_count);
+ // The hl lock acquisition can't block for long, since it can
+ // only be held by other threads waiting for conversion, and
+ // they, like us, drop it quickly without blocking.
+ _Jv_MutexLock(&(hl->si.mutex));
+ JvAssert(he -> address == address | LOCKED );
+ release_set(&(he -> address), (address | REQUEST_CONVERSION | HEAVY));
+ // release lock on he
+ LOG(REQ_CONV, (address | REQUEST_CONVERSION | HEAVY), self);
+ // If _Jv_CondWait is interrupted, we ignore the interrupt, but
+ // restore the thread's interrupt status flag when done.
+ jboolean interrupt_flag = false;
+ while ((he -> address & ~FLAGS) == (address & ~FLAGS))
+ {
+ // Once converted, the lock has to retain heavyweight
+ // status, since heavy_count > 0.
+ int r = _Jv_CondWait (&(hl->si.condition), &(hl->si.mutex), 0, 0);
+ if (r == _JV_INTERRUPTED)
+ {
+ interrupt_flag = true;
+ Thread::currentThread()->interrupt_flag = false;
+ }
+ }
+ if (interrupt_flag)
+ Thread::currentThread()->interrupt_flag = interrupt_flag;
+ keep_live(addr);
+ // Guarantee that hl doesn't get unlinked by finalizer.
+ // This is only an issue if the client fails to release
+ // the lock, which is unlikely.
+ JvAssert(he -> address & HEAVY);
+ // Lock has been converted, we hold the heavyweight lock,
+ // heavy_count has been incremented.
+ return;
+ }
+ }
+ obj_addr_t was_heavy = (address & HEAVY);
+ if ((address & LOCKED) ||
+ !compare_and_swap(&(he -> address), address, (address | LOCKED )))
+ {
+ wait_unlocked(he);
+ goto retry;
+ }
+ if ((address & ~(HEAVY | REQUEST_CONVERSION)) == 0)
+ {
+ // Either was_heavy is true, or something changed out from under us,
+ // since the initial test for 0 failed.
+ JvAssert(!(address & REQUEST_CONVERSION));
+ // Can't convert a nonexistent lightweight lock.
+ heavy_lock *hl;
+ hl = (was_heavy? find_heavy(addr, he) : 0);
+ // The CAS succeeded, so was_heavy is still accurate.
+ if (0 == hl)
+ {
+ // It is OK to use the lighweight lock, since either the
+ // heavyweight lock does not exist, or none of the
+ // heavyweight locks are currently in use. Future threads
+ // trying to acquire the lock will see the lightweight
+ // one first and use that.
+ he -> light_thr_id = self; // OK, since nobody else can hold
+ // light lock or do this at the same time.
+ JvAssert(he -> light_count == 0);
+ JvAssert(was_heavy == (he -> address & HEAVY));
+ release_set(&(he -> address), (addr | was_heavy));
+ LOG(ACQ_LIGHT2, addr | was_heavy, self);
+ }
+ else
+ {
+ // Must use heavy lock.
+ ++ (he -> heavy_count);
+ JvAssert(0 == (address & ~HEAVY));
+ release_set(&(he -> address), HEAVY);
+ LOG(ACQ_HEAVY, addr | was_heavy, self);
+ _Jv_MutexLock(&(hl->si.mutex));
+ keep_live(addr);
+ }
+ return;
+ }
+ // Lightweight lock is held, but does not correspond to this object.
+ // We hold the lock on the hash entry, and he -> address can't
+ // change from under us. Neither can the chain of heavy locks.
+ {
+ JvAssert(0 == he -> heavy_count || (address & HEAVY));
+ heavy_lock *hl = get_heavy(addr, he);
+ ++ (he -> heavy_count);
+ release_set(&(he -> address), address | HEAVY);
+ LOG(ACQ_HEAVY2, address | HEAVY, self);
+ _Jv_MutexLock(&(hl->si.mutex));
+ keep_live(addr);
+ }
+}
+
+
+void
+_Jv_MonitorExit (jobject obj)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+ obj_addr_t addr = (obj_addr_t)obj & ~((obj_addr_t)FLAGS);
+#else
+ obj_addr_t addr = (obj_addr_t)obj;
+#endif
+ _Jv_ThreadId_t self = _Jv_ThreadSelf();
+ unsigned hash = JV_SYNC_HASH(addr);
+ hash_entry * he = light_locks + hash;
+ _Jv_ThreadId_t light_thr_id;
+ unsigned count;
+ obj_addr_t address;
+
+retry:
+ light_thr_id = he -> light_thr_id;
+ // Unfortunately, it turns out we always need to read the address
+ // first. Even if we are going to update it with compare_and_swap,
+ // we need to reset light_thr_id, and that's not safe unless we know
+ // that we hold the lock.
+ address = he -> address;
+ // First the (relatively) fast cases:
+ if (__builtin_expect(light_thr_id == self, true))
+ // Above must fail if addr == 0 .
+ {
+ count = he -> light_count;
+ if (__builtin_expect((address & ~HEAVY) == addr, true))
+ {
+ if (count != 0)
+ {
+ // We held the lightweight lock all along. Thus the values
+ // we saw for light_thr_id and light_count must have been valid.
+ he -> light_count = count - 1;
+ return;
+ }
+ else
+ {
+ // We hold the lightweight lock once.
+ he -> light_thr_id = INVALID_THREAD_ID;
+ if (compare_and_swap_release(&(he -> address), address,
+ address & HEAVY))
+ {
+ LOG(REL_LIGHT, address & HEAVY, self);
+ return;
+ }
+ else
+ {
+ he -> light_thr_id = light_thr_id; // Undo prior damage.
+ goto retry;
+ }
+ }
+ }
+ // else lock is not for this address, conversion is requested,
+ // or the lock bit in the address field is set.
+ }
+ else
+ {
+ if (__builtin_expect(!addr, false))
+ throw new java::lang::NullPointerException;
+ if ((address & ~(HEAVY | REQUEST_CONVERSION)) == addr)
+ {
+# ifdef LOCK_DEBUG
+ fprintf(stderr, "Lightweight lock held by other thread\n\t"
+ "light_thr_id = 0x%lx, self = 0x%lx, "
+ "address = 0x%lx, heavy_count = %d, pid = %d\n",
+ light_thr_id, self, (unsigned long)address,
+ he -> heavy_count, getpid());
+ print_he(he);
+ for(;;) {}
+# endif
+ // Someone holds the lightweight lock for this object, and
+ // it can't be us.
+ throw new java::lang::IllegalMonitorStateException(
+ JvNewStringLatin1("current thread not owner"));
+ }
+ else
+ count = he -> light_count;
+ }
+ if (address & LOCKED)
+ {
+ wait_unlocked(he);
+ goto retry;
+ }
+ // Now the unlikely cases.
+ // We do know that:
+ // - Address is set, and doesn't contain the LOCKED bit.
+ // - If address refers to the same object as addr, then he -> light_thr_id
+ // refers to this thread, and count is valid.
+ // - The case in which we held the lightweight lock has been
+ // completely handled, except for the REQUEST_CONVERSION case.
+ //
+ if ((address & ~FLAGS) == addr)
+ {
+ // The lightweight lock is assigned to this object.
+ // Thus we must be in the REQUEST_CONVERSION case.
+ if (0 != count)
+ {
+ // Defer conversion until we exit completely.
+ he -> light_count = count - 1;
+ return;
+ }
+ JvAssert(he -> light_thr_id == self);
+ JvAssert(address & REQUEST_CONVERSION);
+ // Conversion requested
+ // Convert now.
+ if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+ goto retry;
+ heavy_lock *hl = find_heavy(addr, he);
+ JvAssert (0 != hl);
+ // Requestor created it.
+ he -> light_count = 0;
+ JvAssert(he -> heavy_count > 0);
+ // was incremented by requestor.
+ _Jv_MutexLock(&(hl->si.mutex));
+ // Release the he lock after acquiring the mutex.
+ // Otherwise we can accidentally
+ // notify a thread that has already seen a heavyweight
+ // lock.
+ he -> light_thr_id = INVALID_THREAD_ID;
+ release_set(&(he -> address), HEAVY);
+ LOG(PROMOTE, address, self);
+ // lightweight lock now unused.
+ _Jv_CondNotifyAll(&(hl->si.condition), &(hl->si.mutex));
+ _Jv_MutexUnlock(&(hl->si.mutex));
+ // heavy_count was already incremented by original requestor.
+ keep_live(addr);
+ return;
+ }
+ // lightweight lock not for this object.
+ JvAssert(!(address & LOCKED));
+ JvAssert((address & ~FLAGS) != addr);
+ if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+ goto retry;
+ heavy_lock *hl = find_heavy(addr, he);
+ if (NULL == hl)
+ {
+# ifdef LOCK_DEBUG
+ fprintf(stderr, "Failed to find heavyweight lock for addr 0x%lx"
+ " pid = %d\n", addr, getpid());
+ print_he(he);
+ for(;;) {}
+# endif
+ release_set(&(he -> address), address);
+ throw new java::lang::IllegalMonitorStateException(
+ JvNewStringLatin1("current thread not owner"));
+ }
+ JvAssert(address & HEAVY);
+ count = he -> heavy_count;
+ JvAssert(count > 0);
+ --count;
+ he -> heavy_count = count;
+ if (0 == count)
+ {
+ const unsigned test_freq = 16; // Power of 2
+ static volatile unsigned counter = 0;
+ unsigned my_counter = counter;
+
+ counter = my_counter + 1;
+ if (my_counter%test_freq == 0)
+ {
+ // Randomize the interval length a bit.
+ counter = my_counter + (my_counter >> 4) % (test_freq/2);
+ // Unlock mutex first, to avoid self-deadlock, or worse.
+ _Jv_MutexUnlock(&(hl->si.mutex));
+ maybe_remove_all_heavy(he, address &~HEAVY);
+ // release lock bit, preserving
+ // REQUEST_CONVERSION
+ // and object address.
+ }
+ else
+ {
+ release_set(&(he -> address), address &~HEAVY);
+ _Jv_MutexUnlock(&(hl->si.mutex));
+ // Unlock after releasing the lock bit, so that
+ // we don't switch to another thread prematurely.
+ }
+ }
+ else
+ {
+ release_set(&(he -> address), address);
+ _Jv_MutexUnlock(&(hl->si.mutex));
+ }
+ LOG(REL_HEAVY, addr, self);
+ keep_live(addr);
+}
+
+// Return false if obj's monitor is held by the current thread
+bool
+_Jv_ObjectCheckMonitor (jobject obj)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+ obj_addr_t addr = (obj_addr_t)obj & ~((obj_addr_t)FLAGS);
+#else
+ obj_addr_t addr = (obj_addr_t)obj;
+#endif
+ obj_addr_t address;
+ unsigned hash = JV_SYNC_HASH(addr);
+ hash_entry * he = light_locks + hash;
+
+ JvAssert(!(addr & FLAGS));
+ address = he -> address;
+ // Try it the easy way first:
+ if (address == 0) return true;
+ _Jv_ThreadId_t self = _Jv_ThreadSelf();
+ if ((address & ~(HEAVY | REQUEST_CONVERSION)) == addr)
+ // Fails if entry is LOCKED.
+ // I can't asynchronously become or stop being the holder.
+ return he -> light_thr_id != self;
+retry:
+ // Acquire the hash table entry lock
+ address &= ~LOCKED;
+ if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+ {
+ wait_unlocked(he);
+ goto retry;
+ }
+
+ bool not_mine;
+
+ if ((address & ~FLAGS) == addr)
+ not_mine = (he -> light_thr_id != self);
+ else
+ {
+ heavy_lock* hl = find_heavy(addr, he);
+ not_mine = hl ? _Jv_MutexCheckMonitor(&hl->si.mutex) : true;
+ }
+
+ release_set(&(he -> address), address); // unlock hash entry
+ return not_mine;
+}
+
+// The rest of these are moderately thin veneers on _Jv_Cond ops.
+// The current version of Notify might be able to make the pthread
+// call AFTER releasing the lock, thus saving some context switches??
+
+void
+java::lang::Object::wait (jlong timeout, jint nanos)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+ obj_addr_t addr = (obj_addr_t)this & ~((obj_addr_t)FLAGS);
+#else
+ obj_addr_t addr = (obj_addr_t)this;
+#endif
+ _Jv_ThreadId_t self = _Jv_ThreadSelf();
+ unsigned hash = JV_SYNC_HASH(addr);
+ hash_entry * he = light_locks + hash;
+ unsigned count;
+ obj_addr_t address;
+ heavy_lock *hl;
+
+ if (__builtin_expect (timeout < 0 || nanos < 0 || nanos > 999999, false))
+ throw new IllegalArgumentException;
+retry:
+ address = he -> address;
+ address &= ~LOCKED;
+ if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+ {
+ wait_unlocked(he);
+ goto retry;
+ }
+ // address did not have the lock bit set. We now hold the lock on he.
+ if ((address & ~FLAGS) == addr)
+ {
+ // Convert to heavyweight.
+ if (he -> light_thr_id != self)
+ {
+# ifdef LOCK_DEBUG
+ fprintf(stderr, "Found wrong lightweight lock owner in wait "
+ "address = 0x%lx pid = %d\n", address, getpid());
+ print_he(he);
+ for(;;) {}
+# endif
+ release_set(&(he -> address), address);
+ throw new IllegalMonitorStateException (JvNewStringLatin1
+ ("current thread not owner"));
+ }
+ count = he -> light_count;
+ hl = get_heavy(addr, he);
+ he -> light_count = 0;
+ he -> heavy_count += count + 1;
+ for (unsigned i = 0; i <= count; ++i)
+ _Jv_MutexLock(&(hl->si.mutex));
+ // Again release the he lock after acquiring the mutex.
+ he -> light_thr_id = INVALID_THREAD_ID;
+ release_set(&(he -> address), HEAVY); // lightweight lock now unused.
+ LOG(PROMOTE2, addr, self);
+ if (address & REQUEST_CONVERSION)
+ _Jv_CondNotifyAll (&(hl->si.condition), &(hl->si.mutex));
+ // Since we do this before we do a CondWait, we guarantee that
+ // threads waiting on requested conversion are awoken before
+ // a real wait on the same condition variable.
+ // No other notification can occur in the interim, since
+ // we hold the heavy lock, and notifications are made
+ // without acquiring it.
+ }
+ else /* We should hold the heavyweight lock. */
+ {
+ hl = find_heavy(addr, he);
+ release_set(&(he -> address), address);
+ if (0 == hl)
+ {
+# ifdef LOCK_DEBUG
+ fprintf(stderr, "Couldn't find heavy lock in wait "
+ "addr = 0x%lx pid = %d\n", addr, getpid());
+ print_he(he);
+ for(;;) {}
+# endif
+ throw new IllegalMonitorStateException (JvNewStringLatin1
+ ("current thread not owner"));
+ }
+ JvAssert(address & HEAVY);
+ }
+ LOG(WAIT_START, addr, self);
+ switch (_Jv_CondWait (&(hl->si.condition), &(hl->si.mutex), timeout, nanos))
+ {
+ case _JV_NOT_OWNER:
+ throw new IllegalMonitorStateException (JvNewStringLatin1
+ ("current thread not owner"));
+ case _JV_INTERRUPTED:
+ if (Thread::interrupted ())
+ throw new InterruptedException;
+ }
+ LOG(WAIT_END, addr, self);
+}
+
+void
+java::lang::Object::notify (void)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+ obj_addr_t addr = (obj_addr_t)this & ~((obj_addr_t)FLAGS);
+#else
+ obj_addr_t addr = (obj_addr_t)this;
+#endif
+ _Jv_ThreadId_t self = _Jv_ThreadSelf();
+ unsigned hash = JV_SYNC_HASH(addr);
+ hash_entry * he = light_locks + hash;
+ heavy_lock *hl;
+ obj_addr_t address;
+ int result;
+
+retry:
+ address = ((he -> address) & ~LOCKED);
+ if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+ {
+ wait_unlocked(he);
+ goto retry;
+ }
+ if ((address & ~FLAGS) == addr && he -> light_thr_id == self)
+ {
+ // We hold lightweight lock. Since it has not
+ // been inflated, there are no waiters.
+ release_set(&(he -> address), address); // unlock
+ return;
+ }
+ hl = find_heavy(addr, he);
+ // Hl can't disappear since we point to the underlying object.
+ // It's important that we release the lock bit before the notify, since
+ // otherwise we will try to wake up the target while we still hold the
+ // bit. This results in lock bit contention, which we don't handle
+ // terribly well.
+ release_set(&(he -> address), address); // unlock
+ if (0 == hl)
+ {
+ throw new IllegalMonitorStateException(JvNewStringLatin1
+ ("current thread not owner"));
+ return;
+ }
+ // We know that we hold the heavyweight lock at this point,
+ // and the lightweight lock is not in use.
+ result = _Jv_CondNotify(&(hl->si.condition), &(hl->si.mutex));
+ LOG(NOTIFY, addr, self);
+ keep_live(addr);
+ if (__builtin_expect (result, 0))
+ throw new IllegalMonitorStateException(JvNewStringLatin1
+ ("current thread not owner"));
+}
+
+void
+java::lang::Object::notifyAll (void)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+ obj_addr_t addr = (obj_addr_t)this & ~((obj_addr_t)FLAGS);
+#else
+ obj_addr_t addr = (obj_addr_t)this;
+#endif
+ _Jv_ThreadId_t self = _Jv_ThreadSelf();
+ unsigned hash = JV_SYNC_HASH(addr);
+ hash_entry * he = light_locks + hash;
+ heavy_lock *hl;
+ obj_addr_t address;
+ int result;
+
+retry:
+ address = (he -> address) & ~LOCKED;
+ if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+ {
+ wait_unlocked(he);
+ goto retry;
+ }
+ hl = find_heavy(addr, he);
+ if ((address & ~FLAGS) == addr && he -> light_thr_id == self)
+ {
+ // We hold lightweight lock. Since it has not
+ // been inflated, there are no waiters.
+ release_set(&(he -> address), address); // unlock
+ return;
+ }
+ release_set(&(he -> address), address); // unlock
+ if (0 == hl)
+ {
+ throw new IllegalMonitorStateException(JvNewStringLatin1
+ ("current thread not owner"));
+ }
+ result = _Jv_CondNotifyAll(&(hl->si.condition), &(hl->si.mutex));
+ LOG(NOTIFY_ALL, addr, self);
+ if (__builtin_expect (result, 0))
+ throw new IllegalMonitorStateException(JvNewStringLatin1
+ ("current thread not owner"));
+}
+
+// This is declared in Java code and in Object.h.
+// It should never be called with JV_HASH_SYNCHRONIZATION
+void
+java::lang::Object::sync_init (void)
+{
+ throw new IllegalMonitorStateException(JvNewStringLatin1
+ ("internal error: sync_init"));
+}
+
+// This is called on startup and declared in Object.h.
+// For now we just make it a no-op.
+void
+_Jv_InitializeSyncMutex (void)
+{
+}
+
+#endif /* JV_HASH_SYNCHRONIZATION */
+
diff --git a/libjava/java/lang/natPosixProcess.cc b/libjava/java/lang/natPosixProcess.cc
new file mode 100644
index 000000000..fbd3f6a0a
--- /dev/null
+++ b/libjava/java/lang/natPosixProcess.cc
@@ -0,0 +1,515 @@
+// natPosixProcess.cc - Native side of POSIX process code.
+
+/* Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#include <signal.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include <posix.h>
+#include <posix-threads.h>
+#include <jvm.h>
+
+#include <java/lang/PosixProcess$ProcessManager.h>
+#include <java/lang/PosixProcess.h>
+#include <java/lang/IllegalThreadStateException.h>
+#include <java/lang/InternalError.h>
+#include <java/lang/InterruptedException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Thread.h>
+#include <java/io/File.h>
+#include <java/io/FileDescriptor.h>
+#include <gnu/java/nio/channels/FileChannelImpl.h>
+#include <java/io/FileInputStream.h>
+#include <java/io/FileOutputStream.h>
+#include <java/io/IOException.h>
+#include <java/lang/OutOfMemoryError.h>
+#include <java/lang/PosixProcess$EOFInputStream.h>
+
+using gnu::java::nio::channels::FileChannelImpl;
+using namespace java::lang;
+
+extern char **environ;
+
+static char *
+new_string (jstring string)
+{
+ jsize s = _Jv_GetStringUTFLength (string);
+ char *buf = (char *) _Jv_Malloc (s + 1);
+ _Jv_GetStringUTFRegion (string, 0, string->length(), buf);
+ buf[s] = '\0';
+ return buf;
+}
+
+static void
+cleanup (char **args, char **env, char *path)
+{
+ if (args != NULL)
+ {
+ for (int i = 0; args[i] != NULL; ++i)
+ _Jv_Free (args[i]);
+ _Jv_Free (args);
+ }
+ if (env != NULL)
+ {
+ for (int i = 0; env[i] != NULL; ++i)
+ _Jv_Free (env[i]);
+ _Jv_Free (env);
+ }
+ if (path != NULL)
+ _Jv_Free (path);
+}
+
+// This makes our error handling a bit simpler and it lets us avoid
+// thread bugs where we close a possibly-reopened file descriptor for
+// a second time.
+static void
+myclose (int &fd)
+{
+ if (fd != -1)
+ close (fd);
+ fd = -1;
+}
+
+namespace
+{
+ struct ProcessManagerInternal
+ {
+ int pipe_ends[2];
+ struct sigaction old_sigaction;
+ };
+}
+
+
+// There has to be a signal handler in order to be able to
+// sigwait() on SIGCHLD. The information passed is ignored as it
+// will be recovered by the waitpid() call.
+static void
+#ifdef SA_SIGINFO
+sigchld_handler (int sig, siginfo_t *si, void *third)
+#else
+sigchld_handler (int sig)
+#endif
+{
+ if (PosixProcess$ProcessManager::nativeData != NULL)
+ {
+ ProcessManagerInternal *pmi =
+ (ProcessManagerInternal *)PosixProcess$ProcessManager::nativeData;
+ char c = 0;
+ ::write(pmi->pipe_ends[1], &c, 1);
+ if (pmi->old_sigaction.sa_handler != SIG_DFL
+ && pmi->old_sigaction.sa_handler != SIG_IGN)
+ {
+#ifdef SA_SIGINFO
+ if ((pmi->old_sigaction.sa_flags & SA_SIGINFO) != 0)
+ pmi->old_sigaction.sa_sigaction(sig, si, third);
+ else
+#endif
+ (*pmi->old_sigaction.sa_handler)(sig);
+ }
+ }
+}
+
+
+// Get ready to enter the main reaper thread loop.
+void
+java::lang::PosixProcess$ProcessManager::init ()
+{
+ // The nativeData is static to avoid races installing the signal
+ // handler in the case that it is chained.
+ if (nativeData == NULL )
+ {
+ ProcessManagerInternal *pmi =
+ (ProcessManagerInternal *)JvAllocBytes(sizeof(ProcessManagerInternal));
+
+ if (0 != ::pipe(pmi->pipe_ends))
+ goto error;
+
+ // Make writing non-blocking so that the signal handler will
+ // never block.
+ int fl = ::fcntl(pmi->pipe_ends[1], F_GETFL);
+ ::fcntl(pmi->pipe_ends[1], F_SETFL, fl | O_NONBLOCK);
+
+ nativeData = (::gnu::gcj::RawDataManaged *)pmi;
+
+ // SIGCHLD is blocked in all threads in posix-threads.cc.
+ // Setup the SIGCHLD handler.
+ struct sigaction sa;
+ memset (&sa, 0, sizeof (sa));
+
+#ifdef SA_SIGINFO
+ sa.sa_sigaction = sigchld_handler;
+ // We only want signals when the things exit.
+ sa.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
+#else
+ sa.sa_handler = sigchld_handler;
+ // We only want signals when the things exit.
+ sa.sa_flags = SA_NOCLDSTOP;
+#endif
+
+ if (-1 == sigaction (SIGCHLD, &sa, &pmi->old_sigaction))
+ goto error;
+ }
+ // All OK.
+ return;
+
+error:
+ throw new InternalError (JvNewStringUTF (strerror (errno)));
+}
+
+void
+java::lang::PosixProcess$ProcessManager::waitForSignal ()
+{
+ // Wait for SIGCHLD
+ _Jv_UnBlockSigchld();
+ ProcessManagerInternal *pmi = (ProcessManagerInternal *)nativeData;
+
+ // Try to read multiple (64) notifications in one go.
+ char c[64];
+ ::read(pmi->pipe_ends[0], c, sizeof (c));
+
+ _Jv_BlockSigchld();
+
+ return;
+}
+
+jboolean java::lang::PosixProcess$ProcessManager::reap (PosixProcess *p)
+{
+ pid_t rv;
+
+ // Try to get the return code from the child process.
+ int status;
+ rv = ::waitpid ((pid_t)p->pid, &status, WNOHANG);
+ if (rv == -1)
+ throw new InternalError (JvNewStringUTF (strerror (errno)));
+
+ if (rv == 0)
+ return false; // No children to wait for.
+
+ JvSynchronize sync (p);
+ p->status = WIFEXITED (status) ? WEXITSTATUS (status) : -1;
+ p->state = PosixProcess::STATE_TERMINATED;
+ p->processTerminationCleanup();
+ p->notifyAll ();
+ return true;
+}
+
+void
+java::lang::PosixProcess$ProcessManager::signalReaper ()
+{
+ ProcessManagerInternal *pmi = (ProcessManagerInternal *)nativeData;
+ char c = 0;
+ ::write(pmi->pipe_ends[1], &c, 1);
+ // Ignore errors. If EPIPE the reaper has already exited.
+}
+
+void
+java::lang::PosixProcess::nativeDestroy ()
+{
+ int c = ::kill ((pid_t) pid, SIGKILL);
+ if (c == 0)
+ return;
+ // kill() failed.
+ throw new InternalError (JvNewStringUTF (strerror (errno)));
+}
+
+void
+java::lang::PosixProcess::nativeSpawn ()
+{
+ using namespace java::io;
+
+ // Initialize all locals here to make cleanup simpler.
+ char **args = NULL;
+ char **env = NULL;
+ char *path = NULL;
+ int inp[2], outp[2], errp[2], msgp[2];
+ inp[0] = -1;
+ inp[1] = -1;
+ outp[0] = -1;
+ outp[1] = -1;
+ errp[0] = -1;
+ errp[1] = -1;
+ msgp[0] = -1;
+ msgp[1] = -1;
+ errorStream = NULL;
+ inputStream = NULL;
+ outputStream = NULL;
+
+ try
+ {
+ // Transform arrays to native form.
+ args = (char **) _Jv_Malloc ((progarray->length + 1) * sizeof (char *));
+
+ // Initialize so we can gracefully recover.
+ jstring *elts = elements (progarray);
+ for (int i = 0; i <= progarray->length; ++i)
+ args[i] = NULL;
+
+ for (int i = 0; i < progarray->length; ++i)
+ args[i] = new_string (elts[i]);
+ args[progarray->length] = NULL;
+
+ if (envp)
+ {
+ bool need_path = true;
+ bool need_ld_library_path = true;
+ int i;
+
+ // Preserve PATH and LD_LIBRARY_PATH unless specified
+ // explicitly. We need three extra slots. Potentially PATH
+ // and LD_LIBRARY_PATH will be added plus the NULL
+ // termination.
+ env = (char **) _Jv_Malloc ((envp->length + 3) * sizeof (char *));
+ elts = elements (envp);
+
+ // Initialize so we can gracefully recover.
+ for (i = 0; i < envp->length + 3; ++i)
+ env[i] = NULL;
+
+ for (i = 0; i < envp->length; ++i)
+ {
+ env[i] = new_string (elts[i]);
+ if (!strncmp (env[i], "PATH=", sizeof("PATH=")))
+ need_path = false;
+ if (!strncmp (env[i], "LD_LIBRARY_PATH=",
+ sizeof("LD_LIBRARY_PATH=")))
+ need_ld_library_path = false;
+ }
+
+ if (need_path)
+ {
+ char *path_val = getenv ("PATH");
+ if (path_val)
+ {
+ env[i] = (char *) _Jv_Malloc (strlen (path_val) +
+ sizeof("PATH=") + 1);
+ strcpy (env[i], "PATH=");
+ strcat (env[i], path_val);
+ i++;
+ }
+ }
+ if (need_ld_library_path)
+ {
+ char *path_val = getenv ("LD_LIBRARY_PATH");
+ if (path_val)
+ {
+ env[i] =
+ (char *) _Jv_Malloc (strlen (path_val) +
+ sizeof("LD_LIBRARY_PATH=") + 1);
+ strcpy (env[i], "LD_LIBRARY_PATH=");
+ strcat (env[i], path_val);
+ i++;
+ }
+ }
+ env[i] = NULL;
+ }
+
+ // We allocate this here because we can't call malloc() after
+ // the fork.
+ if (dir != NULL)
+ path = new_string (dir->getPath ());
+
+ // Create pipes for I/O. MSGP is for communicating exec()
+ // status. If redirecting stderr to stdout, we don't need to
+ // create the ERRP pipe.
+ if (pipe (inp) || pipe (outp) || pipe (msgp)
+ || fcntl (msgp[1], F_SETFD, FD_CLOEXEC))
+ throw new IOException (JvNewStringUTF (strerror (errno)));
+ if (! redirect && pipe (errp))
+ throw new IOException (JvNewStringUTF (strerror (errno)));
+
+ // We create the streams before forking. Otherwise if we had an
+ // error while creating the streams we would have run the child
+ // with no way to communicate with it.
+ if (redirect)
+ errorStream = PosixProcess$EOFInputStream::instance;
+ else
+ errorStream =
+ new FileInputStream (new
+ FileChannelImpl (errp[0],
+ FileChannelImpl::READ));
+ inputStream =
+ new FileInputStream (new
+ FileChannelImpl (inp[0], FileChannelImpl::READ));
+ outputStream =
+ new FileOutputStream (new FileChannelImpl (outp[1],
+ FileChannelImpl::WRITE));
+
+ // We don't use vfork() because that would cause the local
+ // environment to be set by the child.
+
+ // Use temporary for fork result to avoid dirtying an extra page.
+ pid_t pid_tmp;
+ if ((pid_tmp = fork ()) == -1)
+ throw new IOException (JvNewStringUTF (strerror (errno)));
+
+ if (pid_tmp == 0)
+ {
+ // Child process, so remap descriptors, chdir and exec.
+ if (envp)
+ environ = env;
+
+ // We ignore errors from dup2 because they should never occur.
+ dup2 (outp[0], 0);
+ dup2 (inp[1], 1);
+ dup2 (redirect ? inp[1] : errp[1], 2);
+
+ // Use close and not myclose -- we're in the child, and we
+ // aren't worried about the possible race condition.
+ close (inp[0]);
+ close (inp[1]);
+ if (! redirect)
+ {
+ close (errp[0]);
+ close (errp[1]);
+ }
+ close (outp[0]);
+ close (outp[1]);
+ close (msgp[0]);
+
+ // Change directory.
+ if (path != NULL)
+ {
+ if (chdir (path) != 0)
+ {
+ char c = errno;
+ write (msgp[1], &c, 1);
+ _exit (127);
+ }
+ }
+ // Make sure all file descriptors are closed. In
+ // multi-threaded programs, there is a race between when a
+ // descriptor is obtained, when we can set FD_CLOEXEC, and
+ // fork(). If the fork occurs before FD_CLOEXEC is set, the
+ // descriptor would leak to the execed process if we did not
+ // manually close it. So that is what we do. Since we
+ // close all the descriptors, it is redundant to set
+ // FD_CLOEXEC on them elsewhere.
+ int max_fd;
+#ifdef HAVE_GETRLIMIT
+ rlimit rl;
+ int rv = getrlimit(RLIMIT_NOFILE, &rl);
+ if (rv == 0)
+ max_fd = rl.rlim_max - 1;
+ else
+ max_fd = 1024 - 1;
+#else
+ max_fd = 1024 - 1;
+#endif
+ while(max_fd > 2)
+ {
+ if (max_fd != msgp[1])
+ close (max_fd);
+ max_fd--;
+ }
+ // Make sure that SIGCHLD is unblocked for the new process.
+ sigset_t mask;
+ sigemptyset (&mask);
+ sigaddset (&mask, SIGCHLD);
+ sigprocmask (SIG_UNBLOCK, &mask, NULL);
+
+ execvp (args[0], args);
+
+ // Send the parent notification that the exec failed.
+ char c = errno;
+ write (msgp[1], &c, 1);
+ _exit (127);
+ }
+
+ // Parent. Close extra file descriptors and mark ours as
+ // close-on-exec.
+ pid = (jlong) pid_tmp;
+
+ myclose (outp[0]);
+ myclose (inp[1]);
+ if (! redirect)
+ myclose (errp[1]);
+ myclose (msgp[1]);
+
+ char c;
+ int r = read (msgp[0], &c, 1);
+ if (r == -1)
+ throw new IOException (JvNewStringUTF (strerror (errno)));
+ else if (r != 0)
+ throw new IOException (JvNewStringUTF (strerror (c)));
+ }
+ catch (java::lang::Throwable *thrown)
+ {
+ // Do some cleanup we only do on failure. If a stream object
+ // has been created, we must close the stream itself (to avoid
+ // duplicate closes when the stream object is collected).
+ // Otherwise we simply close the underlying file descriptor.
+ // We ignore errors here as they are uninteresting.
+
+ try
+ {
+ if (inputStream != NULL)
+ inputStream->close ();
+ else
+ myclose (inp[0]);
+ }
+ catch (java::lang::Throwable *ignore)
+ {
+ }
+
+ try
+ {
+ if (outputStream != NULL)
+ outputStream->close ();
+ else
+ myclose (outp[1]);
+ }
+ catch (java::lang::Throwable *ignore)
+ {
+ }
+
+ try
+ {
+ if (errorStream != NULL)
+ errorStream->close ();
+ else if (! redirect)
+ myclose (errp[0]);
+ }
+ catch (java::lang::Throwable *ignore)
+ {
+ }
+
+ // These are potentially duplicate, but it doesn't matter due to
+ // the use of myclose.
+ myclose (outp[0]);
+ myclose (inp[1]);
+ if (! redirect)
+ myclose (errp[1]);
+ myclose (msgp[1]);
+
+ exception = thrown;
+ }
+
+ myclose (msgp[0]);
+ cleanup (args, env, path);
+}
diff --git a/libjava/java/lang/natRuntime.cc b/libjava/java/lang/natRuntime.cc
new file mode 100644
index 000000000..02842b1df
--- /dev/null
+++ b/libjava/java/lang/natRuntime.cc
@@ -0,0 +1,323 @@
+// natRuntime.cc - Implementation of native side of Runtime class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-props.h>
+#include <java-stack.h>
+#include <java/lang/Long.h>
+#include <java/lang/Runtime.h>
+#include <java/lang/UnknownError.h>
+#include <java/lang/UnsatisfiedLinkError.h>
+#include <gnu/gcj/runtime/FinalizerThread.h>
+#include <java/io/File.h>
+#include <java/util/TimeZone.h>
+#include <java/lang/StringBuffer.h>
+#include <java/lang/Process.h>
+#include <java/lang/ClassLoader.h>
+
+// It is convenient and safe to simply include all of these.
+#include <java/lang/Win32Process.h>
+#include <java/lang/EcosProcess.h>
+#include <java/lang/PosixProcess.h>
+
+#include <jni.h>
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#include <errno.h>
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+
+
+
+#ifdef USE_LTDL
+#include <ltdl.h>
+
+/* FIXME: we don't always need this. The next libtool will let us use
+ AC_LTDL_PREOPEN to see if we do. */
+extern const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } };
+
+struct lookup_data
+{
+ const char *symname;
+ void *result;
+};
+
+static int
+find_symbol (lt_dlhandle handle, lt_ptr data)
+{
+ lookup_data *ld = (lookup_data *) data;
+ ld->result = lt_dlsym (handle, ld->symname);
+ return ld->result != NULL;
+}
+
+void *
+_Jv_FindSymbolInExecutable (const char *symname)
+{
+ lookup_data data;
+ data.symname = symname;
+ data.result = NULL;
+ lt_dlforeach (find_symbol, (lt_ptr) &data);
+ return data.result;
+}
+
+#else
+
+void *
+_Jv_FindSymbolInExecutable (const char *)
+{
+ return NULL;
+}
+
+#endif /* USE_LTDL */
+
+
+
+void
+java::lang::Runtime::runFinalizationForExit ()
+{
+ if (finalizeOnExit)
+ _Jv_RunAllFinalizers ();
+}
+
+void
+java::lang::Runtime::exitInternal (jint status)
+{
+ // Make status right for Unix. This is perhaps strange.
+ if (status < 0 || status > 255)
+ status = 255;
+
+ ::exit (status);
+}
+
+jlong
+java::lang::Runtime::freeMemory (void)
+{
+ return _Jv_GCFreeMemory ();
+}
+
+void
+java::lang::Runtime::gc (void)
+{
+ _Jv_RunGC ();
+}
+
+#ifdef USE_LTDL
+// List of names for JNI_OnLoad.
+static const char *onload_names[] = _Jv_platform_onload_names;
+#endif
+
+void
+java::lang::Runtime::_load (jstring path, jboolean do_search)
+{
+ JvSynchronize sync (this);
+ using namespace java::lang;
+#ifdef USE_LTDL
+ jint len = _Jv_GetStringUTFLength (path);
+ char buf[len + 1 + strlen (_Jv_platform_solib_prefix)
+ + strlen (_Jv_platform_solib_suffix)];
+ int offset = 0;
+ if (do_search)
+ {
+ strcpy (buf, _Jv_platform_solib_prefix);
+ offset = strlen (_Jv_platform_solib_prefix);
+ }
+ jsize total = JvGetStringUTFRegion (path, 0, path->length(), &buf[offset]);
+ buf[offset + total] = '\0';
+
+ char *lib_name = buf;
+
+ if (do_search)
+ {
+ ClassLoader *look = _Jv_StackTrace::GetFirstNonSystemClassLoader ();
+
+ if (look != NULL)
+ {
+ // Don't include solib prefix in string passed to
+ // findLibrary.
+ jstring name = look->findLibrary(JvNewStringUTF(&buf[offset]));
+ if (name != NULL)
+ {
+ len = _Jv_GetStringUTFLength (name);
+ lib_name = (char *) _Jv_AllocBytes(len + 1);
+ total = JvGetStringUTFRegion (name, 0,
+ name->length(), lib_name);
+ lib_name[total] = '\0';
+ // Don't append suffixes any more; we have the full file
+ // name.
+ do_search = false;
+ }
+ }
+ }
+
+ lt_dlhandle h;
+ // FIXME: make sure path is absolute.
+ {
+ // Synchronize on java.lang.Class. This is to protect the class chain from
+ // concurrent modification by class registration calls which may be run
+ // during the dlopen().
+ JvSynchronize sync (&java::lang::Class::class$);
+ h = do_search ? lt_dlopenext (lib_name) : lt_dlopen (lib_name);
+ }
+ if (h == NULL)
+ {
+ const char *msg = lt_dlerror ();
+ jstring str = JvNewStringLatin1 (lib_name);
+ str = str->concat (JvNewStringLatin1 (": "));
+ str = str->concat (JvNewStringLatin1 (msg));
+ throw new UnsatisfiedLinkError (str);
+ }
+
+ // Search for JNI_OnLoad function.
+ void *onload = NULL;
+ const char **name = onload_names;
+ while (*name != NULL)
+ {
+ onload = lt_dlsym (h, *name);
+ if (onload != NULL)
+ break;
+ ++name;
+ }
+
+ if (onload != NULL)
+ {
+ JavaVM *vm = _Jv_GetJavaVM ();
+ if (vm == NULL)
+ {
+ // FIXME: what?
+ return;
+ }
+
+ // Push a new frame so that JNI_OnLoad will get the right class
+ // loader if it calls FindClass.
+ ::java::lang::ClassLoader *loader
+ = _Jv_StackTrace::GetFirstNonSystemClassLoader();
+ JNIEnv *env = _Jv_GetJNIEnvNewFrameWithLoader (loader);
+ jint vers = ((jint (JNICALL *) (JavaVM *, void *)) onload) (vm, NULL);
+ _Jv_JNI_PopSystemFrame (env);
+ if (vers != JNI_VERSION_1_1 && vers != JNI_VERSION_1_2
+ && vers != JNI_VERSION_1_4)
+ {
+ // FIXME: unload the library.
+ throw new UnsatisfiedLinkError (JvNewStringLatin1 ("unrecognized version from JNI_OnLoad"));
+ }
+ }
+#else
+ throw new UnknownError
+ (JvNewStringLatin1 (do_search
+ ? "Runtime.loadLibrary not implemented"
+ : "Runtime.load not implemented"));
+#endif /* USE_LTDL */
+}
+
+jboolean
+java::lang::Runtime::loadLibraryInternal (jstring lib)
+{
+ JvSynchronize sync (this);
+ using namespace java::lang;
+#ifdef USE_LTDL
+ jint len = _Jv_GetStringUTFLength (lib);
+ char buf[len + 1];
+ jsize total = JvGetStringUTFRegion (lib, 0, lib->length(), buf);
+ buf[total] = '\0';
+ // FIXME: make sure path is absolute.
+ lt_dlhandle h = lt_dlopenext (buf);
+ return h != NULL;
+#else
+ return false;
+#endif /* USE_LTDL */
+}
+
+void
+java::lang::Runtime::init (void)
+{
+#ifdef USE_LTDL
+ lt_dlinit ();
+ // Set module load path.
+ lt_dlsetsearchpath (_Jv_Module_Load_Path);
+ // Make sure self is opened.
+ lt_dlopen (NULL);
+#endif
+}
+
+void
+java::lang::Runtime::runFinalization (void)
+{
+ gnu::gcj::runtime::FinalizerThread::finalizerReady ();
+}
+
+jlong
+java::lang::Runtime::totalMemory (void)
+{
+ return _Jv_GCTotalMemory ();
+}
+
+jlong
+java::lang::Runtime::maxMemory (void)
+{
+ // We don't have a maximum. FIXME: we might if we ask the GC for
+ // one.
+ return Long::MAX_VALUE;
+}
+
+void
+java::lang::Runtime::traceInstructions (jboolean)
+{
+ // Do nothing.
+}
+
+void
+java::lang::Runtime::traceMethodCalls (jboolean)
+{
+ // Do nothing.
+}
+
+java::lang::Process *
+java::lang::Runtime::execInternal (jstringArray cmd,
+ jstringArray env,
+ java::io::File *dir)
+{
+ return new _Jv_platform_process (cmd, env, dir, false);
+}
+
+jint
+java::lang::Runtime::availableProcessors (void)
+{
+ // FIXME: find the real value.
+ return 1;
+}
+
+jstring
+java::lang::Runtime::nativeGetLibname (jstring pathname, jstring libname)
+{
+ java::lang::StringBuffer *sb = new java::lang::StringBuffer ();
+ sb->append(pathname);
+ if (pathname->length() > 0)
+ sb->append (_Jv_platform_file_separator);
+
+ sb->append (JvNewStringLatin1 (_Jv_platform_solib_prefix));
+ sb->append(libname);
+ sb->append (JvNewStringLatin1 (_Jv_platform_solib_suffix));
+
+ return sb->toString();
+}
diff --git a/libjava/java/lang/natString.cc b/libjava/java/lang/natString.cc
new file mode 100644
index 000000000..75006a7c9
--- /dev/null
+++ b/libjava/java/lang/natString.cc
@@ -0,0 +1,1068 @@
+// natString.cc - Implementation of java.lang.String native methods.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+ 2007, 2008 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <java/lang/Character.h>
+#include <java/lang/CharSequence.h>
+#include <java/lang/String.h>
+#include <java/lang/IndexOutOfBoundsException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/StringIndexOutOfBoundsException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/StringBuffer.h>
+#include <java/io/ByteArrayOutputStream.h>
+#include <java/io/CharConversionException.h>
+#include <java/io/OutputStreamWriter.h>
+#include <java/io/ByteArrayInputStream.h>
+#include <java/io/InputStreamReader.h>
+#include <java/util/Locale.h>
+#include <gnu/gcj/convert/UnicodeToBytes.h>
+#include <gnu/gcj/convert/BytesToUnicode.h>
+#include <gnu/gcj/runtime/StringBuffer.h>
+#include <jvm.h>
+
+static jstring* strhash = NULL;
+static int strhash_count = 0; /* Number of slots used in strhash. */
+static int strhash_size = 0; /* Number of slots available in strhash.
+ * Assumed be power of 2! */
+
+// Some defines used by toUpperCase / toLowerCase.
+#define ESSET 0x00df
+#define CAPITAL_S 0x0053
+#define SMALL_I 0x0069
+#define CAPITAL_I_WITH_DOT 0x0130
+#define SMALL_DOTLESS_I 0x0131
+#define CAPITAL_I 0x0049
+
+#define DELETED_STRING ((jstring)(~0))
+#define SET_STRING_IS_INTERNED(STR) /* nothing */
+
+#define UNMASK_PTR(Ptr) (((unsigned long) (Ptr)) & ~0x01)
+#define MASK_PTR(Ptr) (((unsigned long) (Ptr)) | 0x01)
+#define PTR_MASKED(Ptr) (((unsigned long) (Ptr)) & 0x01)
+
+/* Find a slot where the string with elements DATA, length LEN,
+ and hash HASH should go in the strhash table of interned strings. */
+jstring*
+_Jv_StringFindSlot (jchar* data, jint len, jint hash)
+{
+ JvSynchronize sync (&java::lang::String::class$);
+
+ int start_index = hash & (strhash_size - 1);
+ int deleted_index = -1;
+
+ int index = start_index;
+ /* step must be non-zero, and relatively prime with strhash_size. */
+ jint step = (hash ^ (hash >> 16)) | 1;
+ do
+ {
+ jstring* ptr = &strhash[index];
+ jstring value = (jstring) UNMASK_PTR (*ptr);
+ if (value == NULL)
+ {
+ if (deleted_index >= 0)
+ return (&strhash[deleted_index]);
+ else
+ return ptr;
+ }
+ else if (*ptr == DELETED_STRING)
+ deleted_index = index;
+ else if (value->length() == len
+ && memcmp(JvGetStringChars(value), data, 2*len) == 0)
+ return (ptr);
+ index = (index + step) & (strhash_size - 1);
+ }
+ while (index != start_index);
+ // Note that we can have INDEX == START_INDEX if the table has no
+ // NULL entries but does have DELETED_STRING entries.
+ JvAssert (deleted_index >= 0);
+ return &strhash[deleted_index];
+}
+
+/* Calculate a hash code for the string starting at PTR at given LENGTH.
+ This uses the same formula as specified for java.lang.String.hash. */
+
+static jint
+hashChars (jchar* ptr, jint length)
+{
+ jchar* limit = ptr + length;
+ jint hash = 0;
+ // Updated specification from
+ // http://www.javasoft.com/docs/books/jls/clarify.html.
+ while (ptr < limit)
+ hash = (31 * hash) + *ptr++;
+ return hash;
+}
+
+jint
+java::lang::String::hashCode()
+{
+ if (cachedHashCode == 0)
+ cachedHashCode = hashChars(JvGetStringChars(this), length());
+ return cachedHashCode;
+}
+
+jstring*
+_Jv_StringGetSlot (jstring str)
+{
+ jchar* data = JvGetStringChars(str);
+ int length = str->length();
+ return _Jv_StringFindSlot(data, length, hashChars (data, length));
+}
+
+static void
+rehash ()
+{
+ JvSynchronize sync (&java::lang::String::class$);
+
+ if (strhash == NULL)
+ {
+ strhash_size = 1024;
+ strhash = (jstring *) _Jv_AllocBytes (strhash_size * sizeof (jstring));
+ }
+ else
+ {
+ int i = strhash_size;
+ jstring* ptr = strhash + i;
+ int nsize = strhash_size * 2;
+ jstring *next = (jstring *) _Jv_AllocBytes (nsize * sizeof (jstring));
+
+ while (--i >= 0)
+ {
+ --ptr;
+ if (*ptr == NULL || *ptr == DELETED_STRING)
+ continue;
+
+ /* This is faster equivalent of
+ * *__JvGetInternSlot(*ptr) = *ptr; */
+ jstring val = (jstring) UNMASK_PTR (*ptr);
+ jint hash = val->hashCode();
+ jint index = hash & (nsize - 1);
+ jint step = (hash ^ (hash >> 16)) | 1;
+ for (;;)
+ {
+ if (next[index] == NULL)
+ {
+ next[index] = *ptr;
+ break;
+ }
+ index = (index + step) & (nsize - 1);
+ }
+ }
+
+ strhash_size = nsize;
+ strhash = next;
+ }
+}
+
+jstring
+java::lang::String::intern()
+{
+ JvSynchronize sync (&java::lang::String::class$);
+ if (3 * strhash_count >= 2 * strhash_size)
+ rehash();
+ jstring* ptr = _Jv_StringGetSlot(this);
+ if (*ptr != NULL && *ptr != DELETED_STRING)
+ {
+ // See description in _Jv_FinalizeString() to understand this.
+ *ptr = (jstring) MASK_PTR (*ptr);
+ return (jstring) UNMASK_PTR (*ptr);
+ }
+ jstring str = (this->data == this
+ ? this
+ : _Jv_NewString(JvGetStringChars(this), this->length()));
+ SET_STRING_IS_INTERNED(str);
+ strhash_count++;
+ *ptr = str;
+ // When string is GC'd, clear the slot in the hash table.
+ _Jv_RegisterStringFinalizer (str);
+ return str;
+}
+
+// The fake String finalizer. This is only used when the String has
+// been intern()d. However, we must check this case, as it might be
+// called by the Reference code for any String.
+void
+_Jv_FinalizeString (jobject obj)
+{
+ JvSynchronize sync (&java::lang::String::class$);
+
+ // We might not actually have intern()d any strings at all, if
+ // we're being called from Reference.
+ if (! strhash)
+ return;
+
+ jstring str = reinterpret_cast<jstring> (obj);
+ jstring *ptr = _Jv_StringGetSlot(str);
+ if (*ptr == NULL || *ptr == DELETED_STRING
+ || (jobject) UNMASK_PTR (*ptr) != obj)
+ return;
+
+ // We assume the lowest bit of the pointer is free for our nefarious
+ // manipulations. What we do is set it to `0' (implicitly) when
+ // interning the String. If we subsequently re-intern the same
+ // String, then we set the bit. When finalizing, if the bit is set
+ // then we clear it and re-register the finalizer. We know this is
+ // a safe approach because both intern() and _Jv_FinalizeString()
+ // acquire the class lock; this bit can't be manipulated when the
+ // lock is not held. So if we are finalizing and the bit is clear
+ // then we know all references are gone and we can clear the entry
+ // in the hash table. The naive approach of simply clearing the
+ // pointer here fails in the case where a request to intern a new
+ // string with the same contents is made between the time the
+ // intern()d string is found to be unreachable and when the
+ // finalizer is actually run. In this case we could clear a pointer
+ // to a valid string, and future intern() calls for that particular
+ // value would spuriously fail.
+ if (PTR_MASKED (*ptr))
+ {
+ *ptr = (jstring) UNMASK_PTR (*ptr);
+ _Jv_RegisterStringFinalizer (obj);
+ }
+ else
+ {
+ *ptr = DELETED_STRING;
+ strhash_count--;
+ }
+}
+
+jstring
+_Jv_NewStringUTF (const char *bytes)
+{
+ int size = strlen (bytes);
+ unsigned char *p = (unsigned char *) bytes;
+
+ int length = _Jv_strLengthUtf8 ((char *) p, size);
+ if (length < 0)
+ return NULL;
+
+ jstring jstr = JvAllocString (length);
+ jchar *chrs = JvGetStringChars (jstr);
+
+ p = (unsigned char *) bytes;
+ unsigned char *limit = p + size;
+ while (p < limit)
+ *chrs++ = UTF8_GET (p, limit);
+
+ return jstr;
+}
+
+jstring
+_Jv_NewStringUtf8Const (Utf8Const* str)
+{
+ jchar *chrs;
+ jchar buffer[100];
+ jstring jstr;
+ unsigned char* data = (unsigned char*) str->data;
+ unsigned char* limit = data + str->length;
+ int length = _Jv_strLengthUtf8(str->data, str->length);
+
+ if (length <= (int) (sizeof(buffer) / sizeof(jchar)))
+ {
+ jstr = NULL;
+ chrs = buffer;
+ }
+ else
+ {
+ jstr = JvAllocString(length);
+ chrs = JvGetStringChars(jstr);
+ }
+
+ jint hash = 0;
+ while (data < limit)
+ {
+ jchar ch = UTF8_GET(data, limit);
+ hash = (31 * hash) + ch;
+ *chrs++ = ch;
+ }
+ chrs -= length;
+
+ JvSynchronize sync (&java::lang::String::class$);
+ if (3 * strhash_count >= 2 * strhash_size)
+ rehash();
+ jstring* ptr = _Jv_StringFindSlot (chrs, length, hash);
+ if (*ptr != NULL && *ptr != DELETED_STRING)
+ return (jstring) UNMASK_PTR (*ptr);
+ strhash_count++;
+ if (jstr == NULL)
+ {
+ jstr = JvAllocString(length);
+ chrs = JvGetStringChars(jstr);
+ memcpy (chrs, buffer, sizeof(jchar)*length);
+ }
+ jstr->cachedHashCode = hash;
+ *ptr = jstr;
+ SET_STRING_IS_INTERNED(jstr);
+ // When string is GC'd, clear the slot in the hash table. Note that
+ // we don't have to call _Jv_RegisterStringFinalizer here, as we
+ // know the new object cannot be referred to by a Reference.
+ _Jv_RegisterFinalizer ((void *) jstr, _Jv_FinalizeString);
+ return jstr;
+}
+
+jsize
+_Jv_GetStringUTFLength (jstring string)
+{
+ jsize len = 0;
+ jchar *ptr = JvGetStringChars (string);
+ jsize i = string->length();
+ while (--i >= 0)
+ {
+ jchar ch = *ptr++;
+ if (ch > 0 && ch <= 0x7F)
+ len += 1;
+ else if (ch <= 0x7FF)
+ len += 2;
+ else
+ len += 3;
+ }
+ return len;
+}
+
+// Not sure this quite matches GetStringUTFRegion.
+// null-termination of result? len? throw exception?
+jsize
+_Jv_GetStringUTFRegion (jstring str, jsize start, jsize len, char *buf)
+{
+ jchar *sptr = JvGetStringChars (str) + start;
+ jsize i = len;
+ char *dptr = buf;
+ while (--i >= 0)
+ {
+ jchar ch = *sptr++;
+ if (ch > 0 && ch <= 0x7F)
+ *dptr++ = (char) ch;
+ else if (ch <= 0x7FF)
+ {
+ *dptr++ = (char) (0xC0 + ((ch >> 6) & 0x1F));
+ *dptr++ = (char) (0x80 + (ch & 0x3F));
+ }
+ else
+ {
+ *dptr++ = (char) (0xE0 + ((ch >> 12) & 0xF));
+ *dptr++ = (char) (0x80 + ((ch >> 6) & 0x3F));
+ *dptr++ = (char) (0x80 + (ch & 0x3F));
+ }
+ }
+ return dptr - buf;
+}
+
+/* Put printed (decimal) representation of NUM in a buffer.
+ BUFEND marks the end of the buffer, which must be at least 11 jchars long.
+ Returns the COUNT of jchars written. The result is in
+ (BUFEND - COUNT) (inclusive) upto (BUFEND) (exclusive). */
+
+jint
+_Jv_FormatInt (jchar* bufend, jint num)
+{
+ register jchar* ptr = bufend;
+ jboolean isNeg;
+ if (num < 0)
+ {
+ isNeg = true;
+ if (num != (jint) -2147483648U)
+ num = -(num);
+ else
+ {
+ // Handle special case of MIN_VALUE.
+ *--ptr = '8';
+ num = 214748364;
+ }
+ }
+ else
+ isNeg = false;
+
+ do
+ {
+ *--ptr = (jchar) ((int) '0' + (num % 10));
+ num /= 10;
+ }
+ while (num > 0);
+
+ if (isNeg)
+ *--ptr = '-';
+ return bufend - ptr;
+}
+
+jstring
+java::lang::String::valueOf (jint num)
+{
+ // Use an array large enough for "-2147483648"; i.e. 11 chars.
+ jchar buffer[11];
+ int i = _Jv_FormatInt (buffer+11, num);
+ return _Jv_NewString (buffer+11-i, i);
+}
+
+jstring
+_Jv_NewString(const jchar *chars, jsize len)
+{
+ jstring str = _Jv_AllocString(len);
+ jchar* data = JvGetStringChars (str);
+ memcpy (data, chars, len * sizeof (jchar));
+ return str;
+}
+
+jstring
+_Jv_NewStringLatin1(const char *bytes, jsize len)
+{
+ jstring str = JvAllocString(len);
+ jchar* data = JvGetStringChars (str);
+ while (--len >= 0)
+ *data++ = *(unsigned char*)bytes++;
+ return str;
+}
+
+void
+java::lang::String::init(jcharArray chars, jint offset, jint count,
+ jboolean dont_copy)
+{
+ if (! chars)
+ throw new NullPointerException;
+ jsize data_size = JvGetArrayLength (chars);
+ if (offset < 0 || count < 0 || offset + count < 0
+ || offset + count > data_size)
+ throw new ArrayIndexOutOfBoundsException;
+ jcharArray array;
+ jchar *pdst;
+ if (! dont_copy)
+ {
+ array = JvNewCharArray(count);
+ pdst = elements (array);
+ memcpy (pdst, elements (chars) + offset, count * sizeof (jchar));
+ }
+ else
+ {
+ array = chars;
+ pdst = &(elements(array)[offset]);
+ }
+
+ data = array;
+ boffset = (char *) pdst - (char *) array;
+ this->count = count;
+}
+
+void
+java::lang::String::init(jbyteArray ascii, jint hibyte, jint offset,
+ jint count)
+{
+ if (! ascii)
+ throw new NullPointerException;
+ jsize data_size = JvGetArrayLength (ascii);
+ if (offset < 0 || count < 0 || offset + count < 0
+ || offset + count > data_size)
+ throw new ArrayIndexOutOfBoundsException;
+ jcharArray array = JvNewCharArray(count);
+ jbyte *psrc = elements (ascii) + offset;
+ jchar *pdst = elements (array);
+ data = array;
+ boffset = (char *) pdst - (char *) array;
+ this->count = count;
+ hibyte = (hibyte & 0xff) << 8;
+ while (-- count >= 0)
+ {
+ *pdst++ = hibyte | (*psrc++ & 0xff);
+ }
+}
+
+void
+java::lang::String::init (jbyteArray bytes, jint offset, jint count,
+ jstring encoding)
+{
+ if (! bytes)
+ throw new NullPointerException;
+ jsize data_size = JvGetArrayLength (bytes);
+ if (offset < 0 || count < 0 || offset + count < 0
+ || offset + count > data_size)
+ throw new ArrayIndexOutOfBoundsException;
+ jcharArray array = JvNewCharArray (count);
+ gnu::gcj::convert::BytesToUnicode *converter
+ = gnu::gcj::convert::BytesToUnicode::getDecoder(encoding);
+ jint outpos = 0;
+ int avail = count;
+ converter->setInput(bytes, offset, offset+count);
+ while (converter->inpos < converter->inlength)
+ {
+ int done;
+ try
+ {
+ done = converter->read(array, outpos, avail);
+ }
+ catch (::java::io::CharConversionException *e)
+ {
+ // Ignore it and silently throw away the offending data.
+ break;
+ }
+ if (done == 0)
+ {
+ // done is zero if either there is no space available in the
+ // output *or* the input is incomplete. We assume that if
+ // there are 20 characters available in the output, the
+ // input must be incomplete and there is no more work to do.
+ // This means we may skip several bytes of input, but that
+ // is OK as the behavior is explicitly unspecified in this
+ // case.
+ if (avail - outpos > 20)
+ break;
+
+ jint new_size = 2 * (outpos + avail);
+ jcharArray new_array = JvNewCharArray (new_size);
+ memcpy (elements (new_array), elements (array),
+ outpos * sizeof(jchar));
+ array = new_array;
+ avail = new_size - outpos;
+ }
+ else
+ {
+ outpos += done;
+ avail -= done;
+ }
+ }
+ converter->done ();
+ this->data = array;
+ this->boffset = (char *) elements (array) - (char *) array;
+ this->count = outpos;
+}
+
+void
+java::lang::String::init (gnu::gcj::runtime::StringBuffer *buffer)
+{
+ init (buffer->value, 0, buffer->count, true);
+}
+
+jboolean
+java::lang::String::equals(jobject anObject)
+{
+ if (anObject == NULL)
+ return false;
+ if (anObject == this)
+ return true;
+ if (anObject->getClass() != &java::lang::String::class$)
+ return false;
+ jstring other = (jstring) anObject;
+ if (count != other->count)
+ return false;
+
+ // If both have cached hash codes, check that. If the cached hash
+ // codes are zero, don't bother trying to compute them.
+ int myHash = cachedHashCode;
+ int otherHash = other->cachedHashCode;
+ if (myHash && otherHash && myHash != otherHash)
+ return false;
+
+ // We could see if both are interned, and return false. But that
+ // seems too expensive.
+
+ jchar *xptr = JvGetStringChars (this);
+ jchar *yptr = JvGetStringChars (other);
+ return ! memcmp (xptr, yptr, count * sizeof (jchar));
+}
+
+jboolean
+java::lang::String::contentEquals(java::lang::StringBuffer* buffer)
+{
+ if (buffer == NULL)
+ throw new NullPointerException;
+ JvSynchronize sync(buffer);
+ if (count != buffer->count)
+ return false;
+ if (data == buffer->value)
+ return true; // Possible if shared.
+ jchar *xptr = JvGetStringChars(this);
+ jchar *yptr = elements(buffer->value);
+ return ! memcmp (xptr, yptr, count * sizeof (jchar));
+}
+
+jboolean
+java::lang::String::contentEquals(java::lang::CharSequence *seq)
+{
+ if (seq->length() != count)
+ return false;
+ jchar *value = JvGetStringChars(this);
+ for (int i = 0; i < count; ++i)
+ if (value[i] != seq->charAt(i))
+ return false;
+ return true;
+}
+
+jchar
+java::lang::String::charAt(jint i)
+{
+ if (i < 0 || i >= count)
+ throw new java::lang::StringIndexOutOfBoundsException(i);
+ return JvGetStringChars(this)[i];
+}
+
+void
+java::lang::String::getChars(jint srcBegin, jint srcEnd,
+ jcharArray dst, jint dstBegin)
+{
+ jint dst_length = JvGetArrayLength (dst);
+ if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count)
+ throw new java::lang::StringIndexOutOfBoundsException;
+ // The 2nd part of the test below is equivalent to
+ // dstBegin + (srcEnd-srcBegin) > dst_length
+ // except that it does not overflow.
+ if (dstBegin < 0 || dstBegin > dst_length - (srcEnd-srcBegin))
+ throw new ArrayIndexOutOfBoundsException;
+ jchar *dPtr = elements (dst) + dstBegin;
+ jchar *sPtr = JvGetStringChars (this) + srcBegin;
+ jint i = srcEnd - srcBegin;
+ memcpy (dPtr, sPtr, i * sizeof (jchar));
+}
+
+jbyteArray
+java::lang::String::getBytes (jstring enc)
+{
+ jint todo = length();
+ jint buflen = todo;
+ jbyteArray buffer = JvNewByteArray(todo);
+ jint bufpos = 0;
+ jint offset = 0;
+ gnu::gcj::convert::UnicodeToBytes *converter
+ = gnu::gcj::convert::UnicodeToBytes::getEncoder(enc);
+ while (todo > 0 || converter->havePendingBytes())
+ {
+ converter->setOutput(buffer, bufpos);
+ int converted = converter->write(this, offset, todo, NULL);
+ bufpos = converter->count;
+ if (converted == 0)
+ {
+ buflen *= 2;
+ jbyteArray newbuffer = JvNewByteArray(buflen);
+ memcpy (elements (newbuffer), elements (buffer), bufpos);
+ buffer = newbuffer;
+ }
+ else
+ {
+ offset += converted;
+ todo -= converted;
+ }
+ }
+ if (length() > 0)
+ {
+ converter->setFinished();
+ converter->write(this, 0, 0, NULL);
+ }
+ converter->done ();
+ if (bufpos == buflen)
+ return buffer;
+ jbyteArray result = JvNewByteArray(bufpos);
+ memcpy (elements (result), elements (buffer), bufpos);
+ return result;
+}
+
+void
+java::lang::String::getBytes(jint srcBegin, jint srcEnd,
+ jbyteArray dst, jint dstBegin)
+{
+ jint dst_length = JvGetArrayLength (dst);
+ if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count)
+ throw new java::lang::StringIndexOutOfBoundsException;
+ // The 2nd part of the test below is equivalent to
+ // dstBegin + (srcEnd-srcBegin) > dst_length
+ // except that it does not overflow.
+ if (dstBegin < 0 || dstBegin > dst_length - (srcEnd-srcBegin))
+ throw new ArrayIndexOutOfBoundsException;
+ jbyte *dPtr = elements (dst) + dstBegin;
+ jchar *sPtr = JvGetStringChars (this) + srcBegin;
+ jint i = srcEnd-srcBegin;
+ while (--i >= 0)
+ *dPtr++ = (jbyte) *sPtr++;
+}
+
+jcharArray
+java::lang::String::toCharArray()
+{
+ jcharArray array = JvNewCharArray(count);
+ jchar *dPtr = elements (array);
+ jchar *sPtr = JvGetStringChars (this);
+ jint i = count;
+ memcpy (dPtr, sPtr, i * sizeof (jchar));
+ return array;
+}
+
+jboolean
+java::lang::String::equalsIgnoreCase (jstring anotherString)
+{
+ if (anotherString == NULL || count != anotherString->count)
+ return false;
+ jchar *tptr = JvGetStringChars (this);
+ jchar *optr = JvGetStringChars (anotherString);
+ jint i = count;
+ while (--i >= 0)
+ {
+ jchar tch = *tptr++;
+ jchar och = *optr++;
+ if (tch != och
+ && (java::lang::Character::toLowerCase (tch)
+ != java::lang::Character::toLowerCase (och))
+ && (java::lang::Character::toUpperCase (tch)
+ != java::lang::Character::toUpperCase (och)))
+ return false;
+ }
+ return true;
+}
+
+jboolean
+java::lang::String::regionMatches (jint toffset,
+ jstring other, jint ooffset, jint len)
+{
+ if (toffset < 0 || ooffset < 0 || len < 0
+ || toffset > count - len
+ || ooffset > other->count - len)
+ return false;
+ jchar *tptr = JvGetStringChars (this) + toffset;
+ jchar *optr = JvGetStringChars (other) + ooffset;
+ jint i = len;
+ return ! memcmp (tptr, optr, i * sizeof (jchar));
+}
+
+jint
+java::lang::String::nativeCompareTo (jstring anotherString)
+{
+ jchar *tptr = JvGetStringChars (this);
+ jchar *optr = JvGetStringChars (anotherString);
+ jint tlen = this->count;
+ jint olen = anotherString->count;
+ jint i = tlen > olen ? olen : tlen;
+ while (--i >= 0)
+ {
+ jchar tch = *tptr++;
+ jchar och = *optr++;
+ if (tch != och)
+ return (jint) tch - (jint) och;
+ }
+ return tlen - olen;
+}
+
+jboolean
+java::lang::String::regionMatches (jboolean ignoreCase, jint toffset,
+ jstring other, jint ooffset, jint len)
+{
+ if (toffset < 0 || ooffset < 0 || len < 0
+ || toffset > count - len
+ || ooffset > other->count - len)
+ return false;
+ jchar *tptr = JvGetStringChars (this) + toffset;
+ jchar *optr = JvGetStringChars (other) + ooffset;
+ jint i = len;
+ if (ignoreCase)
+ {
+ while (--i >= 0)
+ {
+ jchar tch = *tptr++;
+ jchar och = *optr++;
+ if ((java::lang::Character::toLowerCase (tch)
+ != java::lang::Character::toLowerCase (och))
+ && (java::lang::Character::toUpperCase (tch)
+ != java::lang::Character::toUpperCase (och)))
+ return false;
+ }
+ return true;
+ }
+ return ! memcmp (tptr, optr, i * sizeof (jchar));
+}
+
+jboolean
+java::lang::String::startsWith (jstring prefix, jint toffset)
+{
+ jint i = prefix->count;
+ if (toffset < 0 || toffset > count - i)
+ return false;
+ jchar *xptr = JvGetStringChars (this) + toffset;
+ jchar *yptr = JvGetStringChars (prefix);
+ return ! memcmp (xptr, yptr, i * sizeof (jchar));
+}
+
+jint
+java::lang::String::indexOf (jint ch, jint fromIndex)
+{
+ if (fromIndex < 0)
+ fromIndex = 0;
+ jchar *ptr = JvGetStringChars(this);
+ for (;; ++fromIndex)
+ {
+ if (fromIndex >= count)
+ return -1;
+ if (ptr[fromIndex] == ch)
+ return fromIndex;
+ }
+}
+
+jint
+java::lang::String::indexOf (jstring s, jint fromIndex)
+{
+ const jchar *const xchars = JvGetStringChars(s);
+ const jchar *const ychars = JvGetStringChars(this) + fromIndex;
+
+ const int xlength = s->length ();
+ const int ylength = length () - fromIndex;
+
+ int i = 0;
+ int j = 0;
+
+ while (i < ylength && j < xlength)
+ {
+ if (xchars[j] != ychars[i])
+ {
+ i = i - j + 1;
+ j = 0;
+ }
+ else
+ i++, j++;
+ }
+
+ if (j >= xlength)
+ return fromIndex + i - xlength;
+ else
+ return -1;
+}
+
+jint
+java::lang::String::lastIndexOf (jint ch, jint fromIndex)
+{
+ if (fromIndex >= count)
+ fromIndex = count - 1;
+ jchar *ptr = JvGetStringChars(this);
+ for (;; --fromIndex)
+ {
+ if (fromIndex < 0)
+ return -1;
+ if (ptr[fromIndex] == ch)
+ return fromIndex;
+ }
+}
+
+jstring
+java::lang::String::substring (jint beginIndex, jint endIndex)
+{
+ if (beginIndex < 0 || endIndex > count || beginIndex > endIndex)
+ throw new StringIndexOutOfBoundsException;
+ if (beginIndex == 0 && endIndex == count)
+ return this;
+ jint newCount = endIndex - beginIndex;
+ // For very small strings, just allocate a new one. For other
+ // substrings, allocate a new one unless the substring is over half
+ // of the original string.
+ if (newCount <= 8 || newCount < (count >> 1))
+ return JvNewString(JvGetStringChars(this) + beginIndex, newCount);
+ jstring s = new String();
+ s->data = data;
+ s->count = newCount;
+ s->boffset = boffset + sizeof(jchar) * beginIndex;
+ return s;
+}
+
+jstring
+java::lang::String::concat(jstring str)
+{
+ jint str_count = str->count;
+ if (str_count == 0)
+ return this;
+ jstring result = JvAllocString(count + str_count);
+ jchar *dstPtr = JvGetStringChars(result);
+ jchar *srcPtr = JvGetStringChars(this);
+ jint i = count;
+ memcpy (dstPtr, srcPtr, i * sizeof (jchar));
+ dstPtr += i;
+ srcPtr = JvGetStringChars(str);
+ i = str->count;
+ memcpy (dstPtr, srcPtr, i * sizeof (jchar));
+ return result;
+}
+
+jstring
+java::lang::String::replace (jchar oldChar, jchar newChar)
+{
+ jint i;
+ jchar* chrs = JvGetStringChars (this);
+ for (i = 0; ; i++)
+ {
+ if (i == count)
+ return this;
+ if (chrs[i] == oldChar)
+ break;
+ }
+ jstring result = JvAllocString (count);
+ jchar *dPtr = JvGetStringChars (result);
+ for (int j = 0; j < i; j++)
+ *dPtr++ = chrs[j];
+ for (; i < count; i++)
+ {
+ jchar ch = chrs[i];
+ if (ch == oldChar)
+ ch = newChar;
+ *dPtr++ = ch;
+ }
+ return result;
+}
+
+jstring
+java::lang::String::toLowerCase (java::util::Locale *locale)
+{
+ jint i;
+ jchar* chrs = JvGetStringChars(this);
+ jchar ch = 0;
+
+ bool handle_tr = false;
+ if (locale != NULL)
+ {
+ String *lang = locale->getLanguage ();
+ if (lang->length () == 2
+ && lang->charAt (0) == 't'
+ && lang->charAt (1) == 'r')
+ handle_tr = true;
+ }
+
+ for (i = 0; ; i++)
+ {
+ if (i == count)
+ return this;
+ jchar origChar = chrs[i];
+
+ if (handle_tr && (origChar == CAPITAL_I
+ || origChar == CAPITAL_I_WITH_DOT))
+ break;
+
+ ch = java::lang::Character::toLowerCase(origChar);
+ if (ch != origChar)
+ break;
+ }
+ jstring result = JvAllocString(count);
+ jchar *dPtr = JvGetStringChars (result);
+ for (int j = 0; j < i; j++)
+ *dPtr++ = chrs[j];
+ *dPtr++ = ch; i++;
+ for (; i < count; i++)
+ {
+ if (handle_tr && chrs[i] == CAPITAL_I)
+ *dPtr++ = SMALL_DOTLESS_I;
+ else if (handle_tr && chrs[i] == CAPITAL_I_WITH_DOT)
+ *dPtr++ = SMALL_I;
+ else
+ *dPtr++ = java::lang::Character::toLowerCase(chrs[i]);
+ }
+ return result;
+}
+
+jstring
+java::lang::String::toUpperCase (java::util::Locale *locale)
+{
+ jint i;
+ jchar* chrs = JvGetStringChars(this);
+ jchar ch;
+
+ // When handling a specific locale there might be special rules.
+ // Currently all existing rules are simply handled inline, as there
+ // are only two and they are documented in the online 1.2 docs.
+ bool handle_esset = locale != NULL;
+ bool handle_tr = false;
+ if (locale != NULL)
+ {
+ String *lang = locale->getLanguage ();
+ if (lang->length () == 2
+ && lang->charAt (0) == 't'
+ && lang->charAt (1) == 'r')
+ handle_tr = true;
+ }
+
+ int new_count = count;
+ bool new_string = false;
+ for (i = 0; ; i++)
+ {
+ if (i == count)
+ break;
+ jchar origChar = chrs[i];
+
+ if (handle_esset && origChar == ESSET)
+ {
+ ++new_count;
+ new_string = true;
+ }
+ else if (handle_tr && (origChar == SMALL_I
+ || origChar == SMALL_DOTLESS_I))
+ new_string = true;
+ else
+ {
+ ch = java::lang::Character::toUpperCase(origChar);
+ if (ch != origChar)
+ new_string = true;
+ }
+
+ if (new_string && ! handle_esset)
+ break;
+ }
+ if (! new_string)
+ return this;
+ jstring result = JvAllocString(new_count);
+ jchar *dPtr = JvGetStringChars (result);
+ for (i = 0; i < count; i++)
+ {
+ if (handle_esset && chrs[i] == ESSET)
+ {
+ *dPtr++ = CAPITAL_S;
+ *dPtr++ = CAPITAL_S;
+ }
+ else if (handle_tr && chrs[i] == SMALL_I)
+ *dPtr++ = CAPITAL_I_WITH_DOT;
+ else if (handle_tr && chrs[i] == SMALL_DOTLESS_I)
+ *dPtr++ = CAPITAL_I;
+ else
+ *dPtr++ = java::lang::Character::toUpperCase(chrs[i]);
+ }
+ return result;
+}
+
+jstring
+java::lang::String::trim ()
+{
+ jchar* chrs = JvGetStringChars(this);
+ if (count == 0 || (chrs[0] > ' ' && chrs[count-1] > ' '))
+ return this;
+ jint preTrim = 0;
+ for (;; preTrim++)
+ {
+ if (preTrim == count)
+ return new String();
+ if (chrs[preTrim] > ' ')
+ break;
+ }
+ jint endTrim = count;
+ while (chrs[endTrim-1] <= ' ')
+ endTrim--;
+ return substring(preTrim, endTrim);
+}
+
+jstring
+java::lang::String::valueOf(jcharArray data, jint offset, jint count)
+{
+ jint data_length = JvGetArrayLength (data);
+ if (offset < 0 || count < 0 || offset > data_length - count)
+ throw new ArrayIndexOutOfBoundsException;
+ jstring result = JvAllocString(count);
+ jchar *sPtr = elements (data) + offset;
+ jchar *dPtr = JvGetStringChars(result);
+ memcpy (dPtr, sPtr, count * sizeof (jchar));
+ return result;
+}
+
+jstring
+java::lang::String::valueOf(jchar c)
+{
+ jstring result = JvAllocString(1);
+ JvGetStringChars (result)[0] = c;
+ return result;
+}
diff --git a/libjava/java/lang/natSystem.cc b/libjava/java/lang/natSystem.cc
new file mode 100644
index 000000000..42a13258d
--- /dev/null
+++ b/libjava/java/lang/natSystem.cc
@@ -0,0 +1,150 @@
+// natSystem.cc - Native code implementing System class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/lang/System.h>
+#include <java/lang/Class.h>
+#include <java/lang/ArrayStoreException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/io/PrintStream.h>
+#include <java/io/InputStream.h>
+
+
+
+void
+java::lang::System::setErr0 (java::io::PrintStream *newErr)
+{
+ err = newErr;
+}
+
+void
+java::lang::System::setIn0 (java::io::InputStream *newIn)
+{
+ in = newIn;
+}
+
+void
+java::lang::System::setOut0 (java::io::PrintStream *newOut)
+{
+ out = newOut;
+}
+
+void
+java::lang::System::arraycopy (jobject src, jint src_offset,
+ jobject dst, jint dst_offset,
+ jint count)
+{
+ if (! src || ! dst)
+ throw new NullPointerException;
+
+ jclass src_c = src->getClass();
+ jclass dst_c = dst->getClass();
+ jclass src_comp = src_c->getComponentType();
+ jclass dst_comp = dst_c->getComponentType();
+
+ if (! src_c->isArray() || ! dst_c->isArray()
+ || src_comp->isPrimitive() != dst_comp->isPrimitive()
+ || (src_comp->isPrimitive() && src_comp != dst_comp))
+ throw new ArrayStoreException;
+
+ __JArray *src_a = (__JArray *) src;
+ __JArray *dst_a = (__JArray *) dst;
+ if (src_offset < 0 || dst_offset < 0 || count < 0
+ || (unsigned jint) src_offset > (unsigned jint) src_a->length
+ || (unsigned jint) (src_offset + count) > (unsigned jint) src_a->length
+ || (unsigned jint) dst_offset > (unsigned jint) dst_a->length
+ || (unsigned jint) (dst_offset + count) > (unsigned jint) dst_a->length)
+ throw new ArrayIndexOutOfBoundsException;
+
+ // Do-nothing cases.
+ if ((src == dst && src_offset == dst_offset)
+ || ! count)
+ return;
+
+ // If both are primitive, we can optimize trivially. If DST
+ // components are always assignable from SRC components, then we
+ // will never need to raise an error, and thus can do the
+ // optimization. If source and destinations are the same, then we
+ // know that the assignability premise always holds.
+ const bool prim = src_comp->isPrimitive();
+ if (prim || dst_comp->isAssignableFrom(src_comp) || src == dst)
+ {
+ const size_t size = (prim ? src_comp->size()
+ : sizeof elements((jobjectArray)src)[0]);
+
+ char *src_elts = _Jv_GetArrayElementFromElementType (src, src_comp);
+ src_elts += size * src_offset;
+
+ char *dst_elts = _Jv_GetArrayElementFromElementType (dst, dst_comp);
+ dst_elts += size * dst_offset;
+
+#if HAVE_MEMMOVE
+ // We don't bother trying memcpy. It can't be worth the cost of
+ // the check.
+ // Don't cast to (void*), as memmove may expect (char*)
+ memmove (dst_elts, src_elts, count * size);
+#else
+ bcopy (src_elts, dst_elts, count * size);
+#endif
+ }
+ else
+ {
+ jobject *src_elts = elements ((jobjectArray) src_a) + src_offset;
+ jobject *dst_elts = elements ((jobjectArray) dst_a) + dst_offset;
+
+ for (int i = 0; i < count; ++i)
+ {
+ if (*src_elts
+ && ! dst_comp->isAssignableFrom((*src_elts)->getClass()))
+ throw new ArrayStoreException;
+ *dst_elts++ = *src_elts++;
+ }
+ }
+}
+
+jlong
+java::lang::System::currentTimeMillis (void)
+{
+ return _Jv_platform_gettimeofday ();
+}
+
+jlong
+java::lang::System::nanoTime ()
+{
+ return _Jv_platform_nanotime ();
+}
+
+jint
+java::lang::System::identityHashCode (jobject obj)
+{
+ return _Jv_HashCode (obj);
+}
+
+jstring
+java::lang::System::getenv0 (jstring name)
+{
+ jint len = _Jv_GetStringUTFLength (name);
+ char buf[len + 1];
+ jsize total = JvGetStringUTFRegion (name, 0, name->length(), buf);
+ buf[total] = '\0';
+ const char *value = ::getenv (buf);
+ if (value == NULL)
+ return NULL;
+ return JvNewStringUTF (value);
+}
diff --git a/libjava/java/lang/natThread.cc b/libjava/java/lang/natThread.cc
new file mode 100644
index 000000000..d6abff13f
--- /dev/null
+++ b/libjava/java/lang/natThread.cc
@@ -0,0 +1,534 @@
+// natThread.cc - Native part of Thread class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2006, 2007 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-threads.h>
+
+#include <gnu/gcj/RawDataManaged.h>
+#include <java/lang/Thread.h>
+#include <java/lang/Thread$State.h>
+#include <java/lang/Thread$UncaughtExceptionHandler.h>
+#include <java/lang/ThreadGroup.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IllegalThreadStateException.h>
+#include <java/lang/InterruptedException.h>
+#include <java/lang/NullPointerException.h>
+
+#include <jni.h>
+
+#ifdef INTERPRETER
+#include <jvmti.h>
+#include "jvmti-int.h"
+#endif
+
+#ifdef ENABLE_JVMPI
+#include <jvmpi.h>
+#endif
+
+
+
+static void finalize_native (jobject ptr);
+
+// This is called from the constructor to initialize the native side
+// of the Thread.
+void
+java::lang::Thread::initialize_native (void)
+{
+ natThread *nt = (natThread *) _Jv_AllocBytes (sizeof (natThread));
+
+ state = JV_NEW;
+ nt->alive_flag = THREAD_DEAD;
+
+ data = (gnu::gcj::RawDataManaged *) nt;
+
+ // Register a finalizer to clean up the native thread resources.
+ _Jv_RegisterFinalizer (data, finalize_native);
+
+ _Jv_MutexInit (&nt->join_mutex);
+ _Jv_CondInit (&nt->join_cond);
+
+ nt->park_helper.init();
+
+ nt->thread = _Jv_ThreadInitData (this);
+ // FIXME: if JNI_ENV is set we will want to free it. It is
+ // malloc()d.
+ nt->jni_env = NULL;
+}
+
+static void
+finalize_native (jobject ptr)
+{
+ natThread *nt = (natThread *) ptr;
+ _Jv_ThreadDestroyData (nt->thread);
+#ifdef _Jv_HaveCondDestroy
+ _Jv_CondDestroy (&nt->join_cond);
+#endif
+#ifdef _Jv_HaveMutexDestroy
+ _Jv_MutexDestroy (&nt->join_mutex);
+#endif
+ _Jv_FreeJNIEnv((JNIEnv*)nt->jni_env);
+
+ nt->park_helper.destroy();
+}
+
+jint
+java::lang::Thread::countStackFrames (void)
+{
+ // NOTE: This is deprecated in JDK 1.2.
+
+ // Old applets still call this method. Rather than throwing
+ // UnsupportedOperationException we simply fail silently.
+
+ return 0;
+}
+
+java::lang::Thread *
+java::lang::Thread::currentThread (void)
+{
+ return _Jv_ThreadCurrent ();
+}
+
+jboolean
+java::lang::Thread::holdsLock (jobject obj)
+{
+ if (!obj)
+ throw new NullPointerException;
+ return !_Jv_ObjectCheckMonitor (obj);
+}
+
+jboolean
+java::lang::Thread::isAlive (void)
+{
+ natThread *nt = (natThread *) data;
+ return nt->alive_flag != (obj_addr_t)THREAD_DEAD;
+}
+
+void
+java::lang::Thread::interrupt (void)
+{
+ checkAccess ();
+
+ natThread *nt = (natThread *) data;
+
+ // If a thread is in state ALIVE, we atomically set it to state
+ // SIGNALED and send it a signal. Once we've sent it the signal, we
+ // set its state back to ALIVE.
+ if (compare_and_swap
+ (&nt->alive_flag, Thread::THREAD_ALIVE, Thread::THREAD_SIGNALED))
+ {
+ _Jv_ThreadInterrupt (nt->thread);
+ compare_and_swap
+ (&nt->alive_flag, THREAD_SIGNALED, Thread::THREAD_ALIVE);
+
+ // Even though we've interrupted this thread, it might still be
+ // parked.
+ nt->park_helper.unpark ();
+ }
+}
+
+void
+java::lang::Thread::join (jlong millis, jint nanos)
+{
+ if (millis < 0 || nanos < 0 || nanos > 999999)
+ throw new IllegalArgumentException;
+
+ Thread *current = currentThread ();
+
+ // Here `NT' is the native structure for the thread we are trying to join.
+ natThread *nt = (natThread *) data;
+
+ // Now wait for: (1) an interrupt, (2) the thread to exit, or (3)
+ // the timeout to occur.
+ _Jv_MutexLock (&nt->join_mutex);
+ if (! isAlive ())
+ {
+ _Jv_MutexUnlock (&nt->join_mutex);
+ return;
+ }
+ _Jv_CondWait (&nt->join_cond, &nt->join_mutex, millis, nanos);
+ _Jv_MutexUnlock (&nt->join_mutex);
+
+ if (current->isInterrupted (true))
+ throw new InterruptedException;
+}
+
+void
+java::lang::Thread::resume (void)
+{
+ checkAccess ();
+
+ // Old applets still call this method. Rather than throwing
+ // UnsupportedOperationException we simply fail silently.
+}
+
+void
+java::lang::Thread::setPriority (jint newPriority)
+{
+ checkAccess ();
+ if (newPriority < MIN_PRIORITY || newPriority > MAX_PRIORITY)
+ throw new IllegalArgumentException;
+
+ jint gmax = group->getMaxPriority();
+ if (newPriority > gmax)
+ newPriority = gmax;
+
+ priority = newPriority;
+ natThread *nt = (natThread *) data;
+ _Jv_ThreadSetPriority (nt->thread, priority);
+}
+
+void
+java::lang::Thread::sleep (jlong millis, jint nanos)
+{
+ if (millis < 0 || nanos < 0 || nanos > 999999)
+ throw new IllegalArgumentException;
+
+ if (millis == 0 && nanos == 0)
+ ++nanos;
+
+ Thread *current = currentThread ();
+
+ // We use a condition variable to implement sleeping so that an
+ // interrupt can wake us up.
+ natThread *nt = (natThread *) current->data;
+ _Jv_MutexLock (&nt->join_mutex);
+ _Jv_CondWait (&nt->join_cond, &nt->join_mutex, millis, nanos);
+ _Jv_MutexUnlock (&nt->join_mutex);
+
+ if (current->isInterrupted (true))
+ throw new InterruptedException;
+}
+
+void
+java::lang::Thread::finish_ ()
+{
+ __sync_synchronize();
+ natThread *nt = (natThread *) data;
+
+ nt->park_helper.deactivate ();
+ group->removeThread (this);
+
+#ifdef INTERPRETER
+ if (JVMTI_REQUESTED_EVENT (ThreadEnd))
+ _Jv_JVMTI_PostEvent (JVMTI_EVENT_THREAD_END, this, nt->jni_env);
+#endif
+
+#ifdef ENABLE_JVMPI
+ if (_Jv_JVMPI_Notify_THREAD_END)
+ {
+ JVMPI_Event event;
+
+ event.event_type = JVMPI_EVENT_THREAD_END;
+ event.env_id = _Jv_GetCurrentJNIEnv ();
+
+ _Jv_DisableGC ();
+ (*_Jv_JVMPI_Notify_THREAD_END) (&event);
+ _Jv_EnableGC ();
+ }
+#endif
+
+ // If a method cache was created, free it.
+ _Jv_FreeMethodCache();
+
+ // Clear out thread locals.
+ locals = NULL;
+
+ // Signal any threads that are waiting to join() us.
+ _Jv_MutexLock (&nt->join_mutex);
+
+ {
+ JvSynchronize sync (this);
+ nt->alive_flag = THREAD_DEAD;
+ state = JV_TERMINATED;
+ }
+
+ _Jv_CondNotifyAll (&nt->join_cond, &nt->join_mutex);
+ _Jv_MutexUnlock (&nt->join_mutex);
+}
+
+// Run once at thread startup, either when thread is attached or when
+// _Jv_ThreadRun is called.
+static void
+_Jv_NotifyThreadStart (java::lang::Thread* thread)
+{
+#ifdef INTERPRETER
+ if (JVMTI_REQUESTED_EVENT (ThreadStart))
+ {
+ natThread *nt = reinterpret_cast<natThread *> (thread->data);
+ _Jv_JVMTI_PostEvent (JVMTI_EVENT_THREAD_START, thread, nt->jni_env);
+ }
+#endif
+
+#ifdef ENABLE_JVMPI
+ if (_Jv_JVMPI_Notify_THREAD_START)
+ {
+ JVMPI_Event event;
+
+ jstring thread_name = thread->getName ();
+ jstring group_name = NULL, parent_name = NULL;
+ java::lang::ThreadGroup *group = thread->getThreadGroup ();
+
+ if (group)
+ {
+ group_name = group->getName ();
+ group = group->getParent ();
+
+ if (group)
+ parent_name = group->getName ();
+ }
+
+ int thread_len = thread_name ? JvGetStringUTFLength (thread_name) : 0;
+ int group_len = group_name ? JvGetStringUTFLength (group_name) : 0;
+ int parent_len = parent_name ? JvGetStringUTFLength (parent_name) : 0;
+
+ char thread_chars[thread_len + 1];
+ char group_chars[group_len + 1];
+ char parent_chars[parent_len + 1];
+
+ if (thread_name)
+ JvGetStringUTFRegion (thread_name, 0,
+ thread_name->length(), thread_chars);
+ if (group_name)
+ JvGetStringUTFRegion (group_name, 0,
+ group_name->length(), group_chars);
+ if (parent_name)
+ JvGetStringUTFRegion (parent_name, 0,
+ parent_name->length(), parent_chars);
+
+ thread_chars[thread_len] = '\0';
+ group_chars[group_len] = '\0';
+ parent_chars[parent_len] = '\0';
+
+ event.event_type = JVMPI_EVENT_THREAD_START;
+ event.env_id = NULL;
+ event.u.thread_start.thread_name = thread_chars;
+ event.u.thread_start.group_name = group_chars;
+ event.u.thread_start.parent_name = parent_chars;
+ event.u.thread_start.thread_id = (jobjectID) thread;
+ event.u.thread_start.thread_env_id = _Jv_GetCurrentJNIEnv ();
+
+ _Jv_DisableGC ();
+ (*_Jv_JVMPI_Notify_THREAD_START) (&event);
+ _Jv_EnableGC ();
+ }
+#endif
+}
+
+void
+_Jv_ThreadRun (java::lang::Thread* thread)
+{
+ try
+ {
+ _Jv_NotifyThreadStart (thread);
+ thread->run ();
+ }
+ catch (java::lang::Throwable *t)
+ {
+ // Uncaught exceptions are forwarded to the ThreadGroup. If
+ // this results in an uncaught exception, that is ignored.
+ try
+ {
+ thread->getUncaughtExceptionHandler()->uncaughtException (thread, t);
+ }
+ catch (java::lang::Throwable *f)
+ {
+ // Nothing.
+ }
+ }
+
+ thread->finish_ ();
+}
+
+_Jv_Thread_t*
+_Jv_ThreadGetData (java::lang::Thread* thread)
+{
+ natThread* nt = (natThread*) thread->data;
+ return nt->thread;
+}
+
+void
+java::lang::Thread::start (void)
+{
+ JvSynchronize sync (this);
+
+ // Its illegal to re-start() a thread, even if its dead.
+ if (!startable_flag)
+ throw new IllegalThreadStateException;
+
+ natThread *nt = (natThread *) data;
+ nt->alive_flag = THREAD_ALIVE;
+ startable_flag = false;
+ state = JV_RUNNABLE;
+ _Jv_ThreadStart (this, nt->thread, (_Jv_ThreadStartFunc *) &_Jv_ThreadRun);
+}
+
+void
+java::lang::Thread::stop (java::lang::Throwable *)
+{
+ checkAccess ();
+
+ // Old applets still call this method. Rather than throwing
+ // UnsupportedOperationException we simply fail silently.
+}
+
+void
+java::lang::Thread::suspend (void)
+{
+ checkAccess ();
+
+ // Old applets still call this method. Rather than throwing
+ // UnsupportedOperationException we simply fail silently.
+}
+
+static int nextThreadNumber = 0;
+
+jstring
+java::lang::Thread::gen_name (void)
+{
+ jint i;
+ jclass sync = &java::lang::Thread::class$;
+ {
+ JvSynchronize dummy(sync);
+ i = ++nextThreadNumber;
+ }
+
+ // Use an array large enough for "-2147483648"; i.e. 11 chars, + "Thread-".
+ jchar buffer[7+11];
+ jchar *bufend = (jchar *) ((char *) buffer + sizeof(buffer));
+ i = _Jv_FormatInt (bufend, i);
+ jchar *ptr = bufend - i;
+ // Prepend "Thread-".
+ *--ptr = '-';
+ *--ptr = 'd';
+ *--ptr = 'a';
+ *--ptr = 'e';
+ *--ptr = 'r';
+ *--ptr = 'h';
+ *--ptr = 'T';
+ return JvNewString (ptr, bufend - ptr);
+}
+
+void
+java::lang::Thread::yield (void)
+{
+ _Jv_ThreadYield ();
+}
+
+::java::lang::Thread$State *
+java::lang::Thread::getState()
+{
+ _Jv_InitClass(&::java::lang::Thread$State::class$);
+
+ switch (state)
+ {
+ case JV_BLOCKED:
+ return ::java::lang::Thread$State::BLOCKED;
+ case JV_NEW:
+ return ::java::lang::Thread$State::NEW;
+
+ case JV_RUNNABLE:
+ return ::java::lang::Thread$State::RUNNABLE;
+ case JV_TERMINATED:
+ return ::java::lang::Thread$State::TERMINATED;
+ case JV_TIMED_WAITING:
+ return ::java::lang::Thread$State::TIMED_WAITING;
+ case JV_WAITING:
+ return ::java::lang::Thread$State::WAITING;
+ }
+
+ // We don't really need a default, but this makes the compiler
+ // happy.
+ return ::java::lang::Thread$State::RUNNABLE;
+}
+
+JNIEnv *
+_Jv_GetCurrentJNIEnv ()
+{
+ java::lang::Thread *t = _Jv_ThreadCurrent ();
+ if (t == NULL)
+ return NULL;
+ return ((natThread *) t->data)->jni_env;
+}
+
+void
+_Jv_SetCurrentJNIEnv (JNIEnv *env)
+{
+ java::lang::Thread *t = _Jv_ThreadCurrent ();
+ JvAssert (t != NULL);
+ ((natThread *) t->data)->jni_env = env;
+}
+
+// Attach the current native thread to an existing (but unstarted) Thread
+// object. Does not register thread with the garbage collector.
+// Returns -1 on failure, 0 upon success.
+jint
+_Jv_AttachCurrentThread(java::lang::Thread* thread)
+{
+ JvSynchronize sync (thread);
+ if (thread == NULL || thread->startable_flag == false)
+ return -1;
+ thread->startable_flag = false;
+ natThread *nt = (natThread *) thread->data;
+ nt->alive_flag = ::java::lang::Thread::THREAD_ALIVE;
+ thread->state = JV_RUNNABLE;
+ _Jv_ThreadRegister (nt->thread);
+ return 0;
+}
+
+java::lang::Thread*
+_Jv_AttachCurrentThread(jstring name, java::lang::ThreadGroup* group)
+{
+ // Register thread with GC before attempting any allocations.
+ _Jv_GCAttachThread ();
+ java::lang::Thread *thread = _Jv_ThreadCurrent ();
+ if (thread != NULL)
+ return thread;
+ if (name == NULL)
+ name = java::lang::Thread::gen_name ();
+ thread = new java::lang::Thread (NULL, group, NULL, name, false);
+ _Jv_AttachCurrentThread (thread);
+ _Jv_NotifyThreadStart (thread);
+ return thread;
+}
+
+java::lang::Thread*
+_Jv_AttachCurrentThreadAsDaemon(jstring name, java::lang::ThreadGroup* group)
+{
+ java::lang::Thread *thread = _Jv_ThreadCurrent ();
+ if (thread != NULL)
+ return thread;
+ if (name == NULL)
+ name = java::lang::Thread::gen_name ();
+ thread = new java::lang::Thread (NULL, group, NULL, name, false);
+ thread->setDaemon (true);
+ _Jv_AttachCurrentThread (thread);
+ _Jv_NotifyThreadStart (thread);
+ return thread;
+}
+
+jint
+_Jv_DetachCurrentThread (void)
+{
+ java::lang::Thread *t = _Jv_ThreadCurrent ();
+ if (t == NULL)
+ return -1;
+
+ _Jv_ThreadUnRegister ();
+ _Jv_GCDetachThread ();
+ // Release the monitors.
+ t->finish_ ();
+
+ return 0;
+}
diff --git a/libjava/java/lang/natThreadLocal.cc b/libjava/java/lang/natThreadLocal.cc
new file mode 100644
index 000000000..cd61f4a62
--- /dev/null
+++ b/libjava/java/lang/natThreadLocal.cc
@@ -0,0 +1,169 @@
+// natThreadLocal.cc - Native part of ThreadLocal class.
+
+// Fast thread local storage for systems that support the __thread
+// variable attribute.
+
+/* Copyright (C) 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-threads.h>
+
+#include <gnu/gcj/RawDataManaged.h>
+#include <java/lang/ThreadLocal.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IllegalThreadStateException.h>
+#include <java/lang/InterruptedException.h>
+#include <java/util/Map.h>
+
+#include <jni.h>
+
+/* We would like to have fast thread local variables that behave in
+ the same way as C and C++ thread local variables. This would mean
+ having an field attribute "thread" (like static, final, etc.).
+ However, this is not compatible with java semantics, which we wish
+ to support transparently. The problems we must overcome are:
+
+ * In Java, ThreadLocal variables are not statically allocated: they
+ are objects, created at runtime.
+
+ * Class ThreadLocal is not final and neither are its methods, so it
+ is possible to create a subclass of ThreadLocal that overrides
+ any method.
+
+ * __thread variables in DSOs are not visible to the garbage
+ collector, so we must ensure that we keep a copy of every thread
+ local variable somewhere on the heap.
+
+ * Once a ThreadLocal instance has been created and assigned to a
+ static field, that field may be reassigned to a different
+ ThreadLocal instance or null.
+
+ So, we can't simply replace get() and set() with accesses of a
+ __thread variable.
+
+ So, we create a pthread_key in each ThreadLocal object and use that
+ as a kind of "look-aside cache". When a ThreadLocal is set, we
+ also set the corresponding thread-specific value. When the
+ ThreadLocal is collected, we delete the key.
+
+ This scheme is biased towards efficiency when get() is called much
+ more frequently than set(). It is slightly internaler than the
+ all-Java solution using the underlying map in the set() case.
+ However, get() is very much more frequently invoked than set().
+
+*/
+
+
+#ifdef _POSIX_PTHREAD_SEMANTICS
+
+class tls_t
+{
+public:
+ pthread_key_t key;
+};
+
+void
+java::lang::ThreadLocal::constructNative (void)
+{
+ tls_t *tls = (tls_t *)_Jv_Malloc (sizeof (tls_t));
+ if (pthread_key_create (&tls->key, NULL) == 0)
+ TLSPointer = (::gnu::gcj::RawData *)tls;
+ else
+ _Jv_Free (tls);
+}
+
+void
+java::lang::ThreadLocal::set (::java::lang::Object *value)
+{
+ if (TLSPointer != NULL)
+ {
+ tls_t* tls = (tls_t*)TLSPointer;
+ pthread_setspecific (tls->key, value);
+ }
+
+ internalSet (value);
+}
+
+::java::lang::Object *
+java::lang::ThreadLocal::get (void)
+{
+ if (TLSPointer == NULL)
+ return internalGet ();
+
+ tls_t* tls = (tls_t*)TLSPointer;
+ void *obj = pthread_getspecific(tls->key);
+
+ if (obj)
+ return (::java::lang::Object *)obj;
+
+ ::java::lang::Object *value = internalGet ();
+ pthread_setspecific (tls->key, value);
+
+ return value;
+}
+
+void
+java::lang::ThreadLocal::remove (void)
+{
+ if (TLSPointer != NULL)
+ {
+ tls_t* tls = (tls_t*)TLSPointer;
+ pthread_setspecific (tls->key, NULL);
+ }
+
+ internalRemove ();
+}
+
+void
+java::lang::ThreadLocal::finalize (void)
+{
+ if (TLSPointer != NULL)
+ {
+ tls_t* tls = (tls_t*)TLSPointer;
+ pthread_key_delete (tls->key);
+ _Jv_Free (tls);
+ }
+}
+
+#else
+
+void
+java::lang::ThreadLocal::constructNative (void)
+{
+}
+
+void
+java::lang::ThreadLocal::set (::java::lang::Object *value)
+{
+ internalSet (value);
+}
+
+::java::lang::Object *
+java::lang::ThreadLocal::get (void)
+{
+ return internalGet ();
+}
+
+void
+java::lang::ThreadLocal::remove (void)
+{
+ internalRemove ();
+}
+
+void
+java::lang::ThreadLocal::finalize (void)
+{
+}
+
+#endif
diff --git a/libjava/java/lang/natVMClassLoader.cc b/libjava/java/lang/natVMClassLoader.cc
new file mode 100644
index 000000000..4edff7daf
--- /dev/null
+++ b/libjava/java/lang/natVMClassLoader.cc
@@ -0,0 +1,245 @@
+// natVMClassLoader.cc - VMClassLoader native methods
+
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+/* Author: Kresten Krab Thorup <krab@gnu.org> */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java-threads.h>
+#include <java-interp.h>
+
+#include <java/lang/VMClassLoader.h>
+#include <java/lang/VMCompiler.h>
+#include <gnu/gcj/runtime/ExtensionClassLoader.h>
+#include <gnu/gcj/runtime/SystemClassLoader.h>
+#include <gnu/gcj/runtime/BootClassLoader.h>
+#include <java/lang/ClassLoader.h>
+#include <java/lang/Class.h>
+#include <java/lang/Throwable.h>
+#include <java/security/ProtectionDomain.h>
+#include <java/lang/ClassFormatError.h>
+#include <java/lang/StringBuffer.h>
+#include <java/lang/SecurityManager.h>
+#include <java/lang/Runtime.h>
+#include <java/util/HashSet.h>
+#include <java/lang/SecurityException.h>
+#include <java/lang/VirtualMachineError.h>
+
+java::lang::Class *
+java::lang::VMClassLoader::defineClass (java::lang::ClassLoader *loader,
+ jstring name,
+ jbyteArray data,
+ jint offset,
+ jint length,
+ java::security::ProtectionDomain *pd)
+{
+ jclass klass = VMCompiler::compileClass(loader, name, data,
+ offset, length, pd);
+
+ if (klass)
+ _Jv_RegisterInitiatingLoader (klass, klass->loader);
+
+#ifdef INTERPRETER
+ if (klass == NULL)
+ {
+ klass = new java::lang::Class ();
+
+ // Synchronize on the class, so that it is not attempted initialized
+ // until we're done loading.
+ JvSynchronize sync (klass);
+
+ // Record the defining loader. For the bootstrap class loader,
+ // we record NULL.
+ if (loader != bootLoader)
+ klass->loader = loader;
+
+ if (name != 0)
+ {
+ _Jv_Utf8Const *name2 = _Jv_makeUtf8Const (name);
+
+ if (! _Jv_VerifyClassName (name2))
+ throw new java::lang::ClassFormatError
+ (JvNewStringLatin1 ("erroneous class name"));
+
+ klass->name = name2;
+ }
+
+ _Jv_Utf8Const *found_name = NULL;
+ try
+ {
+ _Jv_DefineClass (klass, data, offset, length, pd, &found_name);
+ }
+ catch (java::lang::Throwable *ex)
+ {
+ klass->state = JV_STATE_ERROR;
+ klass->notifyAll ();
+
+ if (found_name != NULL)
+ _Jv_UnregisterInitiatingLoader (klass, klass->loader);
+
+ // If EX is not a ClassNotFoundException, that's ok, because we
+ // account for the possibility in defineClass().
+ throw ex;
+ }
+
+ // if everything proceeded sucessfully, we're loaded.
+ JvAssert (klass->state == JV_STATE_READ);
+ }
+#endif // INTERPRETER
+
+ if (! klass)
+ {
+ StringBuffer *sb = new StringBuffer();
+ if (name)
+ {
+ sb->append(JvNewStringLatin1("found class file for class "));
+ sb->append(name);
+ }
+ else
+ sb->append(JvNewStringLatin1("found unnamed class file"));
+ sb->append(JvNewStringLatin1(", but no interpreter configured in this libgcj"));
+ throw new VirtualMachineError(sb->toString());
+ }
+
+ return klass;
+}
+
+java::lang::ClassLoader *
+java::lang::VMClassLoader::getSystemClassLoaderInternal()
+{
+ _Jv_InitClass (&gnu::gcj::runtime::ExtensionClassLoader::class$);
+ _Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::ExtensionClassLoader::system_instance);
+ return gnu::gcj::runtime::ExtensionClassLoader::system_instance;
+}
+
+jclass
+java::lang::VMClassLoader::getPrimitiveClass (jchar type)
+{
+ char sig[2];
+ sig[0] = (char) type;
+ sig[1] = '\0';
+ // Note: this cannot return NULL, since the input is always correct.
+ return _Jv_FindClassFromSignature (sig, NULL);
+}
+
+void
+java::lang::VMClassLoader::initBootLoader(jstring libdir)
+{
+ bootLoader = new gnu::gcj::runtime::BootClassLoader(libdir);
+}
+
+jclass
+java::lang::VMClassLoader::nativeFindClass (jstring name)
+{
+ jclass klass = NULL;
+
+ if (lib_control != LIB_NEVER)
+ {
+ // Turn `gnu.pkg.quux' into `lib-gnu-pkg-quux'. Then search for
+ // a module named (eg, on Linux) `lib-gnu-pkg-quux.so', followed
+ // by `lib-gnu-pkg.so' and `lib-gnu.so'. If loading one of
+ // these causes the class to appear in the cache, then use it.
+ java::lang::StringBuffer *sb
+ = new java::lang::StringBuffer (JvNewStringLatin1("lib-"));
+ // Skip inner classes
+ jstring cn;
+ jint ci = name->indexOf('$');
+ if (ci == -1)
+ cn = name;
+ else
+ cn = name->substring (0, ci);
+ jstring so_base_name
+ = (sb->append (cn)->toString ())->replace ('.', '-');
+
+ using namespace ::java::lang;
+ Runtime *rt = Runtime::getRuntime();
+
+ _Jv_Utf8Const *name_u = NULL;
+
+ // Compare against `3' because that is the length of "lib".
+ while (! klass && so_base_name && so_base_name->length() > 3)
+ {
+ if (lib_control == LIB_CACHE)
+ {
+ // If we've already tried this name, we're done.
+ if (tried_libraries->contains(so_base_name))
+ break;
+ tried_libraries->add(so_base_name);
+ }
+
+ jboolean loaded = rt->loadLibraryInternal (so_base_name);
+
+ jint nd = so_base_name->lastIndexOf ('-');
+ if (nd == -1)
+ so_base_name = NULL;
+ else
+ so_base_name = so_base_name->substring (0, nd);
+
+ if (loaded)
+ {
+ if (name_u == NULL)
+ name_u = _Jv_makeUtf8Const (name);
+ klass = _Jv_FindClassInCache (name_u);
+ }
+ }
+ }
+
+ if (klass)
+ definePackageForNative(name);
+
+ return klass;
+}
+
+jclass
+java::lang::VMClassLoader::loadClass(jstring name, jboolean resolve)
+{
+ using namespace ::java::lang;
+
+ SecurityManager *sm = (SecurityManager *)SecurityManager::current;
+ if (sm)
+ {
+ jint lastDot = name->lastIndexOf('.');
+ if (lastDot != -1)
+ sm->checkPackageAccess(name->substring(0, lastDot));
+ }
+
+ // We try the boot loader first, so that the endorsed directory
+ // overrides compiled-in classes.
+ jclass klass = NULL;
+ if (bootLoader)
+ klass = bootLoader->bootLoadClass(name);
+ if (! klass)
+ {
+ _Jv_Utf8Const *utf = _Jv_makeUtf8Const (name);
+ klass = _Jv_FindClassInCache (utf);
+ }
+ if (! klass)
+ klass = nativeFindClass(name);
+ if (klass)
+ {
+ // We never want to return a class without its supers linked.
+ // It isn't clear from the spec, but this is what other
+ // implementations do in practice.
+ if (resolve)
+ resolveClass (klass);
+ else
+ _Jv_Linker::wait_for_state (klass, JV_STATE_LOADING);
+
+ definePackageForNative(name);
+ }
+
+ return klass;
+}
diff --git a/libjava/java/lang/natVMDouble.cc b/libjava/java/lang/natVMDouble.cc
new file mode 100644
index 000000000..f770bc422
--- /dev/null
+++ b/libjava/java/lang/natVMDouble.cc
@@ -0,0 +1,215 @@
+// natVMDouble.cc - Implementation of java.lang.VMDouble native methods.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005, 2006, 2007
+ Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <java/lang/String.h>
+#include <java/lang/Double.h>
+#include <java/lang/VMDouble.h>
+#include <java/lang/Character.h>
+#include <java/lang/NumberFormatException.h>
+#include <jvm.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "fdlibm.h"
+
+union u
+{
+ jlong l;
+ jdouble d;
+};
+
+jlong
+java::lang::VMDouble::doubleToLongBits(jdouble value)
+{
+ union u u;
+ u.d = value;
+
+ jlong e = u.l & 0x7ff0000000000000LL;
+ jlong f = u.l & 0x000fffffffffffffLL;
+
+ if (e == 0x7ff0000000000000LL && f != 0L)
+ u.l = 0x7ff8000000000000LL;
+
+ return u.l;
+}
+
+jlong
+java::lang::VMDouble::doubleToRawLongBits(jdouble value)
+{
+ union u u;
+ u.d = value;
+ return u.l;
+}
+
+jdouble
+java::lang::VMDouble::longBitsToDouble(jlong bits)
+{
+ union u u;
+ u.l = bits;
+ return u.d;
+}
+
+jstring
+java::lang::VMDouble::toString(jdouble value, jboolean isFloat)
+{
+ if (Double::isNaN (value))
+ return JvNewStringLatin1 ("NaN", sizeof ("NaN") - 1);
+
+ if (value == Double::POSITIVE_INFINITY)
+ return JvNewStringLatin1 ("Infinity", sizeof ("Infinity") - 1);
+
+ if (value == Double::NEGATIVE_INFINITY)
+ return JvNewStringLatin1 ("-Infinity", sizeof ("-Infinity") - 1);
+
+ char buffer[50], result[50];
+ int decpt, sign;
+
+ _dtoa (value, 0, 20, &decpt, &sign, NULL, buffer, (int)isFloat);
+
+ value = fabs (value);
+
+ char *s = buffer;
+ char *d = result;
+
+ if (sign)
+ *d++ = '-';
+
+ if ((value >= 1e-3 && value < 1e7) || value == 0)
+ {
+ if (decpt <= 0)
+ *d++ = '0';
+ else
+ {
+ for (int i = 0; i < decpt; i++)
+ if (*s)
+ *d++ = *s++;
+ else
+ *d++ = '0';
+ }
+
+ *d++ = '.';
+
+ if (*s == 0)
+ {
+ *d++ = '0';
+ decpt++;
+ }
+
+ while (decpt++ < 0)
+ *d++ = '0';
+
+ while (*s)
+ *d++ = *s++;
+
+ *d = 0;
+
+ return JvNewStringLatin1 (result, strlen (result));
+ }
+
+ *d++ = *s++;
+ decpt--;
+ *d++ = '.';
+
+ if (*s == 0)
+ *d++ = '0';
+
+ while (*s)
+ *d++ = *s++;
+
+ *d++ = 'E';
+
+ if (decpt < 0)
+ {
+ *d++ = '-';
+ decpt = -decpt;
+ }
+
+ {
+ char exp[4];
+ char *e = exp + sizeof exp;
+
+ *--e = 0;
+ do
+ {
+ *--e = '0' + decpt % 10;
+ decpt /= 10;
+ }
+ while (decpt > 0);
+
+ while (*e)
+ *d++ = *e++;
+ }
+
+ *d = 0;
+
+ return JvNewStringLatin1 (result, strlen (result));
+}
+
+jdouble
+java::lang::VMDouble::parseDouble(jstring str)
+{
+ int length = str->length();
+
+ while (length > 0
+ && Character::isWhitespace(str->charAt(length - 1)))
+ length--;
+
+ // The String could end with a f/F/d/D which is valid but we don't need.
+ bool saw_trailer = false;
+ if (length > 0)
+ {
+ jchar last = str->charAt(length-1);
+ if (last == 'f' || last == 'F' || last == 'd' || last == 'D')
+ {
+ length--;
+ saw_trailer = true;
+ }
+ }
+
+ jsize start = 0;
+ while (length > 0
+ && Character::isWhitespace(str->charAt(start)))
+ start++, length--;
+
+ if (length > 0)
+ {
+ // Note that UTF can expand 3x.
+ char *data = (char *) __builtin_alloca (3 * length + 1);
+ jsize blength = _Jv_GetStringUTFRegion (str, start, length, data);
+ data[blength] = 0;
+
+ if (! saw_trailer)
+ {
+ if (! strcmp (data, "NaN") || ! strcmp (data, "+NaN")
+ || ! strcmp (data, "-NaN"))
+ return Double::NaN;
+ else if (! strcmp (data, "Infinity") || ! strcmp (data, "+Infinity"))
+ return Double::POSITIVE_INFINITY;
+ else if (! strcmp (data, "-Infinity"))
+ return Double::NEGATIVE_INFINITY;
+ }
+
+ struct _Jv_reent reent;
+ memset (&reent, 0, sizeof reent);
+
+ char *endptr;
+ double val = _strtod_r (&reent, data, &endptr);
+ if (endptr == data + blength)
+ return val;
+ }
+ throw new NumberFormatException(str);
+}
diff --git a/libjava/java/lang/natVMFloat.cc b/libjava/java/lang/natVMFloat.cc
new file mode 100644
index 000000000..54ae5191d
--- /dev/null
+++ b/libjava/java/lang/natVMFloat.cc
@@ -0,0 +1,52 @@
+// natVMFloat.cc - Implementation of java.lang.VMFloat native methods.
+
+/* Copyright (C) 1998, 1999, 2001, 2006, 2007 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <java/lang/Float.h>
+#include <java/lang/VMFloat.h>
+#include <jvm.h>
+
+union u
+{
+ jint l;
+ jfloat d;
+};
+
+jint
+java::lang::VMFloat::floatToIntBits(jfloat value)
+{
+ union u u;
+ u.d = value;
+ jint e = u.l & 0x7f800000;
+ jint f = u.l & 0x007fffff;
+
+ if (e == 0x7f800000 && f != 0)
+ u.l = 0x7fc00000;
+
+ return u.l;
+}
+
+jint
+java::lang::VMFloat::floatToRawIntBits(jfloat value)
+{
+ union u u;
+ u.d = value;
+ return u.l;
+}
+
+jfloat
+java::lang::VMFloat::intBitsToFloat(jint bits)
+{
+ union u u;
+ u.l = bits;
+ return u.d;
+}
+
diff --git a/libjava/java/lang/natVMProcess.cc b/libjava/java/lang/natVMProcess.cc
new file mode 100644
index 000000000..dfc6f6023
--- /dev/null
+++ b/libjava/java/lang/natVMProcess.cc
@@ -0,0 +1,33 @@
+// natVMProcess.cc - native code for ProcessBuilder
+
+/* Copyright (C) 2007 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <platform.h>
+
+#include <jvm.h>
+
+#include <java/lang/VMProcess.h>
+#include <java/lang/Process.h>
+#include <java/io/File.h>
+
+// It is convenient and safe to simply include all of these.
+#include <java/lang/Win32Process.h>
+#include <java/lang/EcosProcess.h>
+#include <java/lang/PosixProcess.h>
+
+::java::lang::Process *
+java::lang::VMProcess::nativeExec (jstringArray cmd,
+ jstringArray env,
+ ::java::io::File *dir,
+ jboolean redirect)
+{
+ return new _Jv_platform_process (cmd, env, dir, redirect);
+}
diff --git a/libjava/java/lang/natVMThrowable.cc b/libjava/java/lang/natVMThrowable.cc
new file mode 100644
index 000000000..b198f9073
--- /dev/null
+++ b/libjava/java/lang/natVMThrowable.cc
@@ -0,0 +1,45 @@
+// natVMThrowable.cc - Native part of VMThrowable class.
+
+/* Copyright (C) 2003, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-stack.h>
+
+#include <java/lang/Throwable.h>
+#include <java/lang/VMThrowable.h>
+
+using namespace gnu::gcj;
+
+java::lang::VMThrowable *
+java::lang::VMThrowable::fillInStackTrace (java::lang::Throwable *)
+{
+ using namespace java::lang;
+
+ // Don't trace stack during initialization of the runtime.
+ if (! gcj::runtimeInitialized)
+ return NULL;
+
+ _Jv_StackTrace *trace = _Jv_StackTrace::GetStackTrace ();
+ VMThrowable *vmthrowable = new VMThrowable ();
+ vmthrowable->data = (RawDataManaged *) trace;
+ return vmthrowable;
+}
+
+
+JArray< ::java::lang::StackTraceElement *> *
+java::lang::VMThrowable::getStackTrace (java::lang::Throwable *throwable)
+{
+ _Jv_StackTrace *trace = reinterpret_cast <_Jv_StackTrace *> (data);
+ return _Jv_StackTrace::GetStackTraceElements (trace, throwable);
+}
diff --git a/libjava/java/lang/natWin32Process.cc b/libjava/java/lang/natWin32Process.cc
new file mode 100644
index 000000000..0e7f60d6c
--- /dev/null
+++ b/libjava/java/lang/natWin32Process.cc
@@ -0,0 +1,360 @@
+// natWin32Process.cc - Native side of Win32 process code.
+
+/* Copyright (C) 2003, 2006, 2007 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+// Conflicts with the definition in "java/lang/reflect/Modifier.h"
+#undef STRICT
+
+#include <java/lang/Win32Process.h>
+#include <java/lang/IllegalThreadStateException.h>
+#include <java/lang/InterruptedException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Thread.h>
+#include <java/io/File.h>
+#include <java/io/FileDescriptor.h>
+#include <java/io/FileInputStream.h>
+#include <java/io/FileOutputStream.h>
+#include <java/io/IOException.h>
+#include <java/lang/OutOfMemoryError.h>
+#include <java/lang/Win32Process$EOFInputStream.h>
+#include <gnu/java/nio/channels/FileChannelImpl.h>
+
+using gnu::java::nio::channels::FileChannelImpl;
+
+void
+java::lang::Win32Process::cleanup (void)
+{
+ // FIXME:
+ // We used to close the input, output and
+ // error streams here, but we can't do that
+ // because the caller also has the right
+ // to close these and FileInputStream and FileOutputStream
+ // scream if you attempt to close() them twice. Presently,
+ // we use _Jv_platform_close_on_exec, which is similar
+ // to the POSIX approach.
+ //
+ // What I wanted to do is have private nested
+ // classes in Win32Process which extend FileInputStream
+ // and FileOutputStream, respectively, but override
+ // close() to permit multiple calls to close(). This
+ // led to class header and platform configury issues
+ // that I didn't feel like dealing with. However,
+ // this approach could conceivably be a good multiplatform
+ // one since delaying the pipe close until process
+ // termination could be wasteful if many child processes
+ // are spawned within the parent process' lifetime.
+ inputStream = NULL;
+ outputStream = NULL;
+ errorStream = NULL;
+
+ if (procHandle)
+ {
+ CloseHandle((HANDLE) procHandle);
+ procHandle = (jint) INVALID_HANDLE_VALUE;
+ }
+}
+
+void
+java::lang::Win32Process::destroy (void)
+{
+ if (! hasExited ())
+ {
+ // Kill it forcibly and assign an (arbitrary) exit code of 0.
+ TerminateProcess ((HANDLE) procHandle, 0);
+ exitCode = 0;
+
+ cleanup ();
+ }
+}
+
+jboolean
+java::lang::Win32Process::hasExited (void)
+{
+ DWORD exitStatus;
+
+ if (GetExitCodeProcess ((HANDLE) procHandle, &exitStatus) != 0)
+ {
+ // NOTE: STILL_ACTIVE is defined as "259" by Win32 - if the
+ // child actually exits with this return code, we have a
+ // problem here. See MSDN documentation on GetExitCodeProcess( ).
+
+ if (exitStatus == STILL_ACTIVE)
+ return false;
+ else
+ {
+ cleanup ();
+ exitCode = exitStatus;
+ return true;
+ }
+ }
+ else
+ return true;
+}
+
+jint
+java::lang::Win32Process::waitFor (void)
+{
+ if (! hasExited ())
+ {
+ DWORD exitStatus = 0UL;
+
+ // Set up our waitable objects array
+ // - 0: the handle to the process we just launched
+ // - 1: our thread's interrupt event
+ HANDLE arh[2];
+ arh[0] = (HANDLE) procHandle;
+ arh[1] = _Jv_Win32GetInterruptEvent ();
+ DWORD rval = WaitForMultipleObjects (2, arh, 0, INFINITE);
+
+ // Use the returned value from WaitForMultipleObjects
+ // instead of our thread's interrupt_flag to test for
+ // thread interruption. See the comment for
+ // _Jv_Win32GetInterruptEvent().
+ bool bInterrupted = rval == (WAIT_OBJECT_0 + 1);
+
+ if (bInterrupted)
+ {
+ // Querying this forces a reset our thread's interrupt flag.
+ Thread::interrupted();
+
+ cleanup ();
+ throw new InterruptedException ();
+ }
+
+ GetExitCodeProcess ((HANDLE) procHandle, &exitStatus);
+ exitCode = exitStatus;
+
+ cleanup ();
+ }
+
+ return exitCode;
+}
+
+
+// Helper class for creating and managing the pipes
+// used for I/O redirection for child processes.
+class ChildProcessPipe
+{
+public:
+ // Indicates from the child process' point of view
+ // whether the pipe is for reading or writing.
+ enum EType {INPUT, OUTPUT, DUMMY};
+
+ ChildProcessPipe(EType eType);
+ ~ChildProcessPipe();
+
+ // Returns a pipe handle suitable for use by the parent process
+ HANDLE getParentHandle();
+
+ // Returns a pipe handle suitable for use by the child process.
+ HANDLE getChildHandle();
+
+private:
+ EType m_eType;
+ HANDLE m_hRead, m_hWrite;
+};
+
+ChildProcessPipe::ChildProcessPipe(EType eType):
+ m_eType(eType), m_hRead(0), m_hWrite(0)
+{
+ if (eType == DUMMY)
+ return;
+
+ SECURITY_ATTRIBUTES sAttrs;
+
+ // Explicitly allow the handles to the pipes to be inherited.
+ sAttrs.nLength = sizeof (SECURITY_ATTRIBUTES);
+ sAttrs.bInheritHandle = 1;
+ sAttrs.lpSecurityDescriptor = NULL;
+
+ if (CreatePipe (&m_hRead, &m_hWrite, &sAttrs, 0) == 0)
+ {
+ DWORD dwErrorCode = GetLastError ();
+ throw new java::io::IOException (
+ _Jv_WinStrError (_T("Error creating pipe"), dwErrorCode));
+ }
+
+ // If this is the read end of the child, we need
+ // to make the parent write end non-inheritable. Similarly,
+ // if this is the write end of the child, we need to make
+ // the parent read end non-inheritable. If we didn't
+ // do this, the child would inherit these ends and we wouldn't
+ // be able to close them from our end. For full details,
+ // do a Google search on "Q190351".
+ HANDLE& rhStd = m_eType==INPUT ? m_hWrite : m_hRead;
+ _Jv_platform_close_on_exec (rhStd);
+}
+
+ChildProcessPipe::~ChildProcessPipe()
+{
+ // Close the parent end of the pipe. This
+ // destructor is called after the child process
+ // has been spawned.
+ if (m_eType != DUMMY)
+ CloseHandle(getChildHandle());
+}
+
+HANDLE ChildProcessPipe::getParentHandle()
+{
+ return m_eType==INPUT ? m_hWrite : m_hRead;
+}
+
+HANDLE ChildProcessPipe::getChildHandle()
+{
+ return m_eType==INPUT ? m_hRead : m_hWrite;
+}
+
+void
+java::lang::Win32Process::startProcess (jstringArray progarray,
+ jstringArray envp,
+ java::io::File *dir,
+ jboolean redirect)
+{
+ using namespace java::io;
+
+ procHandle = (jint) INVALID_HANDLE_VALUE;
+
+ // Reconstruct the command line.
+ jstring *elts = elements (progarray);
+
+ int cmdLineLen = 0;
+
+ for (int i = 0; i < progarray->length; ++i)
+ cmdLineLen += (elts[i]->length() + 1);
+
+ LPTSTR cmdLine = (LPTSTR) _Jv_Malloc ((cmdLineLen + 1) * sizeof(TCHAR));
+ LPTSTR cmdLineCurPos = cmdLine;
+
+ for (int i = 0; i < progarray->length; ++i)
+ {
+ if (i > 0)
+ *cmdLineCurPos++ = _T(' ');
+
+ jint len = elts[i]->length();
+ JV_TEMP_STRING_WIN32(thiselt, elts[i]);
+ _tcscpy(cmdLineCurPos, thiselt);
+ cmdLineCurPos += len;
+ }
+ *cmdLineCurPos = _T('\0');
+
+ // Get the environment, if any.
+ LPTSTR env = NULL;
+ if (envp)
+ {
+ elts = elements (envp);
+
+ int envLen = 0;
+ for (int i = 0; i < envp->length; ++i)
+ envLen += (elts[i]->length() + 1);
+
+ env = (LPTSTR) _Jv_Malloc ((envLen + 1) * sizeof(TCHAR));
+
+ int j = 0;
+ for (int i = 0; i < envp->length; ++i)
+ {
+ jint len = elts[i]->length();
+
+ JV_TEMP_STRING_WIN32(thiselt, elts[i]);
+ _tcscpy(env + j, thiselt);
+
+ j += len;
+
+ // Skip past the null terminator that _tcscpy just inserted.
+ j++;
+ }
+ *(env + j) = _T('\0');
+ }
+
+ // Get the working directory path, if specified.
+ JV_TEMP_STRING_WIN32 (wdir, dir ? dir->getPath () : 0);
+
+ errorStream = NULL;
+ inputStream = NULL;
+ outputStream = NULL;
+
+ java::lang::Throwable *exc = NULL;
+
+ try
+ {
+ // We create anonymous pipes to communicate with the child
+ // on each of standard streams.
+ ChildProcessPipe aChildStdIn(ChildProcessPipe::INPUT);
+ ChildProcessPipe aChildStdOut(ChildProcessPipe::OUTPUT);
+ ChildProcessPipe aChildStdErr(redirect ? ChildProcessPipe::DUMMY
+ : ChildProcessPipe::OUTPUT);
+
+ outputStream = new FileOutputStream (new FileChannelImpl (
+ (jint) aChildStdIn.getParentHandle (),
+ FileChannelImpl::WRITE));
+ inputStream = new FileInputStream (new FileChannelImpl (
+ (jint) aChildStdOut.getParentHandle (),
+ FileChannelImpl::READ));
+ if (redirect)
+ errorStream = Win32Process$EOFInputStream::instance;
+ else
+ errorStream = new FileInputStream (new FileChannelImpl (
+ (jint) aChildStdErr.getParentHandle (),
+ FileChannelImpl::READ));
+
+ // Now create the child process.
+ PROCESS_INFORMATION pi;
+ STARTUPINFO si;
+
+ ZeroMemory (&pi, sizeof (PROCESS_INFORMATION));
+
+ ZeroMemory (&si, sizeof (STARTUPINFO));
+ si.cb = sizeof (STARTUPINFO);
+
+ // Explicitly specify the handles to the standard streams.
+ si.dwFlags |= STARTF_USESTDHANDLES;
+
+ si.hStdInput = aChildStdIn.getChildHandle();
+ si.hStdOutput = aChildStdOut.getChildHandle();
+ si.hStdError = redirect ? aChildStdOut.getChildHandle()
+ : aChildStdErr.getChildHandle();
+
+ // Spawn the process. CREATE_NO_WINDOW only applies when
+ // starting a console application; it suppresses the
+ // creation of a console window. This flag is ignored on
+ // Win9X.
+
+ if (CreateProcess (NULL,
+ cmdLine,
+ NULL,
+ NULL,
+ 1,
+ CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
+ env,
+ wdir,
+ &si,
+ &pi) == 0)
+ {
+ DWORD dwErrorCode = GetLastError ();
+ throw new IOException (
+ _Jv_WinStrError (_T("Error creating child process"), dwErrorCode));
+ }
+
+ procHandle = (jint ) pi.hProcess;
+
+ _Jv_Free (cmdLine);
+ if (env != NULL)
+ _Jv_Free (env);
+ }
+ catch (java::lang::Throwable *thrown)
+ {
+ cleanup ();
+ exc = thrown;
+ }
+
+ if (exc != NULL)
+ throw exc;
+}
diff --git a/libjava/java/lang/ref/PhantomReference.h b/libjava/java/lang/ref/PhantomReference.h
new file mode 100644
index 000000000..0c8a823d4
--- /dev/null
+++ b/libjava/java/lang/ref/PhantomReference.h
@@ -0,0 +1,20 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ref_PhantomReference__
+#define __java_lang_ref_PhantomReference__
+
+#pragma interface
+
+#include <java/lang/ref/Reference.h>
+
+class java::lang::ref::PhantomReference : public ::java::lang::ref::Reference
+{
+
+public:
+ PhantomReference(::java::lang::Object *, ::java::lang::ref::ReferenceQueue *);
+ virtual ::java::lang::Object * get();
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ref_PhantomReference__
diff --git a/libjava/java/lang/ref/Reference.h b/libjava/java/lang/ref/Reference.h
new file mode 100644
index 000000000..3eeaf65c6
--- /dev/null
+++ b/libjava/java/lang/ref/Reference.h
@@ -0,0 +1,45 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ref_Reference__
+#define __java_lang_ref_Reference__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ class RawData;
+ }
+ }
+}
+
+class java::lang::ref::Reference : public ::java::lang::Object
+{
+
+public: // actually package-private
+ Reference(::java::lang::Object *);
+ Reference(::java::lang::Object *, ::java::lang::ref::ReferenceQueue *);
+private:
+ void create(::java::lang::Object *);
+public:
+ virtual ::java::lang::Object * get();
+ virtual void clear();
+ virtual jboolean isEnqueued();
+ virtual jboolean enqueue();
+public: // actually package-private
+ ::gnu::gcj::RawData * __attribute__((aligned(__alignof__( ::java::lang::Object)))) referent;
+ ::gnu::gcj::RawData * copy;
+ jboolean cleared;
+ ::java::lang::ref::ReferenceQueue * queue;
+ ::java::lang::ref::Reference * nextOnQueue;
+ static ::java::lang::Object * lock;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ref_Reference__
diff --git a/libjava/java/lang/ref/Reference.java b/libjava/java/lang/ref/Reference.java
new file mode 100644
index 000000000..a5184cee8
--- /dev/null
+++ b/libjava/java/lang/ref/Reference.java
@@ -0,0 +1,204 @@
+/* java.lang.ref.Reference
+ Copyright (C) 1999, 2002, 2003, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.ref;
+
+/**
+ * This is the base class of all references. A reference allows
+ * refering to an object without preventing the garbage collector to
+ * collect it. The only way to get the referred object is via the
+ * <code>get()</code>-method. This method will return
+ * <code>null</code> if the object was collected. <br>
+ *
+ * A reference may be registered with a queue. When a referred
+ * element gets collected the reference will be put on the queue, so
+ * that you will be notified. <br>
+ *
+ * There are currently three types of references: soft reference,
+ * weak reference and phantom reference. <br>
+ *
+ * Soft references will be cleared if the garbage collector is told
+ * to free some memory and there are no unreferenced or weakly referenced
+ * objects. It is useful for caches. <br>
+ *
+ * Weak references will be cleared as soon as the garbage collector
+ * determines that the refered object is only weakly reachable. They
+ * are useful as keys in hashtables (see <code>WeakHashtable</code>) as
+ * you get notified when nobody has the key anymore.
+ *
+ * Phantom references don't prevent finalization. If an object is only
+ * phantom reachable, it will be finalized, and the reference will be
+ * enqueued, but not cleared. Since you mustn't access an finalized
+ * object, the <code>get</code> method of a phantom reference will never
+ * work. It is useful to keep track, when an object is finalized.
+ *
+ * @author Jochen Hoenicke
+ * @see java.util.WeakHashtable
+ */
+public abstract class Reference<T>
+{
+ /**
+ * The underlying object. This field is handled in a special way by
+ * the garbage collector.
+ * GCJ LOCAL:
+ * This is a RawData because it must be disguised from the GC.
+ * END GCJ LOCAL
+ */
+ gnu.gcj.RawData referent;
+
+ /**
+ * This is like REFERENT but is not scanned by the GC. We keep a
+ * copy around so that we can clean up our internal data structure
+ * even after clear() is called.
+ * GCJ LOCAL:
+ * This field doesn't exist in Classpath.
+ * END GCJ LOCAL
+ */
+ gnu.gcj.RawData copy;
+
+ /**
+ * Set to true if {@link #clear()} is called.
+ * GCJ LOCAL:
+ * This field doesn't exist in Classpath. It is used internally in
+ * natReference.cc, which enqueues the reference unless it is true
+ * (has been cleared).
+ * END GCJ LOCAL
+ */
+ boolean cleared = false;
+
+ /**
+ * The queue this reference is registered on. This is null, if this
+ * wasn't registered to any queue or reference was already enqueued.
+ */
+ ReferenceQueue<? super T> queue;
+
+ /**
+ * Link to the next entry on the queue. If this is null, this
+ * reference is not enqueued. Otherwise it points to the next
+ * reference. The last reference on a queue will point to itself
+ * (not to null, that value is used to mark a not enqueued
+ * reference).
+ */
+ Reference nextOnQueue;
+
+ /**
+ * This lock should be taken by the garbage collector, before
+ * determining reachability. It will prevent the get()-method to
+ * return the reference so that reachability doesn't change.
+ */
+ static Object lock = new Object();
+
+ /**
+ * Creates a new reference that is not registered to any queue.
+ * Since it is package private, it is not possible to overload this
+ * class in a different package.
+ * @param referent the object we refer to.
+ */
+ Reference(T ref)
+ {
+ create (ref);
+ }
+
+ /**
+ * Creates a reference that is registered to a queue. Since this is
+ * package private, it is not possible to overload this class in a
+ * different package.
+ * @param referent the object we refer to.
+ * @param q the reference queue to register on.
+ * @exception NullPointerException if q is null.
+ */
+ Reference(T ref, ReferenceQueue<? super T> q)
+ {
+ if (q == null)
+ throw new NullPointerException();
+ queue = q;
+ create (ref);
+ }
+
+ /**
+ * Notifies the VM that a new Reference has been created.
+ */
+ private native void create (T o);
+
+ /**
+ * Returns the object, this reference refers to.
+ * @return the object, this reference refers to, or null if the
+ * reference was cleared.
+ */
+ public native T get();
+
+ /**
+ * Clears the reference, so that it doesn't refer to its object
+ * anymore. For soft and weak references this is called by the
+ * garbage collector. For phantom references you should call
+ * this when enqueuing the reference.
+ */
+ public void clear()
+ {
+ // Must synchronize so changes are visible in finalizer thread.
+ synchronized (lock)
+ {
+ referent = null;
+ cleared = true;
+ }
+ }
+
+ /**
+ * Tells if the object is enqueued on a reference queue.
+ * @return true if it is enqueued, false otherwise.
+ */
+ public boolean isEnqueued()
+ {
+ return nextOnQueue != null;
+ }
+
+ /**
+ * Enqueue an object on a reference queue. This is normally executed
+ * by the garbage collector.
+ */
+ public boolean enqueue()
+ {
+ if (queue != null && nextOnQueue == null)
+ {
+ queue.enqueue(this);
+ queue = null;
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/libjava/java/lang/ref/ReferenceQueue.h b/libjava/java/lang/ref/ReferenceQueue.h
new file mode 100644
index 000000000..bd4a9d8b7
--- /dev/null
+++ b/libjava/java/lang/ref/ReferenceQueue.h
@@ -0,0 +1,31 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ref_ReferenceQueue__
+#define __java_lang_ref_ReferenceQueue__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::ref::ReferenceQueue : public ::java::lang::Object
+{
+
+public:
+ ReferenceQueue();
+ virtual ::java::lang::ref::Reference * poll();
+public: // actually package-private
+ virtual jboolean enqueue(::java::lang::ref::Reference *);
+private:
+ ::java::lang::ref::Reference * dequeue();
+public:
+ virtual ::java::lang::ref::Reference * remove(jlong);
+ virtual ::java::lang::ref::Reference * remove();
+private:
+ ::java::lang::ref::Reference * __attribute__((aligned(__alignof__( ::java::lang::Object)))) first;
+ ::java::lang::Object * lock;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ref_ReferenceQueue__
diff --git a/libjava/java/lang/ref/SoftReference.h b/libjava/java/lang/ref/SoftReference.h
new file mode 100644
index 000000000..faa98e7bd
--- /dev/null
+++ b/libjava/java/lang/ref/SoftReference.h
@@ -0,0 +1,21 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ref_SoftReference__
+#define __java_lang_ref_SoftReference__
+
+#pragma interface
+
+#include <java/lang/ref/Reference.h>
+
+class java::lang::ref::SoftReference : public ::java::lang::ref::Reference
+{
+
+public:
+ SoftReference(::java::lang::Object *);
+ SoftReference(::java::lang::Object *, ::java::lang::ref::ReferenceQueue *);
+ virtual ::java::lang::Object * get();
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ref_SoftReference__
diff --git a/libjava/java/lang/ref/WeakReference.h b/libjava/java/lang/ref/WeakReference.h
new file mode 100644
index 000000000..b540274d3
--- /dev/null
+++ b/libjava/java/lang/ref/WeakReference.h
@@ -0,0 +1,20 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_ref_WeakReference__
+#define __java_lang_ref_WeakReference__
+
+#pragma interface
+
+#include <java/lang/ref/Reference.h>
+
+class java::lang::ref::WeakReference : public ::java::lang::ref::Reference
+{
+
+public:
+ WeakReference(::java::lang::Object *);
+ WeakReference(::java::lang::Object *, ::java::lang::ref::ReferenceQueue *);
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_ref_WeakReference__
diff --git a/libjava/java/lang/ref/natReference.cc b/libjava/java/lang/ref/natReference.cc
new file mode 100644
index 000000000..ac7272cf5
--- /dev/null
+++ b/libjava/java/lang/ref/natReference.cc
@@ -0,0 +1,377 @@
+// natReference.cc - Native code for References
+
+/* Copyright (C) 2001, 2002, 2003, 2005, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// Written by Tom Tromey <tromey@redhat.com>
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/lang/Throwable.h>
+#include <java/lang/ref/Reference.h>
+#include <java/lang/ref/SoftReference.h>
+#include <java/lang/ref/WeakReference.h>
+#include <java/lang/ref/PhantomReference.h>
+#include <java/lang/ref/ReferenceQueue.h>
+
+static void finalize_reference (jobject ref);
+static void finalize_referred_to_object (jobject obj);
+
+
+
+enum weight
+{
+ SOFT = 0,
+ WEAK = 1,
+ FINALIZE = 2,
+ PHANTOM = 3,
+
+ // This is used to mark the head of a list.
+ HEAD = 4,
+
+ // This is used to mark a deleted item.
+ DELETED = 5
+};
+
+// Objects of this type are used in the hash table to keep track of
+// the mapping between a finalizable object and the various References
+// which refer to it.
+struct object_list
+{
+ // The reference object. This is NULL for FINALIZE weight.
+ jobject reference;
+
+ // The weight of this object.
+ enum weight weight;
+
+ // Next in list.
+ object_list *next;
+};
+
+// Hash table used to hold mapping from object to References. The
+// object_list item in the hash holds the object itself in the
+// reference field; chained to it are all the references sorted in
+// order of weight (lowest first).
+static object_list *hash = NULL;
+
+// Number of slots used in HASH.
+static int hash_count = 0;
+
+// Number of slots total in HASH. Must be power of 2.
+static int hash_size = 0;
+
+#define DELETED_REFERENCE ((jobject) -1)
+
+static object_list *
+find_slot (jobject key)
+{
+ jint hcode = _Jv_HashCode (key);
+ /* step must be non-zero, and relatively prime with hash_size. */
+ jint step = (hcode ^ (hcode >> 16)) | 1;
+ int start_index = hcode & (hash_size - 1);
+ int index = start_index;
+ int deleted_index = -1;
+ do
+ {
+ object_list *ptr = &hash[index];
+ if (ptr->reference == key)
+ return ptr;
+ else if (ptr->reference == NULL)
+ {
+ if (deleted_index == -1)
+ return ptr;
+ else
+ return &hash[deleted_index];
+ }
+ else if (ptr->weight == DELETED)
+ {
+ deleted_index = index;
+ JvAssert (ptr->reference == DELETED_REFERENCE);
+ }
+ index = (index + step) & (hash_size - 1);
+ }
+ while (index != start_index);
+ // Note that we can have INDEX == START_INDEX if the table has no
+ // NULL entries but does have DELETED entries.
+ JvAssert (deleted_index >= 0);
+ return &hash[deleted_index];
+}
+
+static void
+rehash ()
+{
+ if (hash == NULL)
+ {
+ hash_size = 1024;
+ hash = (object_list *) _Jv_Malloc (hash_size * sizeof (object_list));
+ memset (hash, 0, hash_size * sizeof (object_list));
+ }
+ else
+ {
+ object_list *old = hash;
+ int i = hash_size;
+
+ hash_size *= 2;
+ hash = (object_list *) _Jv_Malloc (hash_size * sizeof (object_list));
+ memset (hash, 0, hash_size * sizeof (object_list));
+
+ while (--i >= 0)
+ {
+ if (old[i].reference == NULL || old[i].weight == DELETED)
+ continue;
+ object_list *newslot = find_slot (old[i].reference);
+ *newslot = old[i];
+ }
+
+ _Jv_Free (old);
+ }
+}
+
+// Remove a Reference.
+static void
+remove_from_hash (jobject obj)
+{
+ java::lang::ref::Reference *ref
+ = reinterpret_cast<java::lang::ref::Reference *> (obj);
+ object_list *head = find_slot (ref->copy);
+
+ // We might have found a new slot. We can just ignore that here.
+ if (head->reference != ref->copy)
+ return;
+
+ object_list **link = &head->next;
+ head = head->next;
+
+ while (head && head->reference != ref)
+ {
+ link = &head->next;
+ head = head->next;
+ }
+
+ // Remove the slot.
+ if (head)
+ {
+ *link = head->next;
+ _Jv_Free (head);
+ }
+}
+
+// Return list head if object is in hash, NULL otherwise.
+object_list *
+in_hash (jobject obj)
+{
+ // The hash table might not yet be initialized.
+ if (hash == NULL)
+ return NULL;
+ object_list *head = find_slot (obj);
+ if (head->reference != obj)
+ return NULL;
+ return head;
+}
+
+// FIXME what happens if an object's finalizer creates a Reference to
+// the object, and the object has never before been added to the hash?
+// Madness!
+
+// Add an item to the hash table. If the item is new, we also add a
+// finalizer item. We keep items in the hash table until they are
+// completely collected; this lets us know when an item is new, even
+// if it has been resurrected after its finalizer has been run.
+static void
+add_to_hash (java::lang::ref::Reference *the_reference)
+{
+ JvSynchronize sync (java::lang::ref::Reference::lock);
+
+ if (3 * hash_count >= 2 * hash_size)
+ rehash ();
+
+ // Use `copy' here because the `referent' field has been cleared.
+ jobject referent = the_reference->copy;
+ object_list *item = find_slot (referent);
+ if (item->reference == NULL || item->reference == DELETED_REFERENCE)
+ {
+ // New item, so make an entry for the finalizer.
+ item->reference = referent;
+ item->weight = HEAD;
+
+ item->next = (object_list *) _Jv_Malloc (sizeof (object_list));
+ item->next->reference = NULL;
+ item->next->weight = FINALIZE;
+ item->next->next = NULL;
+ ++hash_count;
+ }
+
+ object_list *n = (object_list *) _Jv_Malloc (sizeof (object_list));
+ n->reference = the_reference;
+
+ enum weight w = PHANTOM;
+ if (java::lang::ref::SoftReference::class$.isInstance (the_reference))
+ w = SOFT;
+ else if (java::lang::ref::WeakReference::class$.isInstance (the_reference))
+ w = WEAK;
+ n->weight = w;
+
+ object_list **link = &item->next;
+ object_list *iter = *link;
+ while (iter && iter->weight < n->weight)
+ {
+ link = &iter->next;
+ iter = *link;
+ }
+ n->next = *link;
+ *link = n;
+}
+
+// Add a FINALIZE entry if one doesn't exist.
+static void
+maybe_add_finalize (object_list *entry, jobject obj)
+{
+ object_list **link = &entry->next;
+ object_list *iter = *link;
+ while (iter && iter->weight < FINALIZE)
+ {
+ link = &iter->next;
+ iter = *link;
+ }
+
+ // We want at most one FINALIZE entry in the queue.
+ if (iter && iter->weight == FINALIZE)
+ return;
+
+ object_list *n = (object_list *) _Jv_Malloc (sizeof (object_list));
+ n->reference = obj;
+ n->weight = FINALIZE;
+ n->next = *link;
+ *link = n;
+}
+
+// This is called when an object is ready to be finalized. This
+// actually implements the appropriate Reference semantics.
+static void
+finalize_referred_to_object (jobject obj)
+{
+ JvSynchronize sync (java::lang::ref::Reference::lock);
+
+ object_list *list = find_slot (obj);
+ object_list *head = list->next;
+ if (head == NULL)
+ {
+ // We have a truly dead object: the object's finalizer has been
+ // run, all the object's references have been processed, and the
+ // object is unreachable. There is, at long last, no way to
+ // resurrect it.
+ list->reference = DELETED_REFERENCE;
+ list->weight = DELETED;
+ --hash_count;
+ return;
+ }
+
+ enum weight w = head->weight;
+ if (w == FINALIZE)
+ {
+ // Update the list first, as _Jv_FinalizeString might end up
+ // looking at this data structure.
+ list->next = head->next;
+ _Jv_Free (head);
+
+ // If we have a Reference A to a Reference B, and B is
+ // finalized, then we have to take special care to make sure
+ // that B is properly deregistered. This is super gross. FIXME
+ // will it fail if B's finalizer resurrects B?
+ if (java::lang::ref::Reference::class$.isInstance (obj))
+ finalize_reference (obj);
+ else if (obj->getClass() == &java::lang::String::class$)
+ _Jv_FinalizeString (obj);
+ else
+ _Jv_FinalizeObject (obj);
+ }
+ else if (w != SOFT || _Jv_GCCanReclaimSoftReference (obj))
+ {
+ // If we just decided to reclaim a soft reference, we might as
+ // well do all the weak references at the same time.
+ if (w == SOFT)
+ w = WEAK;
+
+ while (head && head->weight <= w)
+ {
+ java::lang::ref::Reference *ref
+ = reinterpret_cast<java::lang::ref::Reference *> (head->reference);
+ if (! ref->cleared)
+ ref->enqueue ();
+
+ object_list *next = head->next;
+ _Jv_Free (head);
+ head = next;
+ }
+ list->next = head;
+ }
+
+ // Re-register this finalizer. We always re-register because we
+ // can't know until the next collection cycle whether or not the
+ // object is truly unreachable.
+ _Jv_RegisterFinalizer (obj, finalize_referred_to_object);
+}
+
+// This is called when a Reference object is finalized. If there is a
+// Reference pointing to this Reference then that case is handled by
+// finalize_referred_to_object.
+static void
+finalize_reference (jobject ref)
+{
+ JvSynchronize sync (java::lang::ref::Reference::lock);
+ remove_from_hash (ref);
+ // The user might have a subclass of Reference with a finalizer.
+ _Jv_FinalizeObject (ref);
+}
+
+void
+_Jv_RegisterStringFinalizer (jobject str)
+{
+ // This function might be called before any other Reference method,
+ // so we must ensure the class is initialized.
+ _Jv_InitClass (&java::lang::ref::Reference::class$);
+ JvSynchronize sync (java::lang::ref::Reference::lock);
+ // If the object is in our hash table, then we might need to add a
+ // new FINALIZE entry. Otherwise, we just register an ordinary
+ // finalizer.
+ object_list *entry = in_hash (str);
+ if (entry)
+ maybe_add_finalize (entry, str);
+ else
+ _Jv_RegisterFinalizer ((void *) str, _Jv_FinalizeString);
+}
+
+void
+::java::lang::ref::Reference::create (jobject ref)
+{
+ // Nothing says you can't make a Reference with a NULL referent.
+ // But there's nothing to do in such a case.
+ referent = reinterpret_cast<gnu::gcj::RawData *> (ref);
+ copy = referent;
+ if (referent != NULL)
+ {
+ JvSynchronize sync (java::lang::ref::Reference::lock);
+ // `this' is a new Reference object. We register a new
+ // finalizer for pointed-to object and we arrange a special
+ // finalizer for ourselves as well.
+ _Jv_RegisterFinalizer (this, finalize_reference);
+ _Jv_RegisterFinalizer (referent, finalize_referred_to_object);
+ gnu::gcj::RawData **p = &referent;
+ _Jv_GCRegisterDisappearingLink ((jobject *) p);
+ add_to_hash (this);
+ }
+}
+
+::java::lang::Object *
+::java::lang::ref::Reference::get()
+{
+ JvSynchronize sync (lock);
+ return referent;
+}
diff --git a/libjava/java/lang/reflect/AccessibleObject.h b/libjava/java/lang/reflect/AccessibleObject.h
new file mode 100644
index 000000000..d140e300c
--- /dev/null
+++ b/libjava/java/lang/reflect/AccessibleObject.h
@@ -0,0 +1,36 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_AccessibleObject__
+#define __java_lang_reflect_AccessibleObject__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::AccessibleObject : public ::java::lang::Object
+{
+
+public: // actually protected
+ AccessibleObject();
+public:
+ virtual jboolean isAccessible();
+ static void setAccessible(JArray< ::java::lang::reflect::AccessibleObject * > *, jboolean);
+ virtual void setAccessible(jboolean);
+private:
+ static void checkPermission();
+ void secureSetAccessible(jboolean);
+public:
+ virtual ::java::lang::annotation::Annotation * getAnnotation(::java::lang::Class *);
+ virtual JArray< ::java::lang::annotation::Annotation * > * getAnnotations();
+ virtual JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotations();
+ virtual jboolean isAnnotationPresent(::java::lang::Class *);
+public: // actually package-private
+ jboolean __attribute__((aligned(__alignof__( ::java::lang::Object)))) flag;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_AccessibleObject__
diff --git a/libjava/java/lang/reflect/AnnotatedElement.h b/libjava/java/lang/reflect/AnnotatedElement.h
new file mode 100644
index 000000000..5792b75e0
--- /dev/null
+++ b/libjava/java/lang/reflect/AnnotatedElement.h
@@ -0,0 +1,24 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_AnnotatedElement__
+#define __java_lang_reflect_AnnotatedElement__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::AnnotatedElement : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::annotation::Annotation * getAnnotation(::java::lang::Class *) = 0;
+ virtual JArray< ::java::lang::annotation::Annotation * > * getAnnotations() = 0;
+ virtual JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotations() = 0;
+ virtual jboolean isAnnotationPresent(::java::lang::Class *) = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_AnnotatedElement__
diff --git a/libjava/java/lang/reflect/Array.h b/libjava/java/lang/reflect/Array.h
new file mode 100644
index 000000000..48df7d3fa
--- /dev/null
+++ b/libjava/java/lang/reflect/Array.h
@@ -0,0 +1,46 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Array__
+#define __java_lang_reflect_Array__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::Array : public ::java::lang::Object
+{
+
+ Array();
+public:
+ static ::java::lang::Object * newInstance(::java::lang::Class *, jint);
+ static ::java::lang::Object * newInstance(::java::lang::Class *, JArray< jint > *);
+ static jint getLength(::java::lang::Object *);
+ static ::java::lang::Object * get(::java::lang::Object *, jint);
+ static jboolean getBoolean(::java::lang::Object *, jint);
+ static jbyte getByte(::java::lang::Object *, jint);
+ static jchar getChar(::java::lang::Object *, jint);
+ static jshort getShort(::java::lang::Object *, jint);
+ static jint getInt(::java::lang::Object *, jint);
+ static jlong getLong(::java::lang::Object *, jint);
+ static jfloat getFloat(::java::lang::Object *, jint);
+ static jdouble getDouble(::java::lang::Object *, jint);
+private:
+ static ::java::lang::Class * getElementType(::java::lang::Object *, jint);
+ static void set(::java::lang::Object *, jint, ::java::lang::Object *, ::java::lang::Class *);
+public:
+ static void set(::java::lang::Object *, jint, ::java::lang::Object *);
+ static void setBoolean(::java::lang::Object *, jint, jboolean);
+ static void setByte(::java::lang::Object *, jint, jbyte);
+ static void setChar(::java::lang::Object *, jint, jchar);
+ static void setShort(::java::lang::Object *, jint, jshort);
+ static void setInt(::java::lang::Object *, jint, jint);
+ static void setLong(::java::lang::Object *, jint, jlong);
+ static void setFloat(::java::lang::Object *, jint, jfloat);
+ static void setDouble(::java::lang::Object *, jint, jdouble);
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_Array__
diff --git a/libjava/java/lang/reflect/Array.java b/libjava/java/lang/reflect/Array.java
new file mode 100644
index 000000000..639cc0e02
--- /dev/null
+++ b/libjava/java/lang/reflect/Array.java
@@ -0,0 +1,458 @@
+/* java.lang.reflect.Array - manipulate arrays by reflection
+ Copyright (C) 1998, 1999, 2001, 2003, 2005, 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.classpath.Configuration;
+
+/**
+ * Array holds static helper functions that allow you to create and
+ * manipulate arrays by reflection. Operations know how to perform widening
+ * conversions, but throw {@link IllegalArgumentException} if you attempt
+ * a narrowing conversion. Also, when accessing primitive arrays, this
+ * class performs object wrapping and unwrapping as necessary.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type. They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc. These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes. Note also that the shorthand <code>Object[].class</code>
+ * is a convenient way to get array Classes.<p>
+ *
+ * <B>Performance note:</B> This class performs best when it does not have
+ * to convert primitive types. The further along the chain it has to convert,
+ * the worse performance will be. You're best off using the array as whatever
+ * type it already is, and then converting the result. You will do even
+ * worse if you do this and use the generic set() function.
+ *
+ * @author John Keiser
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Per Bothner (bothner@cygnus.com)
+ * @see java.lang.Boolean#TYPE
+ * @see java.lang.Byte#TYPE
+ * @see java.lang.Short#TYPE
+ * @see java.lang.Character#TYPE
+ * @see java.lang.Integer#TYPE
+ * @see java.lang.Long#TYPE
+ * @see java.lang.Float#TYPE
+ * @see java.lang.Double#TYPE
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Array
+{
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javalangreflect");
+ }
+ }
+
+ /**
+ * This class is uninstantiable.
+ */
+ private Array()
+ {
+ }
+
+ /**
+ * Creates a new single-dimensioned array.
+ * @param componentType the type of the array to create
+ * @param length the length of the array to create
+ * @return the created array, cast to an Object
+ * @throws NullPointerException if <code>componentType</code> is null
+ * @throws IllegalArgumentException if <code>componentType</code> is
+ * <code>Void.TYPE</code>
+ * @throws NegativeArraySizeException when length is less than 0
+ * @throws OutOfMemoryError if memory allocation fails
+ */
+ public static native Object newInstance(Class<?> componentType, int length);
+
+ /**
+ * Creates a new multi-dimensioned array. The new array has the same
+ * component type as the argument class, and the number of dimensions
+ * in the new array is the sum of the dimensions of the argument class
+ * and the length of the argument dimensions. Virtual Machine limitations
+ * forbid too many dimensions (usually 255 is the maximum); but even
+ * 50 dimensions of 2 elements in each dimension would exceed your memory
+ * long beforehand!
+ *
+ * @param componentType the type of the array to create.
+ * @param dimensions the dimensions of the array to create. Each element
+ * in <code>dimensions</code> makes another dimension of the new
+ * array. Thus, <code>Array.newInstance(java.lang.Boolean,
+ * new int[]{1,2,3})</code> is the same as
+ * <code>new java.lang.Boolean[1][2][3]</code>
+ * @return the created array, cast to an Object
+ * @throws NullPointerException if componentType or dimension is null
+ * @throws IllegalArgumentException if the the size of
+ * <code>dimensions</code> is 0 or exceeds the maximum number of
+ * array dimensions in the VM; or if componentType is Void.TYPE
+ * @throws NegativeArraySizeException when any of the dimensions is less
+ * than 0
+ * @throws OutOfMemoryError if memory allocation fails
+ */
+ public static native Object newInstance(Class<?> elementType, int[] dimensions);
+
+ /**
+ * Gets the array length.
+ * @param array the array
+ * @return the length of the array
+ * @throws IllegalArgumentException if <code>array</code> is not an array
+ * @throws NullPointerException if <code>array</code> is null
+ */
+ public static native int getLength(Object array);
+
+ /**
+ * Gets an element of an array. Primitive elements will be wrapped in
+ * the corresponding class type.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not an array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #getBoolean(Object, int)
+ * @see #getByte(Object, int)
+ * @see #getChar(Object, int)
+ * @see #getShort(Object, int)
+ * @see #getInt(Object, int)
+ * @see #getLong(Object, int)
+ * @see #getFloat(Object, int)
+ * @see #getDouble(Object, int)
+ */
+ public static native Object get(Object array, int index);
+
+ /**
+ * Gets an element of a boolean array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the boolean element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a boolean
+ * array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native boolean getBoolean(Object array, int index);
+
+ /**
+ * Gets an element of a byte array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the byte element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte
+ * array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native byte getByte(Object array, int index);
+
+ /**
+ * Gets an element of a char array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the char element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a char
+ * array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native char getChar(Object array, int index);
+
+ /**
+ * Gets an element of a short array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the short element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte
+ * or char array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native short getShort(Object array, int index);
+
+ /**
+ * Gets an element of an int array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the int element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte,
+ * char, short, or int array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native int getInt(Object array, int index);
+
+ /**
+ * Gets an element of a long array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the long element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte,
+ * char, short, int, or long array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native long getLong(Object array, int index);
+
+ /**
+ * Gets an element of a float array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the float element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte,
+ * char, short, int, long, or float array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native float getFloat(Object array, int index);
+
+ /**
+ * Gets an element of a double array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the double element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte,
+ * char, short, int, long, float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native double getDouble(Object array, int index);
+
+ private static native Class getElementType(Object array, int index);
+
+ private static native void set(Object array, int index,
+ Object value, Class elType);
+
+ /**
+ * Sets an element of an array. If the array is primitive, then the new
+ * value is unwrapped and widened.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not an array,
+ * or the array is primitive and unwrapping value fails, or the
+ * value is not assignable to the array component type
+ * @throws NullPointerException if array is null, or if array is primitive
+ * and value is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #setBoolean(Object, int, boolean)
+ * @see #setByte(Object, int, byte)
+ * @see #setChar(Object, int, char)
+ * @see #setShort(Object, int, short)
+ * @see #setInt(Object, int, int)
+ * @see #setLong(Object, int, long)
+ * @see #setFloat(Object, int, float)
+ * @see #setDouble(Object, int, double)
+ */
+ public static void set(Object array, int index, Object value)
+ {
+ Class elType = getElementType(array, index);
+ if (! elType.isPrimitive())
+ set(array, index, value, elType);
+ else if (value instanceof Byte)
+ setByte(array, index, ((Byte) value).byteValue());
+ else if (value instanceof Short)
+ setShort(array, index, ((Short) value).shortValue());
+ else if (value instanceof Integer)
+ setInt(array, index, ((Integer) value).intValue());
+ else if (value instanceof Long)
+ setLong(array, index, ((Long) value).longValue());
+ else if (value instanceof Float)
+ setFloat(array, index, ((Float) value).floatValue());
+ else if (value instanceof Double)
+ setDouble(array, index, ((Double) value).doubleValue());
+ else if (value instanceof Character)
+ setChar(array, index, ((Character) value).charValue());
+ else if (value instanceof Boolean)
+ setBoolean(array, index, ((Boolean) value).booleanValue());
+ else
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Sets an element of a boolean array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a boolean
+ * array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setBoolean(Object array, int index, boolean value);
+
+ /**
+ * Sets an element of a byte array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a byte,
+ * short, int, long, float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setByte(Object array, int index, byte value);
+
+ /**
+ * Sets an element of a char array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a char,
+ * int, long, float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setChar(Object array, int index, char value);
+
+ /**
+ * Sets an element of a short array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a short,
+ * int, long, float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setShort(Object array, int index, short value);
+
+ /**
+ * Sets an element of an int array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not an int,
+ * long, float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setInt(Object array, int index, int value);
+
+ /**
+ * Sets an element of a long array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a long,
+ * float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setLong(Object array, int index, long value);
+
+ /**
+ * Sets an element of a float array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a float
+ * or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setFloat(Object array, int index, float value);
+
+ /**
+ * Sets an element of a double array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a double
+ * array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setDouble(Object array, int index, double value);
+}
diff --git a/libjava/java/lang/reflect/Constructor.h b/libjava/java/lang/reflect/Constructor.h
new file mode 100644
index 000000000..5a200bc11
--- /dev/null
+++ b/libjava/java/lang/reflect/Constructor.h
@@ -0,0 +1,65 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Constructor__
+#define __java_lang_reflect_Constructor__
+
+#pragma interface
+
+#include <java/lang/reflect/AccessibleObject.h>
+#include <gcj/array.h>
+
+
+jmethodID _Jv_FromReflectedConstructor (java::lang::reflect::Constructor *);
+jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID, jboolean);
+
+class java::lang::reflect::Constructor : public ::java::lang::reflect::AccessibleObject
+{
+
+ Constructor();
+public:
+ ::java::lang::Class * getDeclaringClass();
+ ::java::lang::String * getName();
+private:
+ jint getModifiersInternal();
+public:
+ jint getModifiers();
+ jboolean isSynthetic();
+ jboolean isVarArgs();
+ JArray< ::java::lang::Class * > * getParameterTypes();
+ JArray< ::java::lang::Class * > * getExceptionTypes();
+ jboolean equals(::java::lang::Object *);
+ jint hashCode();
+ ::java::lang::String * toString();
+public: // actually package-private
+ static void addTypeParameters(::java::lang::StringBuilder *, JArray< ::java::lang::reflect::TypeVariable * > *);
+public:
+ ::java::lang::String * toGenericString();
+ ::java::lang::Object * newInstance(JArray< ::java::lang::Object * > *);
+ JArray< ::java::lang::reflect::TypeVariable * > * getTypeParameters();
+private:
+ ::java::lang::String * getSignature();
+public:
+ JArray< ::java::lang::reflect::Type * > * getGenericExceptionTypes();
+ JArray< ::java::lang::reflect::Type * > * getGenericParameterTypes();
+ ::java::lang::annotation::Annotation * getAnnotation(::java::lang::Class *);
+ JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotations();
+ JArray< JArray< ::java::lang::annotation::Annotation * > * > * getParameterAnnotations();
+private:
+ JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotationsInternal();
+ JArray< JArray< ::java::lang::annotation::Annotation * > * > * getParameterAnnotationsInternal();
+ void getType();
+ static const jint CONSTRUCTOR_MODIFIERS = 7;
+ ::java::lang::Class * __attribute__((aligned(__alignof__( ::java::lang::reflect::AccessibleObject)))) declaringClass;
+ JArray< ::java::lang::Class * > * exception_types;
+ JArray< ::java::lang::Class * > * parameter_types;
+ jint offset;
+public:
+ static ::java::lang::Class class$;
+
+ friend jmethodID (::_Jv_FromReflectedConstructor) (java::lang::reflect::Constructor *);
+ friend jobject (::_Jv_JNI_ToReflectedMethod) (_Jv_JNIEnv *, jclass, jmethodID, jboolean);
+ friend class java::lang::Class;
+};
+
+#endif // __java_lang_reflect_Constructor__
diff --git a/libjava/java/lang/reflect/Constructor.java b/libjava/java/lang/reflect/Constructor.java
new file mode 100644
index 000000000..adebc600a
--- /dev/null
+++ b/libjava/java/lang/reflect/Constructor.java
@@ -0,0 +1,424 @@
+/* java.lang.reflect.Constructor - reflection of Java constructors
+ Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.java.lang.reflect.MethodSignatureParser;
+import java.lang.annotation.Annotation;
+
+/**
+ * The Constructor class represents a constructor of a class. It also allows
+ * dynamic creation of an object, via reflection. Invocation on Constructor
+ * objects knows how to do widening conversions, but throws
+ * {@link IllegalArgumentException} if a narrowing conversion would be
+ * necessary. You can query for information on this Constructor regardless
+ * of location, but construction access may be limited by Java language
+ * access controls. If you can't do it in the compiler, you can't normally
+ * do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type. They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc. These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class. It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Tom Tromey <tromey@redhat.com>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getConstructor(Class[])
+ * @see java.lang.Class#getDeclaredConstructor(Class[])
+ * @see java.lang.Class#getConstructors()
+ * @see java.lang.Class#getDeclaredConstructors()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Constructor<T> extends AccessibleObject
+ implements Member, GenericDeclaration
+{
+ private static final int CONSTRUCTOR_MODIFIERS
+ = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
+
+ /**
+ * This class is uninstantiable except from native code.
+ */
+ private Constructor ()
+ {
+ }
+
+ /**
+ * Gets the class that declared this constructor.
+ * @return the class that declared this member
+ */
+ public Class<T> getDeclaringClass ()
+ {
+ return declaringClass;
+ }
+
+ /**
+ * Gets the name of this constructor (the non-qualified name of the class
+ * it was declared in).
+ * @return the name of this constructor
+ */
+ public String getName()
+ {
+ return declaringClass.getName();
+ }
+
+ /**
+ * Return the raw modifiers for this constructor. In particular
+ * this will include the synthetic and varargs bits.
+ * @return the constructor's modifiers
+ */
+ private native int getModifiersInternal();
+
+ /**
+ * Gets the modifiers this constructor uses. Use the <code>Modifier</code>
+ * class to interpret the values. A constructor can only have a subset of the
+ * following modifiers: public, private, protected.
+ *
+ * @return an integer representing the modifiers to this Member
+ * @see Modifier
+ */
+ public int getModifiers ()
+ {
+ return getModifiersInternal() & CONSTRUCTOR_MODIFIERS;
+ }
+
+ /**
+ * Return true if this constructor is synthetic, false otherwise.
+ * A synthetic member is one which is created by the compiler,
+ * and which does not appear in the user's source code.
+ * @since 1.5
+ */
+ public boolean isSynthetic()
+ {
+ return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ }
+
+ /**
+ * Return true if this is a varargs constructor, that is if
+ * the constructor takes a variable number of arguments.
+ * @since 1.5
+ */
+ public boolean isVarArgs()
+ {
+ return (getModifiersInternal() & Modifier.VARARGS) != 0;
+ }
+
+ /**
+ * Get the parameter list for this constructor, in declaration order. If the
+ * constructor takes no parameters, returns a 0-length array (not null).
+ *
+ * @return a list of the types of the constructor's parameters
+ */
+ public Class<?>[] getParameterTypes ()
+ {
+ if (parameter_types == null)
+ getType ();
+ return (Class<?>[]) parameter_types.clone();
+ }
+
+ /**
+ * Get the exception types this constructor says it throws, in no particular
+ * order. If the constructor has no throws clause, returns a 0-length array
+ * (not null).
+ *
+ * @return a list of the types in the constructor's throws clause
+ */
+ public Class<?>[] getExceptionTypes ()
+ {
+ if (exception_types == null)
+ getType();
+ return (Class<?>[]) exception_types.clone();
+ }
+
+ /**
+ * Compare two objects to see if they are semantically equivalent.
+ * Two Constructors are semantically equivalent if they have the same
+ * declaring class and the same parameter list.
+ *
+ * @param o the object to compare to
+ * @return <code>true</code> if they are equal; <code>false</code> if not.
+ */
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof Constructor))
+ return false;
+ Constructor c = (Constructor) obj;
+ return declaringClass == c.declaringClass && offset == c.offset;
+ }
+
+ /**
+ * Get the hash code for the Constructor. The Constructor hash code is the
+ * hash code of the declaring class's name.
+ *
+ * @return the hash code for the object
+ */
+ public int hashCode ()
+ {
+ return declaringClass.getName().hashCode();
+ }
+
+ /**
+ * Get a String representation of the Constructor. A Constructor's String
+ * representation is "&lt;modifier&gt; &lt;classname&gt;(&lt;paramtypes&gt;)
+ * throws &lt;exceptions&gt;", where everything after ')' is omitted if
+ * there are no exceptions.<br> Example:
+ * <code>public java.io.FileInputStream(java.lang.Runnable)
+ * throws java.io.FileNotFoundException</code>
+ *
+ * @return the String representation of the Constructor
+ */
+ public String toString()
+ {
+ if (parameter_types == null)
+ getType ();
+ StringBuffer b = new StringBuffer ();
+ int mods = getModifiers();
+ if (mods != 0)
+ {
+ Modifier.toString(mods, b);
+ b.append(" ");
+ }
+ Method.appendClassName (b, declaringClass);
+ b.append("(");
+ for (int i = 0; i < parameter_types.length; ++i)
+ {
+ Method.appendClassName (b, parameter_types[i]);
+ if (i < parameter_types.length - 1)
+ b.append(",");
+ }
+ b.append(")");
+ return b.toString();
+ }
+
+ 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();
+ }
+
+ /**
+ * Create a new instance by invoking the constructor. Arguments are
+ * automatically unwrapped and widened, if needed.<p>
+ *
+ * If this class is abstract, you will get an
+ * <code>InstantiationException</code>. If the constructor takes 0
+ * arguments, you may use null or a 0-length array for <code>args</code>.<p>
+ *
+ * If this Constructor enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not create this object in similar compiled code. If the class
+ * is uninitialized, you trigger class initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Then, the constructor is invoked. If it completes normally, the return
+ * value will be the new object. If it completes abruptly, the exception is
+ * wrapped in an <code>InvocationTargetException</code>.
+ *
+ * @param args the arguments to the constructor
+ * @return the newly created object
+ * @throws IllegalAccessException if the constructor could not normally be
+ * called by the Java code (i.e. it is not public)
+ * @throws IllegalArgumentException if the number of arguments is incorrect;
+ * or if the arguments types are wrong even with a widening
+ * conversion
+ * @throws InstantiationException if the class is abstract
+ * @throws InvocationTargetException if the constructor throws an exception
+ * @throws ExceptionInInitializerError if construction triggered class
+ * initialization, which then failed
+ */
+ public native T newInstance (Object... args)
+ throws InstantiationException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException;
+
+ /**
+ * Returns an array of <code>TypeVariable</code> objects that represents
+ * the type variables declared by this constructor, in declaration order.
+ * An array of size zero is returned if this constructor has no type
+ * variables.
+ *
+ * @return the type variables associated with this constructor.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public TypeVariable<Constructor<T>>[] getTypeParameters()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return new TypeVariable[0];
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getTypeParameters();
+ }
+
+ /**
+ * Return the String in the Signature attribute for this constructor. If there
+ * is no Signature attribute, return null.
+ */
+ private native String 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
+ * exceptions.
+ *
+ * @return the exception types declared by this constructor.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericExceptionTypes()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getExceptionTypes();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericExceptionTypes();
+ }
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the parameter list for this constructor, in declaration order.
+ * An array of size zero is returned if this constructor takes no
+ * parameters.
+ *
+ * @return a list of the types of the constructor's parameters
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericParameterTypes()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getParameterTypes();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericParameterTypes();
+ }
+
+ public <T extends Annotation> T getAnnotation(Class<T> annoClass)
+ {
+ Annotation[] annos = getDeclaredAnnotations();
+ for (int i = 0; i < annos.length; ++i)
+ if (annos[i].annotationType() == annoClass)
+ return (T) annos[i];
+ return null;
+ }
+
+ public Annotation[] getDeclaredAnnotations()
+ {
+ Annotation[] result = getDeclaredAnnotationsInternal();
+ if (result == null)
+ result = new Annotation[0];
+ return result;
+ }
+
+ public Annotation[][] getParameterAnnotations()
+ {
+ // FIXME: should check that we have the right number
+ // of parameters ...?
+ Annotation[][] result = getParameterAnnotationsInternal();
+ if (result == null)
+ result = new Annotation[0][0];
+ return result;
+ }
+
+ private native Annotation[] getDeclaredAnnotationsInternal();
+ private native Annotation[][] getParameterAnnotationsInternal();
+
+ // Update cached values from method descriptor in class.
+ private native void getType ();
+
+ // Declaring class.
+ private Class<T> declaringClass;
+
+ // Exception types.
+ private Class[] exception_types;
+ // Parameter types.
+ private Class[] parameter_types;
+
+ // Offset in bytes from the start of declaringClass's methods array.
+ private int offset;
+}
diff --git a/libjava/java/lang/reflect/Field.h b/libjava/java/lang/reflect/Field.h
new file mode 100644
index 000000000..0af95652d
--- /dev/null
+++ b/libjava/java/lang/reflect/Field.h
@@ -0,0 +1,98 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Field__
+#define __java_lang_reflect_Field__
+
+#pragma interface
+
+#include <java/lang/reflect/AccessibleObject.h>
+#include <gcj/array.h>
+
+
+jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);
+jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv*, jclass, jfieldID, jboolean);
+jobject _Jv_getFieldInternal (java::lang::reflect::Field *f, jclass c, jobject o);
+
+class java::lang::reflect::Field : public ::java::lang::reflect::AccessibleObject
+{
+
+public: // actually package-private
+ Field();
+public:
+ ::java::lang::Class * getDeclaringClass();
+ ::java::lang::String * getName();
+private:
+ jint getModifiersInternal();
+public:
+ jint getModifiers();
+ jboolean isSynthetic();
+ jboolean isEnumConstant();
+ ::java::lang::Class * getType();
+ jboolean equals(::java::lang::Object *);
+ jint hashCode();
+ ::java::lang::String * toString();
+ ::java::lang::String * toGenericString();
+ ::java::lang::Object * get(::java::lang::Object *);
+ jboolean getBoolean(::java::lang::Object *);
+ jbyte getByte(::java::lang::Object *);
+ jchar getChar(::java::lang::Object *);
+ jshort getShort(::java::lang::Object *);
+ jint getInt(::java::lang::Object *);
+ jlong getLong(::java::lang::Object *);
+ jfloat getFloat(::java::lang::Object *);
+ jdouble getDouble(::java::lang::Object *);
+private:
+ jboolean getBoolean(::java::lang::Class *, ::java::lang::Object *);
+ jchar getChar(::java::lang::Class *, ::java::lang::Object *);
+ jbyte getByte(::java::lang::Class *, ::java::lang::Object *);
+ jshort getShort(::java::lang::Class *, ::java::lang::Object *);
+ jint getInt(::java::lang::Class *, ::java::lang::Object *);
+ jlong getLong(::java::lang::Class *, ::java::lang::Object *);
+ jfloat getFloat(::java::lang::Class *, ::java::lang::Object *);
+ jdouble getDouble(::java::lang::Class *, ::java::lang::Object *);
+ ::java::lang::Object * get(::java::lang::Class *, ::java::lang::Object *);
+public:
+ void set(::java::lang::Object *, ::java::lang::Object *);
+ void setBoolean(::java::lang::Object *, jboolean);
+ void setByte(::java::lang::Object *, jbyte);
+ void setChar(::java::lang::Object *, jchar);
+ void setShort(::java::lang::Object *, jshort);
+ void setInt(::java::lang::Object *, jint);
+ void setLong(::java::lang::Object *, jlong);
+ void setFloat(::java::lang::Object *, jfloat);
+ void setDouble(::java::lang::Object *, jdouble);
+ ::java::lang::reflect::Type * getGenericType();
+ ::java::lang::annotation::Annotation * getAnnotation(::java::lang::Class *);
+ JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotations();
+private:
+ JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotationsInternal();
+ ::java::lang::String * getSignature();
+public: // actually package-private
+ void setByte(::java::lang::Class *, ::java::lang::Object *, jbyte, jboolean);
+ void setShort(::java::lang::Class *, ::java::lang::Object *, jshort, jboolean);
+ void setInt(::java::lang::Class *, ::java::lang::Object *, jint, jboolean);
+ void setLong(::java::lang::Class *, ::java::lang::Object *, jlong, jboolean);
+ void setFloat(::java::lang::Class *, ::java::lang::Object *, jfloat, jboolean);
+ void setDouble(::java::lang::Class *, ::java::lang::Object *, jdouble, jboolean);
+ void setChar(::java::lang::Class *, ::java::lang::Object *, jchar, jboolean);
+ void setBoolean(::java::lang::Class *, ::java::lang::Object *, jboolean, jboolean);
+ void set(::java::lang::Class *, ::java::lang::Object *, ::java::lang::Object *, ::java::lang::Class *, jboolean);
+private:
+ void set(::java::lang::Class *, ::java::lang::Object *, ::java::lang::Object *);
+ ::java::lang::Class * __attribute__((aligned(__alignof__( ::java::lang::reflect::AccessibleObject)))) declaringClass;
+ ::java::lang::String * name;
+ jint offset;
+ ::java::lang::Class * type;
+public: // actually package-private
+ static const jint FIELD_MODIFIERS = 223;
+public:
+ static ::java::lang::Class class$;
+
+ friend jfieldID (::_Jv_FromReflectedField) (java::lang::reflect::Field *);
+ friend jobject (::_Jv_JNI_ToReflectedField) (_Jv_JNIEnv*, jclass, jfieldID, jboolean);
+ friend class java::lang::Class;
+ friend jobject (::_Jv_getFieldInternal) (java::lang::reflect::Field *f, jclass c, jobject o);
+};
+
+#endif // __java_lang_reflect_Field__
diff --git a/libjava/java/lang/reflect/Field.java b/libjava/java/lang/reflect/Field.java
new file mode 100644
index 000000000..61db14df5
--- /dev/null
+++ b/libjava/java/lang/reflect/Field.java
@@ -0,0 +1,817 @@
+/* java.lang.reflect.Field - reflection of Java fields
+ Copyright (C) 1998, 2001, 2005, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.java.lang.ClassHelper;
+
+import gnu.java.lang.reflect.FieldSignatureParser;
+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>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type. They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc. These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class. It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Per Bothner <bothner@cygnus.com>
+ * @see Member
+ * @see Class
+ * @see Class#getField(String)
+ * @see Class#getDeclaredField(String)
+ * @see Class#getFields()
+ * @see Class#getDeclaredFields()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Field
+ extends AccessibleObject implements Member
+{
+ private Class declaringClass;
+ private String name;
+
+ // Offset in bytes from the start of declaringClass's fields array.
+ private int offset;
+
+ // The Class (or primitive TYPE) of this field.
+ private Class type;
+
+ static final int FIELD_MODIFIERS
+ = Modifier.FINAL | Modifier.PRIVATE | Modifier.PROTECTED
+ | Modifier.PUBLIC | Modifier.STATIC | Modifier.TRANSIENT
+ | Modifier.VOLATILE;
+
+ // This is instantiated by Class sometimes, but it uses C++ and
+ // avoids the Java protection check.
+ Field ()
+ {
+ }
+
+ /**
+ * Gets the class that declared this field, or the class where this field
+ * is a non-inherited member.
+ * @return the class that declared this member
+ */
+ public Class<?> getDeclaringClass()
+ {
+ return declaringClass;
+ }
+
+ /**
+ * Gets the name of this field.
+ * @return the name of this field
+ */
+ public native String getName();
+
+ /**
+ * Return the raw modifiers for this field.
+ * @return the field's modifiers
+ */
+ private native int getModifiersInternal();
+
+ /**
+ * Gets the modifiers this field uses. Use the <code>Modifier</code>
+ * class to interpret the values. A field can only have a subset of the
+ * following modifiers: public, private, protected, static, final,
+ * transient, and volatile.
+ *
+ * @return an integer representing the modifiers to this Member
+ * @see Modifier
+ */
+ public int getModifiers()
+ {
+ return getModifiersInternal() & FIELD_MODIFIERS;
+ }
+
+ /**
+ * Return true if this field is synthetic, false otherwise.
+ * @since 1.5
+ */
+ public boolean isSynthetic()
+ {
+ return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ }
+
+ /**
+ * Return true if this field represents an enum constant,
+ * false otherwise.
+ * @since 1.5
+ */
+ public boolean isEnumConstant()
+ {
+ return (getModifiersInternal() & Modifier.ENUM) != 0;
+ }
+
+ /**
+ * Gets the type of this field.
+ * @return the type of this field
+ */
+ public native Class<?> getType();
+
+ /**
+ * Compare two objects to see if they are semantically equivalent.
+ * Two Fields are semantically equivalent if they have the same declaring
+ * class, name, and type. Since you can't creat a Field except through
+ * the VM, this is just the == relation.
+ *
+ * @param o the object to compare to
+ * @return <code>true</code> if they are equal; <code>false</code> if not
+ */
+ public boolean equals (Object fld)
+ {
+ if (! (fld instanceof Field))
+ return false;
+ Field f = (Field) fld;
+ return declaringClass == f.declaringClass && offset == f.offset;
+ }
+
+ /**
+ * Get the hash code for the Field. The Field hash code is the hash code
+ * of its name XOR'd with the hash code of its class name.
+ *
+ * @return the hash code for the object.
+ */
+ public int hashCode()
+ {
+ return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
+ }
+
+ /**
+ * Get a String representation of the Field. A Field's String
+ * representation is "&lt;modifiers&gt; &lt;type&gt;
+ * &lt;class&gt;.&lt;fieldname&gt;".<br> Example:
+ * <code>public transient boolean gnu.parse.Parser.parseComplete</code>
+ *
+ * @return the String representation of the Field
+ */
+ public String toString ()
+ {
+ StringBuffer sbuf = new StringBuffer ();
+ int mods = getModifiers();
+ if (mods != 0)
+ {
+ Modifier.toString(mods, sbuf);
+ sbuf.append(' ');
+ }
+ Method.appendClassName (sbuf, getType ());
+ sbuf.append(' ');
+ Method.appendClassName (sbuf, getDeclaringClass());
+ sbuf.append('.');
+ sbuf.append(getName());
+ return sbuf.toString();
+ }
+
+ public String toGenericString()
+ {
+ StringBuilder sb = new StringBuilder(64);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ sb.append(getGenericType()).append(' ');
+ sb.append(getDeclaringClass().getName()).append('.');
+ sb.append(getName());
+ return sb.toString();
+ }
+
+ /**
+ * Get the value of this Field. If it is primitive, it will be wrapped
+ * in the appropriate wrapper type (boolean = java.lang.Boolean).<p>
+ *
+ * If the field is static, <code>o</code> will be ignored. Otherwise, if
+ * <code>o</code> is null, you get a <code>NullPointerException</code>,
+ * and if it is incompatible with the declaring class of the field, you
+ * get an <code>IllegalArgumentException</code>.<p>
+ *
+ * Next, if this Field enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not access this field in similar compiled code. If the field
+ * is static, and its class is uninitialized, you trigger class
+ * initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Finally, the field is accessed, and primitives are wrapped (but not
+ * necessarily in new objects). This method accesses the field of the
+ * declaring class, even if the instance passed in belongs to a subclass
+ * which declares another field to hide this one.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if <code>o</code> is not an instance of
+ * the class or interface declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #getBoolean(Object)
+ * @see #getByte(Object)
+ * @see #getChar(Object)
+ * @see #getShort(Object)
+ * @see #getInt(Object)
+ * @see #getLong(Object)
+ * @see #getFloat(Object)
+ * @see #getDouble(Object)
+ */
+ public Object get(Object obj)
+ throws IllegalAccessException
+ {
+ return get(null, obj);
+ }
+
+ /**
+ * Get the value of this boolean Field. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a boolean field of
+ * <code>o</code>, or if <code>o</code> is not an instance of the
+ * declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public boolean getBoolean(Object obj)
+ throws IllegalAccessException
+ {
+ return getBoolean(null, obj);
+ }
+
+ /**
+ * Get the value of this byte Field. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte field of
+ * <code>o</code>, or if <code>o</code> is not an instance of the
+ * declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public byte getByte(Object obj)
+ throws IllegalAccessException
+ {
+ return getByte(null, obj);
+ }
+
+ /**
+ * Get the value of this Field as a char. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a char field of
+ * <code>o</code>, or if <code>o</code> is not an instance
+ * of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public char getChar(Object obj)
+ throws IllegalAccessException
+ {
+ return getChar(null, obj);
+ }
+
+ /**
+ * Get the value of this Field as a short. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte or short
+ * field of <code>o</code>, or if <code>o</code> is not an instance
+ * of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public short getShort(Object obj)
+ throws IllegalAccessException
+ {
+ return getShort(null, obj);
+ }
+
+ /**
+ * Get the value of this Field as an int. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, or
+ * int field of <code>o</code>, or if <code>o</code> is not an
+ * instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public int getInt(Object obj)
+ throws IllegalAccessException
+ {
+ return getInt(null, obj);
+ }
+
+ /**
+ * Get the value of this Field as a long. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * or long field of <code>o</code>, or if <code>o</code> is not an
+ * instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public long getLong(Object obj)
+ throws IllegalAccessException
+ {
+ return getLong(null, obj);
+ }
+
+ /**
+ * Get the value of this Field as a float. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * long, or float field of <code>o</code>, or if <code>o</code> is
+ * not an instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public float getFloat(Object obj)
+ throws IllegalAccessException
+ {
+ return getFloat(null, obj);
+ }
+
+ /**
+ * Get the value of this Field as a double. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * long, float, or double field of <code>o</code>, or if
+ * <code>o</code> is not an instance of the declaring class of this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public double getDouble(Object obj)
+ throws IllegalAccessException
+ {
+ return getDouble(null, obj);
+ }
+
+ private native boolean getBoolean (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native char getChar (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native byte getByte (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native short getShort (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native int getInt (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native long getLong (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native float getFloat (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native double getDouble (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native Object get (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Set the value of this Field. If it is a primitive field, the value
+ * will be unwrapped from the passed object (boolean = java.lang.Boolean).<p>
+ *
+ * If the field is static, <code>o</code> will be ignored. Otherwise, if
+ * <code>o</code> is null, you get a <code>NullPointerException</code>,
+ * and if it is incompatible with the declaring class of the field, you
+ * get an <code>IllegalArgumentException</code>.<p>
+ *
+ * Next, if this Field enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not access this field in similar compiled code. This also
+ * occurs whether or not there is access control if the field is final.
+ * If the field is primitive, and unwrapping your argument fails, you will
+ * get an <code>IllegalArgumentException</code>; likewise, this error
+ * happens if <code>value</code> cannot be cast to the correct object type.
+ * If the field is static, and its class is uninitialized, you trigger class
+ * initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Finally, the field is set with the widened value. This method accesses
+ * the field of the declaring class, even if the instance passed in belongs
+ * to a subclass which declares another field to hide this one.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if <code>value</code> cannot be
+ * converted by a widening conversion to the underlying type of
+ * the Field, or if <code>o</code> is not an instance of the class
+ * declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #setBoolean(Object, boolean)
+ * @see #setByte(Object, byte)
+ * @see #setChar(Object, char)
+ * @see #setShort(Object, short)
+ * @see #setInt(Object, int)
+ * @see #setLong(Object, long)
+ * @see #setFloat(Object, float)
+ * @see #setDouble(Object, double)
+ */
+ public void set(Object object, Object value)
+ throws IllegalAccessException
+ {
+ set(null, object, value);
+ }
+
+ /**
+ * Set this boolean Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a boolean field, or if
+ * <code>o</code> is not an instance of the class declaring this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setBoolean(Object obj, boolean b)
+ throws IllegalAccessException
+ {
+ setBoolean(null, obj, b, true);
+ }
+
+ /**
+ * Set this byte Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, int, long,
+ * float, or double field, or if <code>o</code> is not an instance
+ * of the class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setByte(Object obj, byte b)
+ throws IllegalAccessException
+ {
+ setByte(null, obj, b, true);
+ }
+
+ /**
+ * Set this char Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a char, int, long,
+ * float, or double field, or if <code>o</code> is not an instance
+ * of the class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setChar(Object obj, char c)
+ throws IllegalAccessException
+ {
+ setChar(null, obj, c, true);
+ }
+
+ /**
+ * Set this short Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a short, int, long,
+ * float, or double field, or if <code>o</code> is not an instance
+ * of the class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setShort(Object obj, short s)
+ throws IllegalAccessException
+ {
+ setShort(null, obj, s, true);
+ }
+
+ /**
+ * Set this int Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not an int, long, float, or
+ * double field, or if <code>o</code> is not an instance of the
+ * class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setInt(Object obj, int i)
+ throws IllegalAccessException
+ {
+ setInt(null, obj, i, true);
+ }
+
+ /**
+ * Set this long Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a long, float, or double
+ * field, or if <code>o</code> is not an instance of the class
+ * declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setLong(Object obj, long l)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setLong(null, obj, l, true);
+ }
+
+ /**
+ * Set this float Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a float or long field, or
+ * if <code>o</code> is not an instance of the class declaring this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setFloat(Object obj, float f)
+ throws IllegalAccessException
+ {
+ setFloat(null, obj, f, true);
+ }
+
+ /**
+ * Set this double Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a double field, or if
+ * <code>o</code> is not an instance of the class declaring this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setDouble(Object obj, double d)
+ throws IllegalAccessException
+ {
+ setDouble(null, obj, d, true);
+ }
+
+ /**
+ * Return the generic type of the field. If the field type is not a generic
+ * type, the method returns the same as <code>getType()</code>.
+ *
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type getGenericType()
+ {
+ String signature = getSignature();
+ if (signature == null)
+ return getType();
+ FieldSignatureParser p = new FieldSignatureParser(getDeclaringClass(),
+ signature);
+ return p.getFieldType();
+ }
+
+ public <T extends Annotation> T getAnnotation(Class<T> annoClass)
+ {
+ Annotation[] annos = getDeclaredAnnotations();
+ for (int i = 0; i < annos.length; ++i)
+ if (annos[i].annotationType() == annoClass)
+ return (T) annos[i];
+ return null;
+ }
+
+ public Annotation[] getDeclaredAnnotations()
+ {
+ Annotation[] result = getDeclaredAnnotationsInternal();
+ if (result == null)
+ result = new Annotation[0];
+ return result;
+ }
+
+ private native Annotation[] getDeclaredAnnotationsInternal();
+
+ /**
+ * Return the String in the Signature attribute for this field. If there
+ * is no Signature attribute, return null.
+ */
+ private native String getSignature();
+
+ native void setByte (Class caller, Object obj, byte b, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setShort (Class caller, Object obj, short s, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setInt (Class caller, Object obj, int i, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setLong (Class caller, Object obj, long l, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setFloat (Class caller, Object obj, float f, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setDouble (Class caller, Object obj, double d,
+ boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setChar (Class caller, Object obj, char c, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setBoolean (Class caller, Object obj, boolean b,
+ boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void set (Class caller, Object obj, Object val, Class type,
+ boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private void set (Class caller, Object object, Object value)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ Class type = getType();
+ if (! type.isPrimitive())
+ set(caller, object, value, type, true);
+ else if (value instanceof Byte)
+ setByte(caller, object, ((Byte) value).byteValue(), true);
+ else if (value instanceof Short)
+ setShort (caller, object, ((Short) value).shortValue(), true);
+ else if (value instanceof Integer)
+ setInt(caller, object, ((Integer) value).intValue(), true);
+ else if (value instanceof Long)
+ setLong(caller, object, ((Long) value).longValue(), true);
+ else if (value instanceof Float)
+ setFloat(caller, object, ((Float) value).floatValue(), true);
+ else if (value instanceof Double)
+ setDouble(caller, object, ((Double) value).doubleValue(), true);
+ else if (value instanceof Character)
+ setChar(caller, object, ((Character) value).charValue(), true);
+ else if (value instanceof Boolean)
+ setBoolean(caller, object, ((Boolean) value).booleanValue(), true);
+ else
+ throw new IllegalArgumentException();
+ }
+}
diff --git a/libjava/java/lang/reflect/GenericArrayType.h b/libjava/java/lang/reflect/GenericArrayType.h
new file mode 100644
index 000000000..cdeb0b2a3
--- /dev/null
+++ b/libjava/java/lang/reflect/GenericArrayType.h
@@ -0,0 +1,19 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_GenericArrayType__
+#define __java_lang_reflect_GenericArrayType__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::reflect::GenericArrayType : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::reflect::Type * getGenericComponentType() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_GenericArrayType__
diff --git a/libjava/java/lang/reflect/GenericDeclaration.h b/libjava/java/lang/reflect/GenericDeclaration.h
new file mode 100644
index 000000000..5c484ea96
--- /dev/null
+++ b/libjava/java/lang/reflect/GenericDeclaration.h
@@ -0,0 +1,21 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_GenericDeclaration__
+#define __java_lang_reflect_GenericDeclaration__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::GenericDeclaration : public ::java::lang::Object
+{
+
+public:
+ virtual JArray< ::java::lang::reflect::TypeVariable * > * getTypeParameters() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_GenericDeclaration__
diff --git a/libjava/java/lang/reflect/GenericSignatureFormatError.h b/libjava/java/lang/reflect/GenericSignatureFormatError.h
new file mode 100644
index 000000000..c46c9264a
--- /dev/null
+++ b/libjava/java/lang/reflect/GenericSignatureFormatError.h
@@ -0,0 +1,22 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_GenericSignatureFormatError__
+#define __java_lang_reflect_GenericSignatureFormatError__
+
+#pragma interface
+
+#include <java/lang/ClassFormatError.h>
+
+class java::lang::reflect::GenericSignatureFormatError : public ::java::lang::ClassFormatError
+{
+
+public:
+ GenericSignatureFormatError();
+private:
+ static const jlong serialVersionUID = 6709919147137911034LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_GenericSignatureFormatError__
diff --git a/libjava/java/lang/reflect/InvocationHandler.h b/libjava/java/lang/reflect/InvocationHandler.h
new file mode 100644
index 000000000..722195321
--- /dev/null
+++ b/libjava/java/lang/reflect/InvocationHandler.h
@@ -0,0 +1,21 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_InvocationHandler__
+#define __java_lang_reflect_InvocationHandler__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::InvocationHandler : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::Object * invoke(::java::lang::Object *, ::java::lang::reflect::Method *, JArray< ::java::lang::Object * > *) = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_InvocationHandler__
diff --git a/libjava/java/lang/reflect/InvocationTargetException.h b/libjava/java/lang/reflect/InvocationTargetException.h
new file mode 100644
index 000000000..37e229c29
--- /dev/null
+++ b/libjava/java/lang/reflect/InvocationTargetException.h
@@ -0,0 +1,28 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_InvocationTargetException__
+#define __java_lang_reflect_InvocationTargetException__
+
+#pragma interface
+
+#include <java/lang/Exception.h>
+
+class java::lang::reflect::InvocationTargetException : public ::java::lang::Exception
+{
+
+public: // actually protected
+ InvocationTargetException();
+public:
+ InvocationTargetException(::java::lang::Throwable *);
+ InvocationTargetException(::java::lang::Throwable *, ::java::lang::String *);
+ virtual ::java::lang::Throwable * getTargetException();
+ virtual ::java::lang::Throwable * getCause();
+private:
+ static const jlong serialVersionUID = 4085088731926701167LL;
+ ::java::lang::Throwable * __attribute__((aligned(__alignof__( ::java::lang::Exception)))) target;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_InvocationTargetException__
diff --git a/libjava/java/lang/reflect/MalformedParameterizedTypeException.h b/libjava/java/lang/reflect/MalformedParameterizedTypeException.h
new file mode 100644
index 000000000..a48f669c0
--- /dev/null
+++ b/libjava/java/lang/reflect/MalformedParameterizedTypeException.h
@@ -0,0 +1,22 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_MalformedParameterizedTypeException__
+#define __java_lang_reflect_MalformedParameterizedTypeException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::reflect::MalformedParameterizedTypeException : public ::java::lang::RuntimeException
+{
+
+public:
+ MalformedParameterizedTypeException();
+private:
+ static const jlong serialVersionUID = -5696557788586220964LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_MalformedParameterizedTypeException__
diff --git a/libjava/java/lang/reflect/Member.h b/libjava/java/lang/reflect/Member.h
new file mode 100644
index 000000000..9e3522be0
--- /dev/null
+++ b/libjava/java/lang/reflect/Member.h
@@ -0,0 +1,24 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Member__
+#define __java_lang_reflect_Member__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::reflect::Member : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::Class * getDeclaringClass() = 0;
+ virtual ::java::lang::String * getName() = 0;
+ virtual jint getModifiers() = 0;
+ virtual jboolean isSynthetic() = 0;
+ static const jint DECLARED = 1;
+ static const jint PUBLIC = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_Member__
diff --git a/libjava/java/lang/reflect/Method.h b/libjava/java/lang/reflect/Method.h
new file mode 100644
index 000000000..8a843d5d1
--- /dev/null
+++ b/libjava/java/lang/reflect/Method.h
@@ -0,0 +1,84 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Method__
+#define __java_lang_reflect_Method__
+
+#pragma interface
+
+#include <java/lang/reflect/AccessibleObject.h>
+#include <gcj/array.h>
+
+
+jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);
+jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID, jboolean);
+::java::lang::reflect::Method *_Jv_GetReflectedMethod (jclass, _Jv_Utf8Const*, _Jv_Utf8Const*);
+
+class java::lang::reflect::Method : public ::java::lang::reflect::AccessibleObject
+{
+
+ Method();
+public:
+ ::java::lang::Class * getDeclaringClass();
+ ::java::lang::String * getName();
+private:
+ jint getModifiersInternal();
+public:
+ jint getModifiers();
+ jboolean isBridge();
+ jboolean isSynthetic();
+ jboolean isVarArgs();
+ ::java::lang::Class * getReturnType();
+ JArray< ::java::lang::Class * > * getParameterTypes();
+public: // actually package-private
+ JArray< ::java::lang::Class * > * internalGetParameterTypes();
+public:
+ JArray< ::java::lang::Class * > * getExceptionTypes();
+public: // actually package-private
+ JArray< ::java::lang::Class * > * internalGetExceptionTypes();
+public:
+ jboolean equals(::java::lang::Object *);
+ jint hashCode();
+ ::java::lang::String * toString();
+ ::java::lang::String * toGenericString();
+ ::java::lang::Object * invoke(::java::lang::Object *, JArray< ::java::lang::Object * > *);
+ JArray< ::java::lang::reflect::TypeVariable * > * getTypeParameters();
+private:
+ ::java::lang::String * getSignature();
+public:
+ JArray< ::java::lang::reflect::Type * > * getGenericExceptionTypes();
+ JArray< ::java::lang::reflect::Type * > * getGenericParameterTypes();
+ ::java::lang::reflect::Type * getGenericReturnType();
+ ::java::lang::Object * getDefaultValue();
+ ::java::lang::annotation::Annotation * getAnnotation(::java::lang::Class *);
+ JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotations();
+ JArray< JArray< ::java::lang::annotation::Annotation * > * > * getParameterAnnotations();
+private:
+ JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotationsInternal();
+ JArray< JArray< ::java::lang::annotation::Annotation * > * > * getParameterAnnotationsInternal();
+ void getType();
+public: // actually package-private
+ static void appendClassName(::java::lang::StringBuffer *, ::java::lang::Class *);
+ static const jint METHOD_MODIFIERS = 3391;
+private:
+ ::java::lang::Class * __attribute__((aligned(__alignof__( ::java::lang::reflect::AccessibleObject)))) declaringClass;
+public: // actually package-private
+ JArray< ::java::lang::Class * > * exception_types;
+private:
+ ::java::lang::String * name;
+public: // actually package-private
+ JArray< ::java::lang::Class * > * parameter_types;
+ ::java::lang::Class * return_type;
+private:
+ jint offset;
+public:
+ static ::java::lang::Class class$;
+
+ friend jmethodID (::_Jv_FromReflectedMethod) (java::lang::reflect::Method *);
+ friend jobject (::_Jv_JNI_ToReflectedMethod) (_Jv_JNIEnv *, jclass, jmethodID, jboolean);
+ friend class java::lang::Class;
+ friend class java::io::ObjectInputStream;
+ friend java::lang::reflect::Method* ::_Jv_GetReflectedMethod (jclass, _Jv_Utf8Const*, _Jv_Utf8Const*);
+};
+
+#endif // __java_lang_reflect_Method__
diff --git a/libjava/java/lang/reflect/Method.java b/libjava/java/lang/reflect/Method.java
new file mode 100644
index 000000000..878210abb
--- /dev/null
+++ b/libjava/java/lang/reflect/Method.java
@@ -0,0 +1,501 @@
+// Method.java - Represent method of class or interface.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006, 2007 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang.reflect;
+
+import gnu.gcj.RawData;
+import gnu.java.lang.reflect.MethodSignatureParser;
+import java.lang.annotation.Annotation;
+
+/**
+ * The Method class represents a member method of a class. It also allows
+ * dynamic invocation, via reflection. This works for both static and
+ * instance methods. Invocation on Method objects knows how to do
+ * widening conversions, but throws {@link IllegalArgumentException} if
+ * a narrowing conversion would be necessary. You can query for information
+ * on this Method regardless of location, but invocation access may be limited
+ * by Java language access controls. If you can't do it in the compiler, you
+ * can't normally do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type. They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc. These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class. It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Tom Tromey <tromey@redhat.com>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getMethod(String,Class[])
+ * @see java.lang.Class#getDeclaredMethod(String,Class[])
+ * @see java.lang.Class#getMethods()
+ * @see java.lang.Class#getDeclaredMethods()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Method
+ extends AccessibleObject implements Member, GenericDeclaration
+{
+ static final int METHOD_MODIFIERS
+ = Modifier.ABSTRACT | Modifier.FINAL | Modifier.NATIVE
+ | Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC
+ | Modifier.STATIC | Modifier.STRICT | Modifier.SYNCHRONIZED;
+
+ /**
+ * This class is uninstantiable.
+ */
+ private Method ()
+ {
+ }
+
+ /**
+ * Gets the class that declared this method, or the class where this method
+ * is a non-inherited member.
+ * @return the class that declared this member
+ */
+ public Class<?> getDeclaringClass()
+ {
+ return declaringClass;
+ }
+
+ /**
+ * Gets the name of this method.
+ * @return the name of this method
+ */
+ public native String getName ();
+
+ /**
+ * Return the raw modifiers for this method.
+ * @return the method's modifiers
+ */
+ private native int getModifiersInternal();
+
+ /**
+ * Gets the modifiers this method uses. Use the <code>Modifier</code>
+ * class to interpret the values. A method can only have a subset of the
+ * following modifiers: public, private, protected, abstract, static,
+ * final, synchronized, native, and strictfp.
+ *
+ * @return an integer representing the modifiers to this Member
+ * @see Modifier
+ */
+ public int getModifiers()
+ {
+ return getModifiersInternal() & METHOD_MODIFIERS;
+ }
+
+ /**
+ * Return true if this method is a bridge method. A bridge method
+ * is generated by the compiler in some situations involving
+ * generics and inheritance.
+ * @since 1.5
+ */
+ public boolean isBridge()
+ {
+ return (getModifiersInternal() & Modifier.BRIDGE) != 0;
+ }
+
+ /**
+ * Return true if this method is synthetic, false otherwise.
+ * @since 1.5
+ */
+ public boolean isSynthetic()
+ {
+ return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ }
+
+ /**
+ * Return true if this is a varargs method, that is if
+ * the method takes a variable number of arguments.
+ * @since 1.5
+ */
+ public boolean isVarArgs()
+ {
+ return (getModifiersInternal() & Modifier.VARARGS) != 0;
+ }
+
+ /**
+ * Gets the return type of this method.
+ * @return the type of this method
+ */
+ public Class<?> getReturnType ()
+ {
+ if (return_type == null)
+ getType();
+ return return_type;
+ }
+
+ /**
+ * Get the parameter list for this method, in declaration order. If the
+ * method takes no parameters, returns a 0-length array (not null).
+ *
+ * @return a list of the types of the method's parameters
+ */
+ public Class<?>[] getParameterTypes ()
+ {
+ if (parameter_types == null)
+ getType();
+ return (Class<?>[]) parameter_types.clone();
+ }
+
+ // Just like getParameterTypes, but don't clone the array.
+ // Package private for use by VMProxy.
+ final Class<?>[] internalGetParameterTypes ()
+ {
+ if (parameter_types == null)
+ getType();
+ return (Class<?>[]) parameter_types;
+ }
+
+ /**
+ * Get the exception types this method says it throws, in no particular
+ * order. If the method has no throws clause, returns a 0-length array
+ * (not null).
+ *
+ * @return a list of the types in the method's throws clause
+ */
+ public Class<?>[] getExceptionTypes ()
+ {
+ if (exception_types == null)
+ getType();
+ return (Class<?>[]) exception_types.clone();
+ }
+
+ // Just like getExceptionTypes, but don't clone the array.
+ // Package private for use by VMProxy.
+ final Class<?>[] internalGetExceptionTypes ()
+ {
+ if (exception_types == null)
+ getType();
+ return (Class<?>[]) exception_types;
+ }
+
+ /**
+ * Compare two objects to see if they are semantically equivalent.
+ * Two Methods are semantically equivalent if they have the same declaring
+ * class, name, and parameter list. This ignores different exception
+ * clauses or return types.
+ *
+ * @param o the object to compare to
+ * @return <code>true</code> if they are equal; <code>false</code> if not
+ */
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof Method))
+ return false;
+ Method m = (Method) obj;
+ return declaringClass == m.declaringClass && offset == m.offset;
+ }
+
+ /**
+ * Get the hash code for the Method. The Method hash code is the hash code
+ * of its name XOR'd with the hash code of its class name.
+ *
+ * @return the hash code for the object
+ */
+ public int hashCode()
+ {
+ return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
+ }
+
+ /**
+ * Get a String representation of the Method. A Method's String
+ * representation is "&lt;modifiers&gt; &lt;returntype&gt;
+ * &lt;methodname&gt;(&lt;paramtypes&gt;) throws &lt;exceptions&gt;", where
+ * everything after ')' is omitted if there are no exceptions.<br> Example:
+ * <code>public static int run(java.lang.Runnable,int)</code>
+ *
+ * @return the String representation of the Method
+ */
+ public String toString()
+ {
+ if (parameter_types == null)
+ getType ();
+
+ StringBuffer b = new StringBuffer ();
+ int mods = getModifiers();
+ if (mods != 0)
+ {
+ Modifier.toString(mods, b);
+ b.append(" ");
+ }
+ appendClassName (b, return_type);
+ b.append(" ");
+ appendClassName (b, declaringClass);
+ b.append(".");
+ b.append(getName());
+ b.append("(");
+ for (int i = 0; i < parameter_types.length; ++i)
+ {
+ appendClassName (b, parameter_types[i]);
+ if (i < parameter_types.length - 1)
+ b.append(",");
+ }
+ b.append(")");
+ if (exception_types.length > 0)
+ {
+ b.append(" throws ");
+ for (int i = 0; i < exception_types.length; ++i)
+ {
+ appendClassName (b, exception_types[i]);
+ if (i < exception_types.length - 1)
+ b.append(",");
+ }
+ }
+ return b.toString();
+ }
+
+ public String toGenericString()
+ {
+ // 128 is a reasonable buffer initial size for constructor
+ StringBuilder sb = new StringBuilder(128);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ Constructor.addTypeParameters(sb, getTypeParameters());
+ sb.append(getGenericReturnType()).append(' ');
+ sb.append(getDeclaringClass().getName()).append('.');
+ sb.append(getName()).append('(');
+ Type[] types = getGenericParameterTypes();
+ if (types.length > 0)
+ {
+ sb.append(types[0]);
+ for (int i = 1; i < types.length; i++)
+ sb.append(',').append(types[i]);
+ }
+ sb.append(')');
+ types = getGenericExceptionTypes();
+ if (types.length > 0)
+ {
+ sb.append(" throws ").append(types[0]);
+ for (int i = 1; i < types.length; i++)
+ sb.append(',').append(types[i]);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Invoke the method. Arguments are automatically unwrapped and widened,
+ * and the result is automatically wrapped, if needed.<p>
+ *
+ * If the method is static, <code>o</code> will be ignored. Otherwise,
+ * the method uses dynamic lookup as described in JLS 15.12.4.4. You cannot
+ * mimic the behavior of nonvirtual lookup (as in super.foo()). This means
+ * you will get a <code>NullPointerException</code> if <code>o</code> is
+ * null, and an <code>IllegalArgumentException</code> if it is incompatible
+ * with the declaring class of the method. If the method takes 0 arguments,
+ * you may use null or a 0-length array for <code>args</code>.<p>
+ *
+ * Next, if this Method enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not acces this method in similar compiled code. If the method
+ * is static, and its class is uninitialized, you trigger class
+ * initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Finally, the method is invoked. If it completes normally, the return value
+ * will be null for a void method, a wrapped object for a primitive return
+ * method, or the actual return of an Object method. If it completes
+ * abruptly, the exception is wrapped in an
+ * <code>InvocationTargetException</code>.
+ *
+ * @param o the object to invoke the method on
+ * @param args the arguments to the method
+ * @return the return value of the method, wrapped in the appropriate
+ * wrapper if it is primitive
+ * @throws IllegalAccessException if the method could not normally be called
+ * by the Java code (i.e. it is not public)
+ * @throws IllegalArgumentException if the number of arguments is incorrect;
+ * if the arguments types are wrong even with a widening conversion;
+ * or if <code>o</code> is not an instance of the class or interface
+ * declaring this method
+ * @throws InvocationTargetException if the method throws an exception
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static method triggered
+ * class initialization, which then failed
+ */
+ public native Object invoke (Object obj, Object... args)
+ throws IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException;
+
+ /**
+ * Returns an array of <code>TypeVariable</code> objects that represents
+ * the type variables declared by this constructor, in declaration order.
+ * An array of size zero is returned if this class has no type
+ * variables.
+ *
+ * @return the type variables associated with this class.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public TypeVariable<Method>[] getTypeParameters()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return new TypeVariable[0];
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getTypeParameters();
+ }
+
+ /**
+ * Return the String in the Signature attribute for this method. If there
+ * is no Signature attribute, return null.
+ */
+ private native String getSignature();
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the exception types declared by this method, in declaration order.
+ * An array of size zero is returned if this method declares no
+ * exceptions.
+ *
+ * @return the exception types declared by this method.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericExceptionTypes()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getExceptionTypes();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericExceptionTypes();
+ }
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the parameter list for this method, in declaration order.
+ * An array of size zero is returned if this method takes no
+ * parameters.
+ *
+ * @return a list of the types of the method's parameters
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericParameterTypes()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getParameterTypes();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericParameterTypes();
+ }
+
+ /**
+ * Returns the return type of this method.
+ *
+ * @return the return type of this method
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type getGenericReturnType()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getReturnType();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericReturnType();
+ }
+
+ /**
+ * If this method is an annotation method, returns the default
+ * value for the method. If there is no default value, or if the
+ * method is not a member of an annotation type, returns null.
+ * Primitive types are wrapped.
+ *
+ * @throws TypeNotPresentException if the method returns a Class,
+ * and the class cannot be found
+ *
+ * @since 1.5
+ */
+ public native Object getDefaultValue();
+
+ public <T extends Annotation> T getAnnotation(Class<T> annoClass)
+ {
+ Annotation[] annos = getDeclaredAnnotations();
+ for (int i = 0; i < annos.length; ++i)
+ if (annos[i].annotationType() == annoClass)
+ return (T) annos[i];
+ return null;
+ }
+
+ public Annotation[] getDeclaredAnnotations()
+ {
+ Annotation[] result = getDeclaredAnnotationsInternal();
+ if (result == null)
+ result = new Annotation[0];
+ return result;
+ }
+
+ public Annotation[][] getParameterAnnotations()
+ {
+ // FIXME: should check that we have the right number
+ // of parameters ...?
+ Annotation[][] result = getParameterAnnotationsInternal();
+ if (result == null)
+ result = new Annotation[0][0];
+ return result;
+ }
+
+ private native Annotation[] getDeclaredAnnotationsInternal();
+ private native Annotation[][] getParameterAnnotationsInternal();
+
+ private native void getType ();
+
+ // Append a class name to a string buffer. We try to print the
+ // fully-qualified name, the way that a Java programmer would expect
+ // it to be written. Weirdly, Class has no appropriate method for
+ // this.
+ static void appendClassName (StringBuffer buf, Class k)
+ {
+ if (k.isArray ())
+ {
+ appendClassName (buf, k.getComponentType ());
+ buf.append ("[]");
+ }
+ else
+ {
+ // This is correct for primitive and reference types. Really
+ // we'd like `Main$Inner' to be printed as `Main.Inner', I
+ // think, but that is a pain.
+ buf.append (k.getName ());
+ }
+ }
+
+ // Declaring class.
+ private Class declaringClass;
+
+ // Exception types.
+ Class[] exception_types;
+ // Name cache. (Initially null.)
+ private String name;
+ // Parameter types.
+ Class[] parameter_types;
+ // Return type.
+ Class return_type;
+
+ // Offset in bytes from the start of declaringClass's methods array.
+ private int offset;
+}
diff --git a/libjava/java/lang/reflect/Modifier.h b/libjava/java/lang/reflect/Modifier.h
new file mode 100644
index 000000000..4ee474a95
--- /dev/null
+++ b/libjava/java/lang/reflect/Modifier.h
@@ -0,0 +1,58 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Modifier__
+#define __java_lang_reflect_Modifier__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::reflect::Modifier : public ::java::lang::Object
+{
+
+public:
+ Modifier();
+ static jboolean isAbstract(jint);
+ static jboolean isFinal(jint);
+ static jboolean isInterface(jint);
+ static jboolean isNative(jint);
+ static jboolean isPrivate(jint);
+ static jboolean isProtected(jint);
+ static jboolean isPublic(jint);
+ static jboolean isStatic(jint);
+ static jboolean isStrict(jint);
+ static jboolean isSynchronized(jint);
+ static jboolean isTransient(jint);
+ static jboolean isVolatile(jint);
+ static ::java::lang::String * toString(jint);
+public: // actually package-private
+ static ::java::lang::StringBuilder * toString(jint, ::java::lang::StringBuilder *);
+ static ::java::lang::StringBuffer * toString(jint, ::java::lang::StringBuffer *);
+public:
+ static const jint PUBLIC = 1;
+ static const jint PRIVATE = 2;
+ static const jint PROTECTED = 4;
+ static const jint STATIC = 8;
+ static const jint FINAL = 16;
+ static const jint SYNCHRONIZED = 32;
+ static const jint VOLATILE = 64;
+ static const jint TRANSIENT = 128;
+ static const jint NATIVE = 256;
+ static const jint INTERFACE = 512;
+ static const jint ABSTRACT = 1024;
+ static const jint STRICT = 2048;
+public: // actually package-private
+ static const jint SUPER = 32;
+ static const jint ALL_FLAGS = 4095;
+ static const jint BRIDGE = 64;
+ static const jint VARARGS = 128;
+ static const jint SYNTHETIC = 4096;
+ static const jint ENUM = 16384;
+ static const jint INVISIBLE = 32768;
+ static const jint INTERPRETED = 4096;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_Modifier__
diff --git a/libjava/java/lang/reflect/Modifier.java b/libjava/java/lang/reflect/Modifier.java
new file mode 100644
index 000000000..f9a9ca2c9
--- /dev/null
+++ b/libjava/java/lang/reflect/Modifier.java
@@ -0,0 +1,375 @@
+/* java.lang.reflect.Modifier
+ Copyright (C) 1998, 1999, 2001, 2002, 2005, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+/**
+ * Modifier is a helper class with static methods to determine whether an
+ * int returned from getModifiers() represents static, public, protected,
+ * native, final, etc... and provides an additional method to print
+ * out all of the modifiers in an int in order.
+ * <p>
+ * The methods in this class use the bitmask values in the VM spec to
+ * determine the modifiers of an int. This means that a VM must return a
+ * standard mask, conformant with the VM spec. I don't know if this is how
+ * Sun does it, but I'm willing to bet money that it is.
+ *
+ * @author John Keiser
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Member#getModifiers()
+ * @see Method#getModifiers()
+ * @see Field#getModifiers()
+ * @see Constructor#getModifiers()
+ * @see Class#getModifiers()
+ * @since 1.1
+ */
+public class Modifier
+{
+ /** <STRONG>This constructor really shouldn't be here ... there are no
+ * instance methods or variables of this class, so instantiation is
+ * worthless. However, this function is in the 1.1 spec, so it is added
+ * for completeness.</STRONG>
+ */
+ public Modifier()
+ {
+ }
+
+ /**
+ * Public: accessible from any other class.
+ */
+ public static final int PUBLIC = 0x0001;
+
+ /**
+ * Private: accessible only from the same enclosing class.
+ */
+ public static final int PRIVATE = 0x0002;
+
+ /**
+ * Protected: accessible only to subclasses, or within the package.
+ */
+ public static final int PROTECTED = 0x0004;
+
+ /**
+ * Static:<br><ul>
+ * <li>Class: no enclosing instance for nested class.</li>
+ * <li>Field or Method: can be accessed or invoked without an
+ * instance of the declaring class.</li>
+ * </ul>
+ */
+ public static final int STATIC = 0x0008;
+
+ /**
+ * Final:<br><ul>
+ * <li>Class: no subclasses allowed.</li>
+ * <li>Field: cannot be changed.</li>
+ * <li>Method: cannot be overriden.</li>
+ * </ul>
+ */
+ public static final int FINAL = 0x0010;
+
+ /**
+ * Synchronized: Method: lock the class while calling this method.
+ */
+ public static final int SYNCHRONIZED = 0x0020;
+
+ /**
+ * Volatile: Field: cannot be cached.
+ */
+ public static final int VOLATILE = 0x0040;
+
+ /**
+ * Transient: Field: not serialized or deserialized.
+ */
+ public static final int TRANSIENT = 0x0080;
+
+ /**
+ * Native: Method: use JNI to call this method.
+ */
+ public static final int NATIVE = 0x0100;
+
+ /**
+ * Interface: Class: is an interface.
+ */
+ public static final int INTERFACE = 0x0200;
+
+ /**
+ * Abstract:<br><ul>
+ * <li>Class: may not be instantiated.</li>
+ * <li>Method: may not be called.</li>
+ * </ul>
+ */
+ public static final int ABSTRACT = 0x0400;
+
+ /**
+ * Strictfp: Method: expressions are FP-strict.<p>
+ * Also used as a modifier for classes, to mean that all initializers
+ * and constructors are FP-strict, but does not show up in
+ * Class.getModifiers.
+ */
+ public static final int STRICT = 0x0800;
+
+
+ /**
+ * Super - treat invokespecial as polymorphic so that super.foo() works
+ * according to the JLS. This is a reuse of the synchronized constant
+ * to patch a hole in JDK 1.0. *shudder*.
+ */
+ static final int SUPER = 0x0020;
+
+ /**
+ * All the flags, only used by code in this package.
+ */
+ static final int ALL_FLAGS = 0xfff;
+
+ /**
+ * Flag indicating a bridge method.
+ */
+ static final int BRIDGE = 0x40;
+
+ /**
+ * Flag indicating a varargs method.
+ */
+ static final int VARARGS = 0x80;
+
+ /**
+ * Flag indicating a synthetic member.
+ */
+ static final int SYNTHETIC = 0x1000;
+
+ /**
+ * Flag indicating an enum constant or an enum class.
+ */
+ static final int ENUM = 0x4000;
+
+ /**
+ * GCJ-LOCAL: This access flag is set on methods we declare
+ * internally but which must not be visible to reflection.
+ */
+ static final int INVISIBLE = 0x8000;
+
+ /**
+ * GCJ-LOCAL: This access flag is set on interpreted classes.
+ */
+ static final int INTERPRETED = 0x1000;
+
+ /**
+ * Check whether the given modifier is abstract.
+ * @param mod the modifier.
+ * @return <code>true</code> if abstract, <code>false</code> otherwise.
+ */
+ public static boolean isAbstract(int mod)
+ {
+ return (mod & ABSTRACT) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is final.
+ * @param mod the modifier.
+ * @return <code>true</code> if final, <code>false</code> otherwise.
+ */
+ public static boolean isFinal(int mod)
+ {
+ return (mod & FINAL) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is an interface.
+ * @param mod the modifier.
+ * @return <code>true</code> if an interface, <code>false</code> otherwise.
+ */
+ public static boolean isInterface(int mod)
+ {
+ return (mod & INTERFACE) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is native.
+ * @param mod the modifier.
+ * @return <code>true</code> if native, <code>false</code> otherwise.
+ */
+ public static boolean isNative(int mod)
+ {
+ return (mod & NATIVE) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is private.
+ * @param mod the modifier.
+ * @return <code>true</code> if private, <code>false</code> otherwise.
+ */
+ public static boolean isPrivate(int mod)
+ {
+ return (mod & PRIVATE) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is protected.
+ * @param mod the modifier.
+ * @return <code>true</code> if protected, <code>false</code> otherwise.
+ */
+ public static boolean isProtected(int mod)
+ {
+ return (mod & PROTECTED) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is public.
+ * @param mod the modifier.
+ * @return <code>true</code> if public, <code>false</code> otherwise.
+ */
+ public static boolean isPublic(int mod)
+ {
+ return (mod & PUBLIC) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is static.
+ * @param mod the modifier.
+ * @return <code>true</code> if static, <code>false</code> otherwise.
+ */
+ public static boolean isStatic(int mod)
+ {
+ return (mod & STATIC) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is strictfp.
+ * @param mod the modifier.
+ * @return <code>true</code> if strictfp, <code>false</code> otherwise.
+ */
+ public static boolean isStrict(int mod)
+ {
+ return (mod & STRICT) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is synchronized.
+ * @param mod the modifier.
+ * @return <code>true</code> if synchronized, <code>false</code> otherwise.
+ */
+ public static boolean isSynchronized(int mod)
+ {
+ return (mod & SYNCHRONIZED) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is transient.
+ * @param mod the modifier.
+ * @return <code>true</code> if transient, <code>false</code> otherwise.
+ */
+ public static boolean isTransient(int mod)
+ {
+ return (mod & TRANSIENT) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is volatile.
+ * @param mod the modifier.
+ * @return <code>true</code> if volatile, <code>false</code> otherwise.
+ */
+ public static boolean isVolatile(int mod)
+ {
+ return (mod & VOLATILE) != 0;
+ }
+
+ /**
+ * Get a string representation of all the modifiers represented by the
+ * given int. The keywords are printed in this order:
+ * <code>&lt;public|protected|private&gt; abstract static final transient
+ * volatile synchronized native strictfp interface</code>.
+ *
+ * @param mod the modifier.
+ * @return the String representing the modifiers.
+ */
+ public static String toString(int mod)
+ {
+ return toString(mod, new StringBuffer()).toString();
+ }
+
+ /**
+ * Package helper method that can take a StringBuilder.
+ * @param mod the modifier
+ * @param r the StringBuilder to which the String representation is appended
+ * @return r, with information appended
+ */
+ static StringBuilder toString(int mod, StringBuilder r)
+ {
+ r.append(toString(mod, new StringBuffer()));
+ return r;
+ }
+
+ /**
+ * Package helper method that can take a StringBuffer.
+ * @param mod the modifier
+ * @param r the StringBuffer to which the String representation is appended
+ * @return r, with information appended
+ */
+ static StringBuffer toString(int mod, StringBuffer r)
+ {
+ if (isPublic(mod))
+ r.append("public ");
+ if (isProtected(mod))
+ r.append("protected ");
+ if (isPrivate(mod))
+ r.append("private ");
+ if (isAbstract(mod))
+ r.append("abstract ");
+ if (isStatic(mod))
+ r.append("static ");
+ if (isFinal(mod))
+ r.append("final ");
+ if (isTransient(mod))
+ r.append("transient ");
+ if (isVolatile(mod))
+ r.append("volatile ");
+ if (isSynchronized(mod))
+ r.append("synchronized ");
+ if (isNative(mod))
+ r.append("native ");
+ if (isStrict(mod))
+ r.append("strictfp ");
+ if (isInterface(mod))
+ r.append("interface ");
+
+ // Trim trailing space.
+ if ((mod & ALL_FLAGS) != 0)
+ r.setLength(r.length() - 1);
+ return r;
+ }
+}
diff --git a/libjava/java/lang/reflect/ParameterizedType.h b/libjava/java/lang/reflect/ParameterizedType.h
new file mode 100644
index 000000000..dab9ad953
--- /dev/null
+++ b/libjava/java/lang/reflect/ParameterizedType.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_ParameterizedType__
+#define __java_lang_reflect_ParameterizedType__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::ParameterizedType : public ::java::lang::Object
+{
+
+public:
+ virtual JArray< ::java::lang::reflect::Type * > * getActualTypeArguments() = 0;
+ virtual ::java::lang::reflect::Type * getOwnerType() = 0;
+ virtual ::java::lang::reflect::Type * getRawType() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_ParameterizedType__
diff --git a/libjava/java/lang/reflect/Proxy$ClassFactory.h b/libjava/java/lang/reflect/Proxy$ClassFactory.h
new file mode 100644
index 000000000..c4cfb883d
--- /dev/null
+++ b/libjava/java/lang/reflect/Proxy$ClassFactory.h
@@ -0,0 +1,78 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Proxy$ClassFactory__
+#define __java_lang_reflect_Proxy$ClassFactory__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::Proxy$ClassFactory : public ::java::lang::Object
+{
+
+public: // actually package-private
+ Proxy$ClassFactory(::java::lang::reflect::Proxy$ProxyData *);
+private:
+ void emitMethod(jint, JArray< ::java::lang::Class * > *);
+public: // actually package-private
+ ::java::lang::Class * generate(::java::lang::ClassLoader *);
+private:
+ void putU1(jint);
+ void putU2(jint);
+ void putU4(jint);
+ void putConst(jint);
+ void putLoad(jint, ::java::lang::Class *);
+ ::java::lang::String * wrapper(::java::lang::Class *);
+ jchar utf8Info(::java::lang::String *);
+ jchar classInfo(::java::lang::String *);
+ jchar classInfo(::java::lang::Class *);
+ jchar refInfo(jbyte, ::java::lang::String *, ::java::lang::String *, ::java::lang::String *);
+ jchar nameAndTypeInfo(::java::lang::String *, ::java::lang::String *);
+ ::java::lang::String * toUtf8(::java::lang::String *);
+ jchar poolIndex(::java::lang::String *);
+ static const jbyte FIELD = 1;
+ static const jbyte METHOD = 2;
+ static const jbyte INTERFACE = 3;
+ static ::java::lang::String * CTOR_SIG;
+ static ::java::lang::String * INVOKE_SIG;
+ static const jchar ACONST_NULL = 1;
+ static const jchar ICONST_0 = 3;
+ static const jchar BIPUSH = 16;
+ static const jchar SIPUSH = 17;
+ static const jchar ILOAD = 21;
+ static const jchar ILOAD_0 = 26;
+ static const jchar ALOAD_0 = 42;
+ static const jchar ALOAD_1 = 43;
+ static const jchar AALOAD = 50;
+ static const jchar AASTORE = 83;
+ static const jchar DUP = 89;
+ static const jchar DUP_X1 = 90;
+ static const jchar SWAP = 95;
+ static const jchar IRETURN = 172;
+ static const jchar LRETURN = 173;
+ static const jchar FRETURN = 174;
+ static const jchar DRETURN = 175;
+ static const jchar ARETURN = 176;
+ static const jchar RETURN = 177;
+ static const jchar GETSTATIC = 178;
+ static const jchar GETFIELD = 180;
+ static const jchar INVOKEVIRTUAL = 182;
+ static const jchar INVOKESPECIAL = 183;
+ static const jchar INVOKEINTERFACE = 185;
+ static const jchar NEW = 187;
+ static const jchar ANEWARRAY = 189;
+ static const jchar ATHROW = 191;
+ static const jchar CHECKCAST = 192;
+ ::java::lang::StringBuffer * __attribute__((aligned(__alignof__( ::java::lang::Object)))) pool;
+ ::java::lang::StringBuffer * stream;
+ ::java::util::Map * poolEntries;
+ ::java::lang::String * qualName;
+ JArray< ::java::lang::reflect::Method * > * methods;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_Proxy$ClassFactory__
diff --git a/libjava/java/lang/reflect/Proxy$ProxyData.h b/libjava/java/lang/reflect/Proxy$ProxyData.h
new file mode 100644
index 000000000..2c0d91e5e
--- /dev/null
+++ b/libjava/java/lang/reflect/Proxy$ProxyData.h
@@ -0,0 +1,37 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Proxy$ProxyData__
+#define __java_lang_reflect_Proxy$ProxyData__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::Proxy$ProxyData : public ::java::lang::Object
+{
+
+public: // actually package-private
+ Proxy$ProxyData();
+private:
+ static ::java::lang::String * getPackage(::java::lang::Class *);
+public: // actually package-private
+ static ::java::lang::reflect::Proxy$ProxyData * getProxyData(::java::lang::reflect::Proxy$ProxyType *);
+private:
+ static jboolean isCoreObjectMethod(::java::lang::reflect::Method *);
+public: // actually package-private
+ ::java::lang::String * __attribute__((aligned(__alignof__( ::java::lang::Object)))) pack;
+ JArray< ::java::lang::Class * > * interfaces;
+ JArray< ::java::lang::reflect::Method * > * methods;
+ JArray< JArray< ::java::lang::Class * > * > * exceptions;
+private:
+ static jint count;
+public: // actually package-private
+ jint id;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_Proxy$ProxyData__
diff --git a/libjava/java/lang/reflect/Proxy$ProxySignature.h b/libjava/java/lang/reflect/Proxy$ProxySignature.h
new file mode 100644
index 000000000..ae0f028de
--- /dev/null
+++ b/libjava/java/lang/reflect/Proxy$ProxySignature.h
@@ -0,0 +1,28 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Proxy$ProxySignature__
+#define __java_lang_reflect_Proxy$ProxySignature__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::reflect::Proxy$ProxySignature : public ::java::lang::Object
+{
+
+public: // actually package-private
+ Proxy$ProxySignature(::java::lang::reflect::Method *);
+ void checkCompatibility(::java::lang::reflect::Proxy$ProxySignature *);
+public:
+ jint hashCode();
+ jboolean equals(::java::lang::Object *);
+public: // actually package-private
+ static ::java::util::HashMap * coreMethods;
+ ::java::lang::reflect::Method * __attribute__((aligned(__alignof__( ::java::lang::Object)))) method;
+ ::java::util::Set * exceptions;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_Proxy$ProxySignature__
diff --git a/libjava/java/lang/reflect/Proxy$ProxyType.h b/libjava/java/lang/reflect/Proxy$ProxyType.h
new file mode 100644
index 000000000..da7653539
--- /dev/null
+++ b/libjava/java/lang/reflect/Proxy$ProxyType.h
@@ -0,0 +1,28 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Proxy$ProxyType__
+#define __java_lang_reflect_Proxy$ProxyType__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::Proxy$ProxyType : public ::java::lang::Object
+{
+
+public: // actually package-private
+ Proxy$ProxyType(::java::lang::ClassLoader *, JArray< ::java::lang::Class * > *);
+public:
+ jint hashCode();
+ jboolean equals(::java::lang::Object *);
+public: // actually package-private
+ ::java::lang::ClassLoader * __attribute__((aligned(__alignof__( ::java::lang::Object)))) loader;
+ JArray< ::java::lang::Class * > * interfaces;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_Proxy$ProxyType__
diff --git a/libjava/java/lang/reflect/Proxy.h b/libjava/java/lang/reflect/Proxy.h
new file mode 100644
index 000000000..4dad2cffd
--- /dev/null
+++ b/libjava/java/lang/reflect/Proxy.h
@@ -0,0 +1,32 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Proxy__
+#define __java_lang_reflect_Proxy__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::Proxy : public ::java::lang::Object
+{
+
+public: // actually protected
+ Proxy(::java::lang::reflect::InvocationHandler *);
+public:
+ static ::java::lang::Class * getProxyClass(::java::lang::ClassLoader *, JArray< ::java::lang::Class * > *);
+ static ::java::lang::Object * newProxyInstance(::java::lang::ClassLoader *, JArray< ::java::lang::Class * > *, ::java::lang::reflect::InvocationHandler *);
+ static jboolean isProxyClass(::java::lang::Class *);
+ static ::java::lang::reflect::InvocationHandler * getInvocationHandler(::java::lang::Object *);
+private:
+ static const jlong serialVersionUID = -2222568056686623797LL;
+ static ::java::util::Map * proxyClasses;
+public: // actually protected
+ ::java::lang::reflect::InvocationHandler * __attribute__((aligned(__alignof__( ::java::lang::Object)))) h;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_Proxy__
diff --git a/libjava/java/lang/reflect/ReflectPermission.h b/libjava/java/lang/reflect/ReflectPermission.h
new file mode 100644
index 000000000..0e6a7c32e
--- /dev/null
+++ b/libjava/java/lang/reflect/ReflectPermission.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_ReflectPermission__
+#define __java_lang_reflect_ReflectPermission__
+
+#pragma interface
+
+#include <java/security/BasicPermission.h>
+
+class java::lang::reflect::ReflectPermission : public ::java::security::BasicPermission
+{
+
+public:
+ ReflectPermission(::java::lang::String *);
+ ReflectPermission(::java::lang::String *, ::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 7412737110241507485LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_ReflectPermission__
diff --git a/libjava/java/lang/reflect/Type.h b/libjava/java/lang/reflect/Type.h
new file mode 100644
index 000000000..55c317fa4
--- /dev/null
+++ b/libjava/java/lang/reflect/Type.h
@@ -0,0 +1,18 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Type__
+#define __java_lang_reflect_Type__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::reflect::Type : public ::java::lang::Object
+{
+
+public:
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_Type__
diff --git a/libjava/java/lang/reflect/TypeVariable.h b/libjava/java/lang/reflect/TypeVariable.h
new file mode 100644
index 000000000..6029c0190
--- /dev/null
+++ b/libjava/java/lang/reflect/TypeVariable.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_TypeVariable__
+#define __java_lang_reflect_TypeVariable__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::TypeVariable : public ::java::lang::Object
+{
+
+public:
+ virtual JArray< ::java::lang::reflect::Type * > * getBounds() = 0;
+ virtual ::java::lang::reflect::GenericDeclaration * getGenericDeclaration() = 0;
+ virtual ::java::lang::String * getName() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_TypeVariable__
diff --git a/libjava/java/lang/reflect/UndeclaredThrowableException.h b/libjava/java/lang/reflect/UndeclaredThrowableException.h
new file mode 100644
index 000000000..01b969b0e
--- /dev/null
+++ b/libjava/java/lang/reflect/UndeclaredThrowableException.h
@@ -0,0 +1,26 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_UndeclaredThrowableException__
+#define __java_lang_reflect_UndeclaredThrowableException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::reflect::UndeclaredThrowableException : public ::java::lang::RuntimeException
+{
+
+public:
+ UndeclaredThrowableException(::java::lang::Throwable *);
+ UndeclaredThrowableException(::java::lang::Throwable *, ::java::lang::String *);
+ virtual ::java::lang::Throwable * getUndeclaredThrowable();
+ virtual ::java::lang::Throwable * getCause();
+private:
+ static const jlong serialVersionUID = 330127114055056639LL;
+ ::java::lang::Throwable * __attribute__((aligned(__alignof__( ::java::lang::RuntimeException)))) undeclaredThrowable;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_UndeclaredThrowableException__
diff --git a/libjava/java/lang/reflect/VMProxy.h b/libjava/java/lang/reflect/VMProxy.h
new file mode 100644
index 000000000..e48e8e4e8
--- /dev/null
+++ b/libjava/java/lang/reflect/VMProxy.h
@@ -0,0 +1,28 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_VMProxy__
+#define __java_lang_reflect_VMProxy__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::VMProxy : public ::java::lang::Object
+{
+
+public: // actually package-private
+ VMProxy();
+ static ::java::lang::Class * getProxyClass(::java::lang::ClassLoader *, JArray< ::java::lang::Class * > *);
+ static ::java::lang::reflect::Proxy$ProxyData * getProxyData(::java::lang::ClassLoader *, JArray< ::java::lang::Class * > *);
+ static ::java::lang::Class * generateProxyClass(::java::lang::ClassLoader *, ::java::lang::reflect::Proxy$ProxyData *);
+ static jboolean HAVE_NATIVE_GET_PROXY_CLASS;
+ static jboolean HAVE_NATIVE_GET_PROXY_DATA;
+ static jboolean HAVE_NATIVE_GENERATE_PROXY_CLASS;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_VMProxy__
diff --git a/libjava/java/lang/reflect/VMProxy.java b/libjava/java/lang/reflect/VMProxy.java
new file mode 100644
index 000000000..ea1c88506
--- /dev/null
+++ b/libjava/java/lang/reflect/VMProxy.java
@@ -0,0 +1,140 @@
+/* VMProxy.java -- VM interface for proxy class
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+final class VMProxy
+{
+ /**
+ * Set to true if the VM provides a native method to implement
+ * Proxy.getProxyClass completely, including argument verification.
+ * If this is true, HAVE_NATIVE_GET_PROXY_DATA and
+ * HAVE_NATIVE_GENERATE_PROXY_CLASS should be false.
+ * @see java.lang.reflect.Proxy
+ */
+ static boolean HAVE_NATIVE_GET_PROXY_CLASS = false;
+
+ /**
+ * Set to true if the VM provides a native method to implement
+ * the first part of Proxy.getProxyClass: generation of the array
+ * of methods to convert, and verification of the arguments.
+ * If this is true, HAVE_NATIVE_GET_PROXY_CLASS should be false.
+ * @see java.lang.reflect.Proxy
+ */
+ static boolean HAVE_NATIVE_GET_PROXY_DATA = false;
+
+ /**
+ * Set to true if the VM provides a native method to implement
+ * the second part of Proxy.getProxyClass: conversion of an array of
+ * methods into an actual proxy class.
+ * If this is true, HAVE_NATIVE_GET_PROXY_CLASS should be false.
+ * @see java.lang.reflect.Proxy
+ */
+ static boolean HAVE_NATIVE_GENERATE_PROXY_CLASS = true;
+
+ /**
+ * Optional native method to replace (and speed up) the pure Java
+ * implementation of getProxyClass. Only needed if
+ * VMProxy.HAVE_NATIVE_GET_PROXY_CLASS is true, this does the
+ * work of both getProxyData and generateProxyClass with no
+ * intermediate form in Java. The native code may safely assume that
+ * this class must be created, and does not already exist.
+ *
+ * @param loader the class loader to define the proxy class in; null
+ * implies the bootstrap class loader
+ * @param interfaces the interfaces the class will extend
+ * @return the generated proxy class
+ * @throws IllegalArgumentException if the constraints for getProxyClass
+ * were violated, except for problems with null
+ * @throws NullPointerException if `interfaces' is null or contains
+ * a null entry, or if handler is null
+ * @see Configuration#HAVE_NATIVE_GET_PROXY_CLASS
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see #getProxyData(ClassLoader, Class[])
+ * @see #generateProxyClass(ProxyData)
+ */
+ static Class getProxyClass(ClassLoader loader, Class[] interfaces)
+ {
+ return null;
+ }
+
+ /**
+ * Optional native method to replace (and speed up) the pure Java
+ * implementation of getProxyData. Only needed if
+ * Configuration.HAVE_NATIVE_GET_PROXY_DATA is true. The native code
+ * may safely assume that a new ProxyData object must be created which
+ * does not duplicate any existing ones.
+ *
+ * @param loader the class loader to define the proxy class in; null
+ * implies the bootstrap class loader
+ * @param interfaces the interfaces the class will extend
+ * @return all data that is required to make this proxy class
+ * @throws IllegalArgumentException if the constraints for getProxyClass
+ * were violated, except for problems with null
+ * @throws NullPointerException if `interfaces' is null or contains
+ * a null entry, or if handler is null
+ * @see Configuration.HAVE_NATIVE_GET_PROXY_DATA
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see ProxyType#getProxyData()
+ */
+ static Proxy.ProxyData getProxyData(ClassLoader loader, Class[] interfaces)
+ {
+ return null;
+ }
+
+ /**
+ * Optional native method to replace (and speed up) the pure Java
+ * implementation of generateProxyClass. Only needed if
+ * Configuration.HAVE_NATIVE_GENERATE_PROXY_CLASS is true. The native
+ * code may safely assume that a new Class must be created, and that
+ * the ProxyData object does not describe any existing class.
+ *
+ * @param loader the class loader to define the proxy class in; null
+ * implies the bootstrap class loader
+ * @param data the struct of information to convert to a Class. This
+ * has already been verified for all problems except exceeding
+ * VM limitations
+ * @return the newly generated class
+ * @throws IllegalArgumentException if VM limitations are exceeded
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see ProxyData#generateProxyClass(ClassLoader)
+ */
+ static native Class generateProxyClass(ClassLoader loader, Proxy.ProxyData data);
+}
diff --git a/libjava/java/lang/reflect/WildcardType.h b/libjava/java/lang/reflect/WildcardType.h
new file mode 100644
index 000000000..2c5b93d65
--- /dev/null
+++ b/libjava/java/lang/reflect/WildcardType.h
@@ -0,0 +1,22 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_WildcardType__
+#define __java_lang_reflect_WildcardType__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::WildcardType : public ::java::lang::Object
+{
+
+public:
+ virtual JArray< ::java::lang::reflect::Type * > * getLowerBounds() = 0;
+ virtual JArray< ::java::lang::reflect::Type * > * getUpperBounds() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_WildcardType__
diff --git a/libjava/java/lang/reflect/natArray.cc b/libjava/java/lang/reflect/natArray.cc
new file mode 100644
index 000000000..b7bc8beff
--- /dev/null
+++ b/libjava/java/lang/reflect/natArray.cc
@@ -0,0 +1,360 @@
+// natField.cc - Implementation of java.lang.reflect.Field native methods.
+
+/* Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <jvm.h>
+#include <gcj/cni.h>
+#include <java-stack.h>
+#include <java/lang/reflect/Array.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+
+jobject
+java::lang::reflect::Array::newInstance (jclass componentType, jint length)
+{
+ if (componentType->isPrimitive())
+ {
+ // We could check for this in _Jv_NewPrimArray, but that seems
+ // like needless overhead when the only real route to this
+ // problem is here.
+ if (componentType == JvPrimClass (void))
+ throw new java::lang::IllegalArgumentException ();
+ return _Jv_NewPrimArray (componentType, length);
+ }
+ else
+ // FIXME: class loader?
+ return JvNewObjectArray (length, componentType, NULL);
+}
+
+jobject
+java::lang::reflect::Array::newInstance (jclass componentType,
+ jintArray dimensions)
+{
+ jint ndims = dimensions->length;
+ if (ndims == 0)
+ throw new java::lang::IllegalArgumentException ();
+ jint* dims = elements (dimensions);
+ if (ndims == 1)
+ return newInstance (componentType, dims[0]);
+
+ Class *caller = _Jv_StackTrace::GetCallingClass (&Array::class$);
+ ClassLoader *caller_loader = NULL;
+ if (caller)
+ caller_loader = caller->getClassLoaderInternal();
+
+ jclass arrayType = componentType;
+ for (int i = 0; i < ndims; i++)
+ arrayType = _Jv_GetArrayClass (arrayType, caller_loader);
+
+ return _Jv_NewMultiArray (arrayType, ndims, dims);
+}
+
+jint
+java::lang::reflect::Array::getLength (jobject array)
+{
+ jclass arrayType = array->getClass();
+ if (! arrayType->isArray ())
+ throw new java::lang::IllegalArgumentException;
+ return ((__JArray*) array)->length;
+}
+
+jclass
+java::lang::reflect::Array::getElementType (jobject array, jint index)
+{
+ jclass arrayType = array->getClass();
+ if (! arrayType->isArray ())
+ throw new java::lang::IllegalArgumentException;
+ jint length = ((__JArray*) array)->length;
+ if ((_Jv_uint) index >= (_Jv_uint) length)
+ _Jv_ThrowBadArrayIndex(index);
+ return arrayType->getComponentType ();
+}
+
+jboolean
+java::lang::reflect::Array::getBoolean (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (boolean))
+ return elements ((jbooleanArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jchar
+java::lang::reflect::Array::getChar (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jbyte
+java::lang::reflect::Array::getByte (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jshort
+java::lang::reflect::Array::getShort (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jint
+java::lang::reflect::Array::getInt (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (int))
+ return elements ((jintArray) array) [index];
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jlong
+java::lang::reflect::Array::getLong (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (long))
+ return elements ((jlongArray) array) [index];
+ if (elementType == JvPrimClass (int))
+ return elements ((jintArray) array) [index];
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jfloat
+java::lang::reflect::Array::getFloat (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (float))
+ return elements ((jfloatArray) array) [index];
+ if (elementType == JvPrimClass (long))
+ return elements ((jlongArray) array) [index];
+ if (elementType == JvPrimClass (int))
+ return elements ((jintArray) array) [index];
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jdouble
+java::lang::reflect::Array::getDouble (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (double))
+ return elements ((jdoubleArray) array) [index];
+ if (elementType == JvPrimClass (float))
+ return elements ((jfloatArray) array) [index];
+ if (elementType == JvPrimClass (long))
+ return elements ((jlongArray) array) [index];
+ if (elementType == JvPrimClass (int))
+ return elements ((jintArray) array) [index];
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jobject
+java::lang::reflect::Array::get (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (! elementType->isPrimitive ())
+ return elements ((jobjectArray) array) [index];
+ if (elementType == JvPrimClass (double))
+ return new java::lang::Double (elements ((jdoubleArray) array) [index]);
+ if (elementType == JvPrimClass (float))
+ return new java::lang::Float (elements ((jfloatArray) array) [index]);
+ if (elementType == JvPrimClass (long))
+ return new java::lang::Long (elements ((jlongArray) array) [index]);
+ if (elementType == JvPrimClass (int))
+ return new java::lang::Integer (elements ((jintArray) array) [index]);
+ if (elementType == JvPrimClass (short))
+ return new java::lang::Short (elements ((jshortArray) array) [index]);
+ if (elementType == JvPrimClass (byte))
+ return new java::lang::Byte (elements ((jbyteArray) array) [index]);
+ if (elementType == JvPrimClass (char))
+ return new java::lang::Character (elements ((jcharArray) array) [index]);
+ if (elementType == JvPrimClass (boolean))
+ {
+ _Jv_InitClass (&java::lang::Boolean::class$);
+ if (elements ((jbooleanArray) array) [index])
+ return java::lang::Boolean::TRUE;
+ else
+ return java::lang::Boolean::FALSE;
+ }
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setChar (jobject array, jint index, jchar value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (char))
+ elements ((jcharArray) array) [index] = value;
+ else if (elementType == JvPrimClass (int))
+ elements ((jintArray) array) [index] = value;
+ else if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setByte (jobject array, jint index, jbyte value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (byte))
+ elements ((jbyteArray) array) [index] = value;
+ else if (elementType == JvPrimClass (short))
+ elements ((jshortArray) array) [index] = value;
+ else if (elementType == JvPrimClass (int))
+ elements ((jintArray) array) [index] = value;
+ else if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setShort (jobject array, jint index, jshort value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (short))
+ elements ((jshortArray) array) [index] = value;
+ else if (elementType == JvPrimClass (int))
+ elements ((jintArray) array) [index] = value;
+ else if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setInt (jobject array, jint index, jint value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (int))
+ elements ((jintArray) array) [index] = value;
+ else if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setLong (jobject array, jint index, jlong value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setFloat (jobject array, jint index, jfloat value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setDouble (jobject array, jint index, jdouble value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setBoolean (jobject array,
+ jint index, jboolean value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (boolean))
+ elements ((jbooleanArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::set (jobject array, jint index,
+ jobject value, jclass elType)
+{
+ // We don't have to call getElementType here, or check INDEX,
+ // because it was already done in the Java wrapper.
+ if (value != NULL && ! _Jv_IsInstanceOf (value, elType))
+ throw new java::lang::IllegalArgumentException;
+ elements ((jobjectArray) array) [index] = value;
+}
diff --git a/libjava/java/lang/reflect/natConstructor.cc b/libjava/java/lang/reflect/natConstructor.cc
new file mode 100644
index 000000000..953d86dd4
--- /dev/null
+++ b/libjava/java/lang/reflect/natConstructor.cc
@@ -0,0 +1,93 @@
+// natConstructor.cc - Native code for Constructor class.
+
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-stack.h>
+
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/IllegalAccessException.h>
+#include <java/lang/reflect/Constructor.h>
+#include <java/lang/reflect/Method.h>
+#include <java/lang/reflect/InvocationTargetException.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/InstantiationException.h>
+#include <gcj/method.h>
+
+typedef JArray< ::java::lang::annotation::Annotation * > * anno_a_t;
+typedef JArray< JArray< ::java::lang::annotation::Annotation * > *> * anno_aa_t;
+
+jint
+java::lang::reflect::Constructor::getModifiersInternal ()
+{
+ return _Jv_FromReflectedConstructor (this)->accflags;
+}
+
+jstring
+java::lang::reflect::Constructor::getSignature()
+{
+ return declaringClass->getReflectionSignature (this);
+}
+
+anno_a_t
+java::lang::reflect::Constructor::getDeclaredAnnotationsInternal()
+{
+ return (anno_a_t) declaringClass->getDeclaredAnnotations(this, false);
+}
+
+anno_aa_t
+java::lang::reflect::Constructor::getParameterAnnotationsInternal()
+{
+ return (anno_aa_t) declaringClass->getDeclaredAnnotations(this, true);
+}
+
+void
+java::lang::reflect::Constructor::getType ()
+{
+ _Jv_GetTypesFromSignature (_Jv_FromReflectedConstructor (this),
+ declaringClass,
+ &parameter_types,
+ NULL);
+
+ // FIXME: for now we have no way to get exception information.
+ exception_types =
+ (JArray<jclass> *) JvNewObjectArray (0, &java::lang::Class::class$, NULL);
+}
+
+jobject
+java::lang::reflect::Constructor::newInstance (jobjectArray args)
+{
+ using namespace java::lang::reflect;
+
+ if (parameter_types == NULL)
+ getType ();
+
+ jmethodID meth = _Jv_FromReflectedConstructor (this);
+
+ // Check accessibility, if required.
+ if (! (Modifier::isPublic (meth->accflags) || this->isAccessible()))
+ {
+ Class *caller = _Jv_StackTrace::GetCallingClass (&Constructor::class$);
+ if (! _Jv_CheckAccess(caller, declaringClass, meth->accflags))
+ throw new IllegalAccessException;
+ }
+
+ if (Modifier::isAbstract (declaringClass->getModifiers()))
+ throw new InstantiationException;
+
+ _Jv_InitClass (declaringClass);
+
+ // In the constructor case the return type is the type of the
+ // constructor.
+ return _Jv_CallAnyMethodA (NULL, declaringClass, meth, true,
+ parameter_types, args);
+}
diff --git a/libjava/java/lang/reflect/natField.cc b/libjava/java/lang/reflect/natField.cc
new file mode 100644
index 000000000..734f65316
--- /dev/null
+++ b/libjava/java/lang/reflect/natField.cc
@@ -0,0 +1,449 @@
+// natField.cc - Implementation of java.lang.reflect.Field native methods.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <jvm.h>
+#include <java-stack.h>
+#include <java/lang/reflect/Field.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IllegalAccessException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+
+typedef JArray< ::java::lang::annotation::Annotation * > * anno_a_t;
+
+jint
+java::lang::reflect::Field::getModifiersInternal ()
+{
+ return _Jv_FromReflectedField (this)->flags;
+}
+
+jstring
+java::lang::reflect::Field::getSignature()
+{
+ return declaringClass->getReflectionSignature (this);
+}
+
+anno_a_t
+java::lang::reflect::Field::getDeclaredAnnotationsInternal()
+{
+ return (anno_a_t) declaringClass->getDeclaredAnnotations(this);
+}
+
+jstring
+java::lang::reflect::Field::getName ()
+{
+ if (name == NULL)
+ name = _Jv_NewStringUtf8Const (_Jv_FromReflectedField (this)->name);
+ return name;
+}
+
+jclass
+java::lang::reflect::Field::getType ()
+{
+ if (type == NULL)
+ {
+ jfieldID fld = _Jv_FromReflectedField (this);
+ JvSynchronize sync (declaringClass);
+ _Jv_Linker::resolve_field (fld, declaringClass->getClassLoaderInternal ());
+ type = fld->type;
+ }
+ return type;
+}
+
+static void*
+getAddr (java::lang::reflect::Field* field, jclass caller, jobject obj,
+ jboolean checkFinal)
+{
+ using namespace java::lang::reflect;
+
+ jfieldID fld = _Jv_FromReflectedField (field);
+ _Jv_ushort flags = fld->getModifiers();
+
+ // Setting a final field is usually not allowed.
+ if (checkFinal
+ // As of 1.5, you can set a non-static final field if it is
+ // accessible.
+ && (! field->isAccessible()
+ || (field->getModifiers() & java::lang::reflect::Modifier::STATIC))
+ && (field->getModifiers() & java::lang::reflect::Modifier::FINAL))
+ throw new java::lang::IllegalAccessException(JvNewStringUTF
+ ("Field is final"));
+
+ // Check accessibility, if required.
+ if (! (Modifier::isPublic (flags) || field->isAccessible()))
+ {
+ if (! caller)
+ caller = _Jv_StackTrace::GetCallingClass (&Field::class$);
+ if (! _Jv_CheckAccess (caller, field->getDeclaringClass(), flags))
+ throw new java::lang::IllegalAccessException;
+ }
+
+ if (flags & Modifier::STATIC)
+ {
+ jclass fldClass = field->getDeclaringClass ();
+ JvInitClass(fldClass);
+ return fld->u.addr;
+ }
+ else
+ {
+ if (obj == NULL)
+ throw new java::lang::NullPointerException;
+ if (! _Jv_IsInstanceOf (obj, field->getDeclaringClass()))
+ throw new java::lang::IllegalArgumentException;
+ return (void*) ((char*) obj + fld->getOffset ());
+ }
+}
+
+static jboolean
+getBoolean (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (boolean))
+ return * (jboolean *) addr;
+ throw new java::lang::IllegalArgumentException;
+}
+
+static jchar
+getChar (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (char))
+ return * (jchar *) addr;
+ throw new java::lang::IllegalArgumentException;
+}
+
+static jbyte
+getByte (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (byte))
+ return * (jbyte *) addr;
+ throw new java::lang::IllegalArgumentException;
+}
+
+static jshort
+getShort (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (short))
+ return * (jshort *) addr;
+ if (cls == JvPrimClass (byte))
+ return * (jbyte *) addr;
+ throw new java::lang::IllegalArgumentException;
+}
+
+static jint
+getInt (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (int))
+ return * (jint *) addr;
+ if (cls == JvPrimClass (short))
+ return * (jshort *) addr;
+ if (cls == JvPrimClass (char))
+ return * (jchar *) addr;
+ if (cls == JvPrimClass (byte))
+ return * (jbyte *) addr;
+ throw new java::lang::IllegalArgumentException;
+}
+
+static jlong
+getLong (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (long))
+ return * (jlong *) addr;
+ return ::getInt(cls, addr);
+}
+
+static jfloat
+getFloat (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (float))
+ return * (jfloat *) addr;
+ if (cls == JvPrimClass (long))
+ return * (jlong *) addr;
+ return ::getInt(cls, addr);
+}
+
+static jdouble
+getDouble (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (double))
+ return * (jdouble *) addr;
+ if (cls == JvPrimClass (float))
+ return * (jfloat *) addr;
+ if (cls == JvPrimClass (long))
+ return * (jlong *) addr;
+ return ::getInt(cls, addr);
+}
+
+jboolean
+java::lang::reflect::Field::getBoolean (jclass caller, jobject obj)
+{
+ return ::getBoolean (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jchar
+java::lang::reflect::Field::getChar (jclass caller, jobject obj)
+{
+ return ::getChar (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jbyte
+java::lang::reflect::Field::getByte (jclass caller, jobject obj)
+{
+ return ::getByte (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jshort
+java::lang::reflect::Field::getShort (jclass caller, jobject obj)
+{
+ return ::getShort (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jint
+java::lang::reflect::Field::getInt (jclass caller, jobject obj)
+{
+ return ::getInt (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jlong
+java::lang::reflect::Field::getLong (jclass caller, jobject obj)
+{
+ return ::getLong (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jfloat
+java::lang::reflect::Field::getFloat (jclass caller, jobject obj)
+{
+ return ::getFloat (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jdouble
+java::lang::reflect::Field::getDouble (jclass caller, jobject obj)
+{
+ return ::getDouble (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jobject
+java::lang::reflect::Field::get (jclass caller, jobject obj)
+{
+ jclass type = this->getType();
+ void* addr = getAddr (this, caller, obj, false);
+ if (! type->isPrimitive ())
+ return * (jobject*) addr;
+ if (type == JvPrimClass (double))
+ return new java::lang::Double (* (jdouble*) addr);
+ if (type == JvPrimClass (float))
+ return new java::lang::Float (* (jfloat*) addr);
+ if (type == JvPrimClass (long))
+ return new java::lang::Long (* (jlong*) addr);
+ if (type == JvPrimClass (int))
+ return new java::lang::Integer (* (jint*) addr);
+ if (type == JvPrimClass (short))
+ return new java::lang::Short (* (jshort*) addr);
+ if (type == JvPrimClass (byte))
+ return new java::lang::Byte (* (jbyte*) addr);
+ if (type == JvPrimClass (char))
+ return new java::lang::Character (* (jchar*) addr);
+ if (type == JvPrimClass (boolean))
+ {
+ _Jv_InitClass (&java::lang::Boolean::class$);
+ if (* (jboolean*) addr)
+ return java::lang::Boolean::TRUE;
+ else
+ return java::lang::Boolean::FALSE;
+ }
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setBoolean (jclass type, void *addr, jboolean value)
+{
+ if (type == JvPrimClass (boolean))
+ * (jboolean *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setChar (jclass type, void *addr, jchar value)
+{
+ if (type == JvPrimClass (char))
+ * (jchar *) addr = value;
+ else if (type == JvPrimClass (int))
+ * (jint *) addr = value;
+ else if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setByte (jclass type, void *addr, jbyte value)
+{
+ if (type == JvPrimClass (byte))
+ * (jbyte *) addr = value;
+ else if (type == JvPrimClass (short))
+ * (jshort *) addr = value;
+ else if (type == JvPrimClass (int))
+ * (jint *) addr = value;
+ else if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setShort (jclass type, void *addr, jshort value)
+{
+ if (type == JvPrimClass (short))
+ * (jshort *) addr = value;
+ else if (type == JvPrimClass (int))
+ * (jint *) addr = value;
+ else if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setInt (jclass type, void *addr, jint value)
+{
+ if (type == JvPrimClass (int))
+ * (jint *) addr = value;
+ else if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setLong (jclass type, void *addr, jlong value)
+{
+ if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setFloat (jclass type, void *addr, jfloat value)
+{
+ if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setDouble (jclass type, void *addr, jdouble value)
+{
+ if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Field::setBoolean (jclass caller, jobject obj, jboolean b,
+ jboolean checkFinal)
+{
+ ::setBoolean (this->getType(), getAddr (this, caller, obj, checkFinal), b);
+}
+
+void
+java::lang::reflect::Field::setChar (jclass caller, jobject obj, jchar c,
+ jboolean checkFinal)
+{
+ ::setChar (this->getType(), getAddr (this, caller, obj, checkFinal), c);
+}
+
+void
+java::lang::reflect::Field::setByte (jclass caller, jobject obj, jbyte b,
+ jboolean checkFinal)
+{
+ ::setByte (this->getType(), getAddr (this, caller, obj, checkFinal), b);
+}
+
+void
+java::lang::reflect::Field::setShort (jclass caller, jobject obj, jshort s,
+ jboolean checkFinal)
+{
+ ::setShort (this->getType(), getAddr (this, caller, obj, checkFinal), s);
+}
+
+void
+java::lang::reflect::Field::setInt (jclass caller, jobject obj, jint i,
+ jboolean checkFinal)
+{
+ ::setInt (this->getType(), getAddr (this, caller, obj, checkFinal), i);
+}
+
+void
+java::lang::reflect::Field::setLong (jclass caller, jobject obj, jlong l,
+ jboolean checkFinal)
+{
+ ::setLong (this->getType(), getAddr (this, caller, obj, checkFinal), l);
+}
+
+void
+java::lang::reflect::Field::setFloat (jclass caller, jobject obj, jfloat f,
+ jboolean checkFinal)
+{
+ ::setFloat (this->getType(), getAddr (this, caller, obj, checkFinal), f);
+}
+
+void
+java::lang::reflect::Field::setDouble (jclass caller, jobject obj, jdouble d,
+ jboolean checkFinal)
+{
+ ::setDouble (this->getType(), getAddr (this, caller, obj, checkFinal), d);
+}
+
+void
+java::lang::reflect::Field::set (jclass caller, jobject object, jobject value,
+ jclass type, jboolean checkFinal)
+{
+ void* addr = getAddr (this, caller, object, checkFinal);
+ if (value != NULL && ! _Jv_IsInstanceOf (value, type))
+ throw new java::lang::IllegalArgumentException;
+ * (jobject*) addr = value;
+}
diff --git a/libjava/java/lang/reflect/natMethod.cc b/libjava/java/lang/reflect/natMethod.cc
new file mode 100644
index 000000000..d95c92f84
--- /dev/null
+++ b/libjava/java/lang/reflect/natMethod.cc
@@ -0,0 +1,701 @@
+// natMethod.cc - Native code for Method class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001 , 2002, 2003, 2004, 2005, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <jni.h>
+#include <java-stack.h>
+
+#include <java/lang/reflect/Method.h>
+#include <java/lang/reflect/Constructor.h>
+#include <java/lang/reflect/InvocationTargetException.h>
+#include <java/lang/reflect/Modifier.h>
+
+#include <java/lang/Void.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/IllegalAccessException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/VirtualMachineError.h>
+#include <java/lang/Class.h>
+#include <gcj/method.h>
+#include <gnu/gcj/RawData.h>
+#include <java/lang/NoClassDefFoundError.h>
+
+#include <stdlib.h>
+
+#if USE_LIBFFI
+#include <ffi.h>
+#else
+#include <java/lang/UnsupportedOperationException.h>
+#endif
+
+typedef JArray< ::java::lang::annotation::Annotation * > * anno_a_t;
+typedef JArray< JArray< ::java::lang::annotation::Annotation * > *> * anno_aa_t;
+
+
+
+struct cpair
+{
+ jclass prim;
+ jclass wrap;
+};
+
+// This is used to determine when a primitive widening conversion is
+// allowed.
+static cpair primitives[] =
+{
+#define BOOLEAN 0
+ { JvPrimClass (boolean), &java::lang::Boolean::class$ },
+ { JvPrimClass (byte), &java::lang::Byte::class$ },
+#define SHORT 2
+ { JvPrimClass (short), &java::lang::Short::class$ },
+#define CHAR 3
+ { JvPrimClass (char), &java::lang::Character::class$ },
+ { JvPrimClass (int), &java::lang::Integer::class$ },
+ { JvPrimClass (long), &java::lang::Long::class$ },
+ { JvPrimClass (float), &java::lang::Float::class$ },
+ { JvPrimClass (double), &java::lang::Double::class$ },
+ { NULL, NULL }
+};
+
+static inline jboolean
+can_widen (jclass from, jclass to)
+{
+ int fromx = -1, tox = -1;
+
+ for (int i = 0; primitives[i].prim; ++i)
+ {
+ if (primitives[i].wrap == from)
+ fromx = i;
+ if (primitives[i].prim == to)
+ tox = i;
+ }
+
+ // Can't handle a miss.
+ if (fromx == -1 || tox == -1)
+ return false;
+ // Boolean arguments may not be widened.
+ if (fromx == BOOLEAN && tox != BOOLEAN)
+ return false;
+ // Nothing promotes to char.
+ if (tox == CHAR && fromx != CHAR)
+ return false;
+
+ return fromx <= tox;
+}
+
+#ifdef USE_LIBFFI
+static inline ffi_type *
+get_ffi_type (jclass klass)
+{
+ // A special case.
+ if (klass == NULL)
+ return &ffi_type_pointer;
+
+ ffi_type *r;
+ if (klass == JvPrimClass (byte))
+ r = &ffi_type_sint8;
+ else if (klass == JvPrimClass (short))
+ r = &ffi_type_sint16;
+ else if (klass == JvPrimClass (int))
+ r = &ffi_type_sint32;
+ else if (klass == JvPrimClass (long))
+ r = &ffi_type_sint64;
+ else if (klass == JvPrimClass (float))
+ r = &ffi_type_float;
+ else if (klass == JvPrimClass (double))
+ r = &ffi_type_double;
+ else if (klass == JvPrimClass (boolean))
+ {
+ // On some platforms a bool is a byte, on others an int.
+ if (sizeof (jboolean) == sizeof (jbyte))
+ r = &ffi_type_sint8;
+ else
+ {
+ JvAssert (sizeof (jboolean) == sizeof (jint));
+ r = &ffi_type_sint32;
+ }
+ }
+ else if (klass == JvPrimClass (char))
+ r = &ffi_type_uint16;
+ else
+ {
+ JvAssert (! klass->isPrimitive());
+ r = &ffi_type_pointer;
+ }
+
+ return r;
+}
+#endif // USE_LIBFFI
+
+jobject
+java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
+{
+ using namespace java::lang::reflect;
+ jclass iface = NULL;
+
+ if (parameter_types == NULL)
+ getType ();
+
+ jmethodID meth = _Jv_FromReflectedMethod (this);
+
+ if (Modifier::isStatic(meth->accflags))
+ {
+ // We have to initialize a static class. It is safe to do this
+ // here and not in _Jv_CallAnyMethodA because JNI initializes a
+ // class whenever a method lookup is done.
+ _Jv_InitClass (declaringClass);
+ }
+ else
+ {
+ jclass objClass = JV_CLASS (obj);
+ if (! _Jv_IsAssignableFrom (objClass, declaringClass))
+ throw new java::lang::IllegalArgumentException;
+ }
+
+ // Check accessibility, if required.
+ if (! this->isAccessible())
+ {
+ if (! (Modifier::isPublic (meth->accflags)))
+ {
+ Class *caller = _Jv_StackTrace::GetCallingClass (&Method::class$);
+ if (! _Jv_CheckAccess(caller, declaringClass, meth->accflags))
+ throw new IllegalAccessException;
+ }
+ else
+ // Method is public, check to see if class is accessible.
+ {
+ jint flags = (declaringClass->accflags
+ & (Modifier::PUBLIC
+ | Modifier::PROTECTED
+ | Modifier::PRIVATE));
+ if (flags == 0) // i.e. class is package private
+ {
+ Class *caller = _Jv_StackTrace::GetCallingClass (&Method::class$);
+ if (! _Jv_ClassNameSamePackage (caller->name,
+ declaringClass->name))
+ throw new IllegalAccessException;
+ }
+ }
+ }
+
+ if (declaringClass->isInterface())
+ iface = declaringClass;
+
+ return _Jv_CallAnyMethodA (obj, return_type, meth, false,
+ parameter_types, args, iface);
+}
+
+jint
+java::lang::reflect::Method::getModifiersInternal ()
+{
+ return _Jv_FromReflectedMethod (this)->accflags;
+}
+
+jstring
+java::lang::reflect::Method::getSignature()
+{
+ return declaringClass->getReflectionSignature (this);
+}
+
+jobject
+java::lang::reflect::Method::getDefaultValue()
+{
+ return declaringClass->getMethodDefaultValue(this);
+}
+
+anno_a_t
+java::lang::reflect::Method::getDeclaredAnnotationsInternal()
+{
+ return (anno_a_t) declaringClass->getDeclaredAnnotations(this, false);
+}
+
+anno_aa_t
+java::lang::reflect::Method::getParameterAnnotationsInternal()
+{
+ return (anno_aa_t) declaringClass->getDeclaredAnnotations(this, true);
+}
+
+jstring
+java::lang::reflect::Method::getName ()
+{
+ if (name == NULL)
+ name = _Jv_NewStringUtf8Const (_Jv_FromReflectedMethod (this)->name);
+ return name;
+}
+
+/* Internal method to set return_type and parameter_types fields. */
+
+void
+java::lang::reflect::Method::getType ()
+{
+ _Jv_Method *method = _Jv_FromReflectedMethod (this);
+ _Jv_GetTypesFromSignature (method,
+ declaringClass,
+ &parameter_types,
+ &return_type);
+
+ int count = 0;
+ if (method->throws != NULL)
+ {
+ while (method->throws[count] != NULL)
+ ++count;
+ }
+
+ exception_types
+ = (JArray<jclass> *) JvNewObjectArray (count, &java::lang::Class::class$,
+ NULL);
+ jclass *elts = elements (exception_types);
+ for (int i = 0; i < count; ++i)
+ elts[i] = _Jv_FindClass (method->throws[i],
+ declaringClass->getClassLoaderInternal ());
+}
+
+void
+_Jv_GetTypesFromSignature (jmethodID method,
+ jclass declaringClass,
+ JArray<jclass> **arg_types_out,
+ jclass *return_type_out)
+{
+
+ _Jv_Utf8Const* sig = method->signature;
+ java::lang::ClassLoader *loader = declaringClass->getClassLoaderInternal();
+ char *ptr = sig->chars();
+ int numArgs = 0;
+ /* First just count the number of parameters. */
+ // FIXME: should do some validation here, e.g., that there is only
+ // one return type.
+ for (; ; ptr++)
+ {
+ switch (*ptr)
+ {
+ case 0:
+ case ')':
+ case 'V':
+ break;
+ case '[':
+ case '(':
+ continue;
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'F':
+ case 'S':
+ case 'I':
+ case 'J':
+ case 'Z':
+ numArgs++;
+ continue;
+ case 'L':
+ numArgs++;
+ do
+ ptr++;
+ while (*ptr != ';' && ptr[1] != '\0');
+ continue;
+ }
+ break;
+ }
+
+ JArray<jclass> *args = (JArray<jclass> *)
+ JvNewObjectArray (numArgs, &java::lang::Class::class$, NULL);
+ jclass* argPtr = elements (args);
+ for (ptr = sig->chars(); *ptr != '\0'; ptr++)
+ {
+ if (*ptr == '(')
+ continue;
+ if (*ptr == ')')
+ {
+ argPtr = return_type_out;
+ continue;
+ }
+
+ char *end_ptr;
+ jclass type = _Jv_FindClassFromSignature (ptr, loader, &end_ptr);
+ if (type == NULL)
+ // FIXME: This isn't ideal.
+ throw new java::lang::NoClassDefFoundError (sig->toString());
+
+ // ARGPTR can be NULL if we are processing the return value of a
+ // call from Constructor.
+ if (argPtr)
+ *argPtr++ = type;
+
+ ptr = end_ptr;
+ }
+ *arg_types_out = args;
+}
+
+// This is a very rough analog of the JNI CallNonvirtual<type>MethodA
+// functions. It handles both Methods and Constructors, and it can
+// handle any return type. In the Constructor case, the `obj'
+// argument is unused and should be NULL; also, the `return_type' is
+// the class that the constructor will construct. RESULT is a pointer
+// to a `jvalue' (see jni.h); for a void method this should be NULL.
+// This function returns an exception (if one was thrown), or NULL if
+// the call went ok.
+void
+_Jv_CallAnyMethodA (jobject obj,
+ jclass return_type,
+ jmethodID meth,
+ jboolean is_constructor,
+ jboolean is_virtual_call,
+ JArray<jclass> *parameter_types,
+ const jvalue *args,
+ jvalue *result,
+ jboolean is_jni_call,
+ jclass iface)
+{
+ using namespace java::lang::reflect;
+
+#ifdef USE_LIBFFI
+ JvAssert (! is_constructor || ! obj);
+ JvAssert (! is_constructor || return_type);
+
+ // See whether call needs an object as the first argument. A
+ // constructor does need a `this' argument, but it is one we create.
+ jboolean needs_this = false;
+ if (is_constructor
+ || ! Modifier::isStatic(meth->accflags))
+ needs_this = true;
+
+ int param_count = parameter_types->length;
+ if (needs_this)
+ ++param_count;
+
+ ffi_type *rtype;
+ // A constructor itself always returns void.
+ if (is_constructor || return_type == JvPrimClass (void))
+ rtype = &ffi_type_void;
+ else
+ rtype = get_ffi_type (return_type);
+ ffi_type **argtypes = (ffi_type **) __builtin_alloca (param_count
+ * sizeof (ffi_type *));
+
+ jclass *paramelts = elements (parameter_types);
+
+ // Special case for the `this' argument of a constructor. Note that
+ // the JDK 1.2 docs specify that the new object must be allocated
+ // before argument conversions are done.
+ if (is_constructor)
+ obj = _Jv_AllocObject (return_type);
+
+ const int size_per_arg = sizeof(jvalue);
+ ffi_cif cif;
+
+ char *p = (char *) __builtin_alloca (param_count * size_per_arg);
+ // Overallocate to get correct alignment.
+ void **values = (void **)
+ __builtin_alloca (param_count * sizeof (void *));
+
+ int i = 0;
+ if (needs_this)
+ {
+ // The `NULL' type is `Object'.
+ argtypes[i] = get_ffi_type (NULL);
+ values[i] = p;
+ memcpy (p, &obj, sizeof (jobject));
+ p += size_per_arg;
+ ++i;
+ }
+
+ for (int arg = 0; i < param_count; ++i, ++arg)
+ {
+ int tsize;
+
+ argtypes[i] = get_ffi_type (paramelts[arg]);
+ if (paramelts[arg]->isPrimitive())
+ tsize = paramelts[arg]->size();
+ else
+ tsize = sizeof (jobject);
+
+ // Copy appropriate bits from the jvalue into the ffi array.
+ // FIXME: we could do this copying all in one loop, above, by
+ // over-allocating a bit.
+ // How do we do this without breaking big-endian platforms?
+ values[i] = p;
+ memcpy (p, &args[arg], tsize);
+ p += size_per_arg;
+ }
+
+ if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, param_count,
+ rtype, argtypes) != FFI_OK)
+ throw new java::lang::VirtualMachineError(JvNewStringLatin1("internal error: ffi_prep_cif failed"));
+
+ using namespace java::lang;
+ using namespace java::lang::reflect;
+
+ union
+ {
+ ffi_arg i;
+ jobject o;
+ jlong l;
+ jfloat f;
+ jdouble d;
+ } ffi_result;
+
+ switch (rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ break;
+ case FFI_TYPE_SINT8:
+ result->b = 0;
+ break;
+ case FFI_TYPE_SINT16:
+ result->s = 0;
+ break;
+ case FFI_TYPE_UINT16:
+ result->c = 0;
+ break;
+ case FFI_TYPE_SINT32:
+ result->i = 0;
+ break;
+ case FFI_TYPE_SINT64:
+ result->j = 0;
+ break;
+ case FFI_TYPE_FLOAT:
+ result->f = 0;
+ break;
+ case FFI_TYPE_DOUBLE:
+ result->d = 0;
+ break;
+ case FFI_TYPE_POINTER:
+ result->l = 0;
+ break;
+ default:
+ JvFail ("Unknown ffi_call return type");
+ break;
+ }
+
+ void *ncode;
+
+ // FIXME: If a vtable index is -1 at this point it is invalid, so we
+ // have to use the ncode.
+ //
+ // This can happen because methods in final classes don't have
+ // vtable entries, but _Jv_isVirtualMethod() doesn't know that. We
+ // could solve this problem by allocating a vtable index for methods
+ // in final classes.
+ if (is_virtual_call
+ && ! Modifier::isFinal (meth->accflags)
+ && (_Jv_ushort)-1 != meth->index)
+ {
+ _Jv_VTable *vtable = *(_Jv_VTable **) obj;
+ if (iface == NULL)
+ {
+ if (is_jni_call && Modifier::isAbstract (meth->accflags))
+ {
+ // With JNI we don't know if this is an interface call
+ // or a call to an abstract method. Look up the method
+ // by name, the slow way.
+ _Jv_Method *concrete_meth
+ = _Jv_LookupDeclaredMethod (vtable->clas,
+ meth->name,
+ meth->signature,
+ NULL);
+ if (concrete_meth == NULL
+ || concrete_meth->ncode == NULL
+ || Modifier::isAbstract(concrete_meth->accflags))
+ throw new java::lang::IncompatibleClassChangeError
+ (_Jv_GetMethodString (vtable->clas, meth));
+ ncode = concrete_meth->ncode;
+ }
+ else
+ ncode = vtable->get_method (meth->index);
+ }
+ else
+ ncode = _Jv_LookupInterfaceMethodIdx (vtable->clas, iface,
+ meth->index);
+ }
+ else
+ {
+ ncode = meth->ncode;
+ }
+
+ try
+ {
+ ffi_call (&cif, (void (*)()) ncode, &ffi_result, values);
+ }
+ catch (Throwable *ex)
+ {
+ // For JNI we just throw the real error. For reflection, we
+ // wrap the underlying method's exception in an
+ // InvocationTargetException.
+ if (! is_jni_call)
+ ex = new InvocationTargetException (ex);
+ throw ex;
+ }
+
+ // Since ffi_call returns integer values promoted to a word, use
+ // a narrowing conversion for jbyte, jchar, etc. results.
+ // Note that boolean is handled either by the FFI_TYPE_SINT8 or
+ // FFI_TYPE_SINT32 case.
+ if (is_constructor)
+ result->l = obj;
+ else
+ {
+ switch (rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ break;
+ case FFI_TYPE_SINT8:
+ result->b = (jbyte)ffi_result.i;
+ break;
+ case FFI_TYPE_SINT16:
+ result->s = (jshort)ffi_result.i;
+ break;
+ case FFI_TYPE_UINT16:
+ result->c = (jchar)ffi_result.i;
+ break;
+ case FFI_TYPE_SINT32:
+ result->i = (jint)ffi_result.i;
+ break;
+ case FFI_TYPE_SINT64:
+ result->j = (jlong)ffi_result.l;
+ break;
+ case FFI_TYPE_FLOAT:
+ result->f = (jfloat)ffi_result.f;
+ break;
+ case FFI_TYPE_DOUBLE:
+ result->d = (jdouble)ffi_result.d;
+ break;
+ case FFI_TYPE_POINTER:
+ result->l = (jobject)ffi_result.o;
+ break;
+ default:
+ JvFail ("Unknown ffi_call return type");
+ break;
+ }
+ }
+#else
+ throw new java::lang::UnsupportedOperationException(JvNewStringLatin1("reflection not available in this build"));
+#endif // USE_LIBFFI
+}
+
+// This is another version of _Jv_CallAnyMethodA, but this one does
+// more checking and is used by the reflection (and not JNI) code.
+jobject
+_Jv_CallAnyMethodA (jobject obj,
+ jclass return_type,
+ jmethodID meth,
+ jboolean is_constructor,
+ JArray<jclass> *parameter_types,
+ jobjectArray args,
+ jclass iface)
+{
+ if (parameter_types->length == 0 && args == NULL)
+ {
+ // The JDK accepts this, so we do too.
+ }
+ else if (parameter_types->length != args->length)
+ throw new java::lang::IllegalArgumentException;
+
+ int param_count = parameter_types->length;
+
+ jclass *paramelts = elements (parameter_types);
+ jobject *argelts = args == NULL ? NULL : elements (args);
+ jvalue argvals[param_count];
+
+#define COPY(Where, What, Type) \
+ do { \
+ Type val = (What); \
+ memcpy ((Where), &val, sizeof (Type)); \
+ } while (0)
+
+ for (int i = 0; i < param_count; ++i)
+ {
+ jclass k = argelts[i] ? argelts[i]->getClass() : NULL;
+ if (paramelts[i]->isPrimitive())
+ {
+ if (! argelts[i]
+ || ! k
+ || ! can_widen (k, paramelts[i]))
+ throw new java::lang::IllegalArgumentException;
+
+ if (paramelts[i] == JvPrimClass (boolean))
+ COPY (&argvals[i],
+ ((java::lang::Boolean *) argelts[i])->booleanValue(),
+ jboolean);
+ else if (paramelts[i] == JvPrimClass (char))
+ COPY (&argvals[i],
+ ((java::lang::Character *) argelts[i])->charValue(),
+ jchar);
+ else
+ {
+ java::lang::Number *num = (java::lang::Number *) argelts[i];
+ if (paramelts[i] == JvPrimClass (byte))
+ COPY (&argvals[i], num->byteValue(), jbyte);
+ else if (paramelts[i] == JvPrimClass (short))
+ COPY (&argvals[i], num->shortValue(), jshort);
+ else if (paramelts[i] == JvPrimClass (int))
+ COPY (&argvals[i], num->intValue(), jint);
+ else if (paramelts[i] == JvPrimClass (long))
+ COPY (&argvals[i], num->longValue(), jlong);
+ else if (paramelts[i] == JvPrimClass (float))
+ COPY (&argvals[i], num->floatValue(), jfloat);
+ else if (paramelts[i] == JvPrimClass (double))
+ COPY (&argvals[i], num->doubleValue(), jdouble);
+ }
+ }
+ else
+ {
+ if (argelts[i] && ! paramelts[i]->isAssignableFrom (k))
+ throw new java::lang::IllegalArgumentException;
+ COPY (&argvals[i], argelts[i], jobject);
+ }
+ }
+
+ jvalue ret_value;
+ _Jv_CallAnyMethodA (obj, return_type, meth, is_constructor,
+ _Jv_isVirtualMethod (meth),
+ parameter_types, argvals, &ret_value,
+ false, iface);
+
+ jobject r;
+#define VAL(Wrapper, Field) (new Wrapper (ret_value.Field))
+ if (is_constructor)
+ r = ret_value.l;
+ else if (return_type == JvPrimClass (byte))
+ r = VAL (java::lang::Byte, b);
+ else if (return_type == JvPrimClass (short))
+ r = VAL (java::lang::Short, s);
+ else if (return_type == JvPrimClass (int))
+ r = VAL (java::lang::Integer, i);
+ else if (return_type == JvPrimClass (long))
+ r = VAL (java::lang::Long, j);
+ else if (return_type == JvPrimClass (float))
+ r = VAL (java::lang::Float, f);
+ else if (return_type == JvPrimClass (double))
+ r = VAL (java::lang::Double, d);
+ else if (return_type == JvPrimClass (boolean))
+ r = VAL (java::lang::Boolean, z);
+ else if (return_type == JvPrimClass (char))
+ r = VAL (java::lang::Character, c);
+ else if (return_type == JvPrimClass (void))
+ r = NULL;
+ else
+ {
+ JvAssert (return_type == NULL || ! return_type->isPrimitive());
+ r = ret_value.l;
+ }
+
+ return r;
+}
diff --git a/libjava/java/lang/reflect/natVMProxy.cc b/libjava/java/lang/reflect/natVMProxy.cc
new file mode 100644
index 000000000..4c3fd74f9
--- /dev/null
+++ b/libjava/java/lang/reflect/natVMProxy.cc
@@ -0,0 +1,459 @@
+// natVMProxy.cc -- Implementation of VMProxy methods.
+
+/* Copyright (C) 2006, 2007
+ Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// The idea of behind this code is to utilize libffi's ability to
+// create closures to provide a fast "cut-through" way to generate
+// proxy classes. Instead of generating bytecode and then
+// interpreting that, we copy the method definitions for each of the
+// methods we're supposed to be prxying and generate a libffi closure
+// for each one.
+
+#include <config.h>
+#include <platform.h>
+#include <sysdep/descriptor.h>
+
+#include <limits.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#include <gcj/cni.h>
+#include <gcj/javaprims.h>
+#include <jvm.h>
+#include <jni.h>
+#include <java-threads.h>
+#include <java-interp.h>
+#include <ffi.h>
+#include <execution.h>
+#include <gcj/method.h>
+
+#include <gnu/gcj/runtime/BootClassLoader.h>
+#include <java/lang/Class.h>
+#include <java/lang/ClassCastException.h>
+#include <java/lang/Error.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/Integer.h>
+#include <java/lang/StringBuffer.h>
+#include <java/lang/UnsupportedOperationException.h>
+#include <java/lang/VMClassLoader.h>
+#include <java/lang/VMCompiler.h>
+#include <java/lang/reflect/InvocationHandler.h>
+#include <java/lang/reflect/Method.h>
+#include <java/lang/reflect/Proxy$ClassFactory.h>
+#include <java/lang/reflect/Proxy$ProxyData.h>
+#include <java/lang/reflect/Proxy.h>
+#include <java/lang/reflect/UndeclaredThrowableException.h>
+#include <java/lang/reflect/VMProxy.h>
+
+#include <java/lang/Byte.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+
+
+using namespace java::lang::reflect;
+using namespace java::lang;
+
+#ifndef INTERPRETER
+jclass
+java::lang::reflect::VMProxy::generateProxyClass
+ (ClassLoader *, Proxy$ProxyData *)
+{
+ throw new UnsupportedOperationException (
+ JvNewStringLatin1 ("Interpreter not available"));
+}
+#else
+typedef void (*closure_fun) (ffi_cif*, void*, void**, void*);
+static void *ncode (int method_index, jclass klass, _Jv_Method *self, closure_fun fun);
+static void run_proxy (ffi_cif*, void*, void**, void*);
+
+typedef jobject invoke_t (jobject, Proxy *, Method *, JArray< jobject > *);
+
+// True if pc points to a proxy frame.
+
+bool
+_Jv_is_proxy (void *pc)
+{
+ return pc == UNWRAP_FUNCTION_DESCRIPTOR ((void*)&run_proxy);
+}
+
+// Generate a proxy class by using libffi closures for each entry
+// point.
+
+jclass
+java::lang::reflect::VMProxy::generateProxyClass
+ (ClassLoader *loader, Proxy$ProxyData *d)
+{
+ // If we're precompiling, generate bytecode and allow VMCompiler to
+ // precompile it.
+ if (VMCompiler::precompiles ())
+ return (new Proxy$ClassFactory(d))->generate(loader);
+
+ jclass klass = new Class ();
+
+ // Synchronize on the class, so that it is not attempted initialized
+ // until we're done.
+ JvSynchronize sync (klass);
+
+ klass->superclass = &Proxy::class$;
+ klass->engine = &_Jv_soleIndirectCompiledEngine;
+ klass->size_in_bytes = -1;
+ klass->vtable_method_count = -1;
+
+ // Declare private static transient java.lang.reflect.Method[] $Proxy0.m
+ klass->field_count = klass->static_field_count = 1;
+ klass->fields = (_Jv_Field*)_Jv_AllocRawObj (sizeof (_Jv_Field));
+ klass->fields[0].name = _Jv_makeUtf8Const ("m");
+ klass->fields[0].type = d->methods->getClass();
+ klass->fields[0].flags = (Modifier::PRIVATE | Modifier::STATIC
+ | Modifier::TRANSIENT);
+
+ // Record the defining loader. For the bootstrap class loader,
+ // we record NULL.
+ if (loader != VMClassLoader::bootLoader)
+ klass->loader = loader;
+
+ {
+ StringBuffer *sb = new StringBuffer();
+ sb->append(JvNewStringLatin1 ("$Proxy"));
+ sb->append(Integer::toString (d->id));
+ klass->name = _Jv_makeUtf8Const (sb->toString());
+ }
+
+ // Allocate space for the interfaces.
+ klass->interface_count = d->interfaces->length;
+ klass->interfaces = (jclass*) _Jv_AllocRawObj (klass->interface_count
+ *sizeof (jclass));
+ for (int i = 0; i < klass->interface_count; i++)
+ klass->interfaces[i] = elements(d->interfaces)[i];
+
+ size_t count = d->methods->length;
+
+ {
+ size_t total_count = count + Proxy::class$.method_count + 1;
+ if (total_count >= 65536)
+ throw new IllegalArgumentException ();
+ // Allocate space for the methods. This is a worst case
+ // estimate.
+ klass->methods
+ = (_Jv_Method *) _Jv_AllocRawObj (sizeof (_Jv_Method)
+ * total_count);
+ }
+
+ jshort &method_count = klass->method_count;
+
+ // Copy all reachable methods from Proxy.
+ for (int i = 0; i < Proxy::class$.method_count; i++)
+ {
+ if (_Jv_CheckAccess (klass, &Proxy::class$,
+ Proxy::class$.methods[i].accflags))
+ {
+ klass->methods[method_count] = Proxy::class$.methods[i];
+ method_count++;
+ }
+ }
+
+ _Jv_Method *init_method
+ = (_Jv_Linker::search_method_in_class
+ (klass, klass,
+ _Jv_makeUtf8Const ("<init>"),
+ _Jv_makeUtf8Const ("(Ljava.lang.reflect.InvocationHandler;)V"),
+ false));
+ init_method->accflags |= Modifier::PUBLIC;
+
+ // Create the methods for all of the interfaces.
+ for (size_t i = 0; i < count; i++)
+ {
+ _Jv_Method &method = klass->methods[method_count++];
+ const _Jv_Method &imethod
+ = *_Jv_FromReflectedMethod (elements(d->methods)[i]);
+ // We use a shallow copy of IMETHOD rather than a deep copy;
+ // this means that the pointer fields of METHOD point into the
+ // interface. As long as this subclass of Proxy is reachable,
+ // the interfaces of which it is a proxy will also be reachable,
+ // so this is safe.
+ method = imethod;
+ method.ncode = ncode (i, klass, &method, run_proxy);
+ method.accflags &= ~Modifier::ABSTRACT;
+ }
+
+ _Jv_Linker::layout_vtable_methods (klass);
+ _Jv_RegisterInitiatingLoader (klass, klass->loader);
+
+ // Set $Proxy0.m to point to the methods arrray
+ java::lang::reflect::Field *f
+ = klass->getDeclaredField (JvNewStringLatin1 ("m"));
+ f->flag = true;
+ f->set(NULL, d->methods);
+
+ return klass;
+}
+
+
+// Box things with primitive types.
+static inline jobject
+box (void *thing, jclass klass, FFI_TYPE type)
+{
+ jobject o;
+
+ switch (type)
+ {
+ case FFI_TYPE_VOID:
+ return NULL;
+
+ case FFI_TYPE_POINTER:
+ o = *(jobject*)thing;
+ return o;
+
+ default:
+ ;
+ }
+
+ if (klass == JvPrimClass (byte))
+ o = new Byte (*(jbyte*)thing);
+ else if (klass == JvPrimClass (short))
+ o = new Short (*(jshort*)thing);
+ else if (klass == JvPrimClass (int))
+ o = new Integer (*(jint*)thing);
+ else if (klass == JvPrimClass (long))
+ o = new Long (*(jlong*)thing);
+ else if (klass == JvPrimClass (float))
+ o = new Float (*(jfloat*)thing);
+ else if (klass == JvPrimClass (double))
+ o = new Double (*(jdouble*)thing);
+ else if (klass == JvPrimClass (boolean))
+ o = new Boolean (*(jboolean*)thing);
+ else if (klass == JvPrimClass (char))
+ o = new Character (*(jchar*)thing);
+ else
+ JvFail ("Bad ffi type in proxy");
+
+ return o;
+}
+
+
+// Unbox things with primitive types.
+static inline void
+unbox (jobject o, jclass klass, void *rvalue, FFI_TYPE type)
+{
+ switch (type)
+ {
+ case FFI_TYPE_VOID:
+ return;
+
+ case FFI_TYPE_POINTER:
+ _Jv_CheckCast (klass, o);
+ *(jobject*)rvalue = o;
+ return;
+
+ default:
+ ;
+ }
+
+ // If the value returned ... is null and the interface method's
+ // return type is primitive, then a NullPointerException will be
+ // thrown ...
+ if (klass == JvPrimClass (byte))
+ {
+ _Jv_CheckCast (&Byte::class$, o);
+ *(jbyte*)rvalue = ((Byte*)o)->byteValue();
+ }
+ else if (klass == JvPrimClass (short))
+ {
+ _Jv_CheckCast (&Short::class$, o);
+ *(jshort*)rvalue = ((Short*)o)->shortValue();
+ }
+ else if (klass == JvPrimClass (int))
+ {
+ _Jv_CheckCast (&Integer::class$, o);
+ *(jint*)rvalue = ((Integer*)o)->intValue();
+ }
+ else if (klass == JvPrimClass (long))
+ {
+ _Jv_CheckCast (&Long::class$, o);
+ *(jlong*)rvalue = ((Long*)o)->longValue();
+ }
+ else if (klass == JvPrimClass (float))
+ {
+ _Jv_CheckCast (&Float::class$, o);
+ *(jfloat*)rvalue = ((Float*)o)->floatValue();
+ }
+ else if (klass == JvPrimClass (double))
+ {
+ _Jv_CheckCast (&Double::class$, o);
+ *(jdouble*)rvalue = ((Double*)o)->doubleValue();
+ }
+ else if (klass == JvPrimClass (boolean))
+ {
+ _Jv_CheckCast (&Boolean::class$, o);
+ *(jboolean*)rvalue = ((Boolean*)o)->booleanValue();
+ }
+ else if (klass == JvPrimClass (char))
+ {
+ _Jv_CheckCast (&Character::class$, o);
+ *(jchar*)rvalue = ((Character*)o)->charValue();
+ }
+ else
+ JvFail ("Bad ffi type in proxy");
+}
+
+// _Jv_getFieldInternal is declared as a friend of reflect.Field in
+// libjava/headers.txt. This gives us a way to call the private
+// method Field.get (Class caller, Object obj).
+extern inline jobject
+_Jv_getFieldInternal (java::lang::reflect::Field *f, jclass c, jobject o)
+{
+ return f->get(c, o);
+}
+
+// run_proxy is the entry point for all proxy methods. It boxes up
+// all the arguments and then invokes the invocation handler's invoke()
+// method. Exceptions are caught and propagated.
+
+typedef struct {
+ ffi_closure closure;
+ _Jv_ClosureList list;
+ ffi_cif cif;
+ _Jv_Method *self;
+ int method_index;
+ ffi_type *arg_types[0];
+} ncode_closure;
+
+static void
+run_proxy (ffi_cif *cif,
+ void *rvalue,
+ void **args,
+ void*user_data)
+{
+ using namespace java::lang::reflect;
+
+ Proxy *proxy = *(Proxy**)args[0];
+ ncode_closure *self = (ncode_closure *) user_data;
+
+ jclass proxyClass = proxy->getClass();
+
+ // FRAME_DESC registers this particular invocation as the top-most
+ // interpreter frame. This lets the stack tracing code (for
+ // Throwable) print information about the Proxy being run rather
+ // than about Proxy.class itself. FRAME_DESC has a destructor so it
+ // cleans up automatically when this proxy invocation returns.
+ Thread *thread = Thread::currentThread();
+ _Jv_InterpFrame frame_desc (self->self, thread, proxyClass,
+ NULL, frame_proxy);
+
+ // The method to invoke is saved in $Proxy0.m[method_index].
+ // FIXME: We could somewhat improve efficiency by storing a pointer
+ // to the method (rather than its index) in ncode_closure. This
+ // would avoid the lookup, but it probably wouldn't make a huge
+ // difference. We'd still have to save the method array because
+ // ncode structs are not scanned by the gc.
+ Field *f = proxyClass->getDeclaredField (JvNewStringLatin1 ("m"));
+ JArray<Method*> *methods
+ = (JArray<Method*>*)_Jv_getFieldInternal (f, proxyClass, NULL);
+ Method *meth = elements(methods)[self->method_index];
+
+ JArray<jclass> *parameter_types = meth->internalGetParameterTypes ();
+ JArray<jclass> *exception_types = meth->internalGetExceptionTypes ();
+
+ InvocationHandler *handler = proxy->h;
+ JArray<jobject> *argsArray = NULL;
+ jobject *jargs = NULL;
+ if (parameter_types->length)
+ {
+ void *poo
+ = _Jv_NewObjectArray (parameter_types->length, &Object::class$, NULL);
+ argsArray = (JArray<jobject> *) poo;
+ jargs = elements(argsArray);
+ }
+
+ // FIXME: It must be possible to use fast interface dispatch here,
+ // but I've not quite figured out how to do it.
+ invoke_t *invoke
+ = (invoke_t *)(_Jv_LookupInterfaceMethod
+ (handler->getClass (),
+ _Jv_makeUtf8Const ("invoke"),
+ (_Jv_makeUtf8Const
+ ("(Ljava.lang.Object;Ljava.lang.reflect.Method;[Ljava.lang.Object;)"
+ "Ljava.lang.Object;"))));
+
+ // Copy and box all the args.
+ int index = 1;
+ for (int i = 0; i < parameter_types->length; i++, index++)
+ jargs[i] = box (args[index], elements(parameter_types)[i],
+ cif->arg_types[index]->type);
+
+ jobject ret;
+ try
+ {
+ ret = invoke (handler, proxy, meth, argsArray);
+ }
+ catch (Throwable *t)
+ {
+ if (_Jv_IsInstanceOf (t, &RuntimeException::class$)
+ || _Jv_IsInstanceOf (t, &Error::class$))
+ throw t;
+
+ Class **throwables = elements (exception_types);
+ for (int i = 0; i < exception_types->length; i++)
+ if (_Jv_IsInstanceOf (t, throwables[i]))
+ throw t;
+
+ throw new UndeclaredThrowableException (t);
+ }
+
+ unbox (ret, meth->return_type, rvalue, cif->rtype->type);
+}
+
+
+// Given a method and a closure function, create libffi CIF and return
+// the address of its closure.
+
+static void *
+ncode (int method_index, jclass klass, _Jv_Method *self, closure_fun fun)
+{
+ using namespace java::lang::reflect;
+
+ jboolean staticp = (self->accflags & Modifier::STATIC) != 0;
+ int arg_count = _Jv_count_arguments (self->signature, staticp);
+
+ void *code;
+ ncode_closure *closure =
+ (ncode_closure*)ffi_closure_alloc (sizeof (ncode_closure)
+ + arg_count * sizeof (ffi_type*),
+ &code);
+ closure->method_index = method_index;
+ closure->list.registerClosure (klass, closure);
+
+ _Jv_init_cif (self->signature,
+ arg_count,
+ staticp,
+ &closure->cif,
+ &closure->arg_types[0],
+ NULL);
+ closure->self = self;
+
+ JvAssert ((self->accflags & Modifier::NATIVE) == 0);
+
+ ffi_prep_closure_loc (&closure->closure,
+ &closure->cif,
+ fun,
+ code,
+ code);
+
+ self->ncode = code;
+ return self->ncode;
+}
+
+#endif // INTERPRETER