From: twisti Date: Fri, 22 Jun 2007 11:15:47 +0000 (+0000) Subject: * configure.ac, X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=cacao.git;a=commitdiff_plain;h=773281400f5bab23de28144498baeffcfed4159a * configure.ac, contrib/mapfile-vers-product, m4/classpath.m4, src/cacao/Makefile.am, src/lib/Makefile.am, src/lib/gnu/java/lang/reflect, src/lib/gnu/java/lang/reflect/Field.java, src/lib/gnu/java/lang/reflect/Method.java, src/lib/gnu/sun, src/lib/gnu/sun/misc, src/lib/gnu/sun/misc/Unsafe.java, src/native/include/Makefile.am, src/native/jni.c, src/native/jni.h, src/native/native.c, src/native/native.h, src/native/vm/Makefile.am, src/native/vm/gnu/java_lang_reflect_Field.c, src/native/vm/gnu/java_lang_reflect_Method.c, src/native/vm/java_lang_Class.c, src/native/vm/java_lang_ClassLoader.c, src/native/vm/java_lang_Object.c, src/native/vm/java_lang_Object.h, src/native/vm/java_lang_Thread.c, src/native/vm/java_lang_reflect_Constructor.c, src/native/vm/java_lang_reflect_Method.c, src/native/vm/nativevm.c, src/native/vm/nativevm.h, src/native/vm/sun, src/native/vm/sun/Makefile.am, src/native/vm/sun/jvm.c, src/native/vm/sun_misc_Unsafe.c, src/threads/native/threads.c, src/threads/threads-common.c, src/vm/properties.c, src/vm/vm.c, src/vm/vm.h, src/vmcore/class.h, src/vmcore/field.c, src/vmcore/field.h, src/vmcore/utf8.c, src/vmcore/utf8.h: Initial support for using OpenJDK libraries as Java core libraries. --- diff --git a/configure.ac b/configure.ac index af6829398..3b57da342 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA dnl 02110-1301, USA. dnl -dnl $Id: configure.ac 8126 2007-06-21 10:42:35Z twisti $ +dnl $Id: configure.ac 8132 2007-06-22 11:15:47Z twisti $ dnl Process this file with autoconf to produce a configure script. @@ -963,6 +963,7 @@ AC_CONFIG_FILES([Makefile] [src/native/vm/Makefile] [src/native/vm/cldc1.1/Makefile] [src/native/vm/gnu/Makefile] + [src/native/vm/sun/Makefile] [src/scripts/Makefile] [src/scripts/java] [src/threads/Makefile] diff --git a/contrib/mapfile-vers-product b/contrib/mapfile-vers-product new file mode 100644 index 000000000..5d23dfa6a --- /dev/null +++ b/contrib/mapfile-vers-product @@ -0,0 +1,286 @@ +# +# @(#)mapfile-vers-product 1.17 07/05/05 17:03:55 +# + +# +# Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code 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 +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# +# + +# Define public interface. + +SUNWprivate_1.1 { + global: + # CACAO + vm_createjvm; + vm_run; + + # JNI + JNI_CreateJavaVM; + JNI_GetCreatedJavaVMs; + JNI_GetDefaultJavaVMInitArgs; + + # JVM + JVM_Accept; + JVM_ActiveProcessorCount; + JVM_AllocateNewArray; + JVM_AllocateNewObject; + JVM_ArrayCopy; + JVM_AssertionStatusDirectives; + JVM_Available; + JVM_Bind; + JVM_ClassDepth; + JVM_ClassLoaderDepth; + JVM_Clone; + JVM_Close; + JVM_CX8Field; + JVM_CompileClass; + JVM_CompileClasses; + JVM_CompilerCommand; + JVM_Connect; + JVM_ConstantPoolGetClassAt; + JVM_ConstantPoolGetClassAtIfLoaded; + JVM_ConstantPoolGetDoubleAt; + JVM_ConstantPoolGetFieldAt; + JVM_ConstantPoolGetFieldAtIfLoaded; + JVM_ConstantPoolGetFloatAt; + JVM_ConstantPoolGetIntAt; + JVM_ConstantPoolGetLongAt; + JVM_ConstantPoolGetMethodAt; + JVM_ConstantPoolGetMethodAtIfLoaded; + JVM_ConstantPoolGetMemberRefInfoAt; + JVM_ConstantPoolGetSize; + JVM_ConstantPoolGetStringAt; + JVM_ConstantPoolGetUTF8At; + JVM_CountStackFrames; + JVM_CurrentClassLoader; + JVM_CurrentLoadedClass; + JVM_CurrentThread; + JVM_CurrentTimeMillis; + JVM_DefineClass; + JVM_DefineClassWithSource; + JVM_DesiredAssertionStatus; + JVM_DisableCompiler; + JVM_DoPrivileged; + JVM_DumpAllStacks; + JVM_DumpThreads; + JVM_EnableCompiler; + JVM_Exit; + JVM_FillInStackTrace; + JVM_FindClassFromClass; + JVM_FindClassFromClassLoader; + JVM_FindLibraryEntry; + JVM_FindLoadedClass; + JVM_FindPrimitiveClass; + JVM_FindSignal; + JVM_FreeMemory; + JVM_GC; + JVM_GetAllThreads; + JVM_GetArrayElement; + JVM_GetArrayLength; + JVM_GetCPClassNameUTF; + JVM_GetCPFieldClassNameUTF; + JVM_GetCPFieldModifiers; + JVM_GetCPFieldNameUTF; + JVM_GetCPFieldSignatureUTF; + JVM_GetCPMethodClassNameUTF; + JVM_GetCPMethodModifiers; + JVM_GetCPMethodNameUTF; + JVM_GetCPMethodSignatureUTF; + JVM_GetCallerClass; + JVM_GetClassAccessFlags; + JVM_GetClassAnnotations; + JVM_GetClassCPEntriesCount; + JVM_GetClassCPTypes; + JVM_GetClassConstantPool; + JVM_GetClassContext; + JVM_GetClassDeclaredConstructors; + JVM_GetClassDeclaredFields; + JVM_GetClassDeclaredMethods; + JVM_GetClassFieldsCount; + JVM_GetClassInterfaces; + JVM_GetClassLoader; + JVM_GetClassMethodsCount; + JVM_GetClassModifiers; + JVM_GetClassName; + JVM_GetClassNameUTF; + JVM_GetClassSignature; + JVM_GetClassSigners; + JVM_GetComponentType; + JVM_GetDeclaredClasses; + JVM_GetDeclaringClass; + JVM_GetEnclosingMethodInfo; + JVM_GetFieldAnnotations; + JVM_GetFieldIxModifiers; + JVM_GetHostName; + JVM_GetInheritedAccessControlContext; + JVM_GetInterfaceVersion; + JVM_GetLastErrorString; + JVM_GetManagement; + JVM_GetMethodAnnotations; + JVM_GetMethodDefaultAnnotationValue; + JVM_GetMethodIxArgsSize; + JVM_GetMethodIxByteCode; + JVM_GetMethodIxByteCodeLength; + JVM_GetMethodIxExceptionIndexes; + JVM_GetMethodIxExceptionTableEntry; + JVM_GetMethodIxExceptionTableLength; + JVM_GetMethodIxExceptionsCount; + JVM_GetMethodIxLocalsCount; + JVM_GetMethodIxMaxStack; + JVM_GetMethodIxModifiers; + JVM_GetMethodIxNameUTF; + JVM_GetMethodIxSignatureUTF; + JVM_GetMethodParameterAnnotations; + JVM_GetPrimitiveArrayElement; + JVM_GetProtectionDomain; + JVM_GetSockName; + JVM_GetSockOpt; + JVM_GetStackAccessControlContext; + JVM_GetStackTraceDepth; + JVM_GetStackTraceElement; + JVM_GetSystemPackage; + JVM_GetSystemPackages; + JVM_GetThreadStateNames; + JVM_GetThreadStateValues; + JVM_GetVersionInfo; + JVM_Halt; + JVM_HoldsLock; + JVM_IHashCode; + JVM_InitAgentProperties; + JVM_InitProperties; + JVM_InitializeCompiler; + JVM_InitializeSocketLibrary; + JVM_InternString; + JVM_Interrupt; + JVM_InvokeMethod; + JVM_IsArrayClass; + JVM_IsConstructorIx; + JVM_IsInterface; + JVM_IsInterrupted; + JVM_IsNaN; + JVM_IsPrimitiveClass; + JVM_IsSameClassPackage; + JVM_IsSilentCompiler; + JVM_IsSupportedJNIVersion; + JVM_IsThreadAlive; + JVM_LatestUserDefinedLoader; + JVM_Listen; + JVM_LoadClass0; + JVM_LoadLibrary; + JVM_Lseek; + JVM_MaxObjectInspectionAge; + JVM_MaxMemory; + JVM_MonitorNotify; + JVM_MonitorNotifyAll; + JVM_MonitorWait; + JVM_NanoTime; + JVM_NativePath; + JVM_NewArray; + JVM_NewInstanceFromConstructor; + JVM_NewMultiArray; + JVM_OnExit; + JVM_Open; + JVM_PrintStackTrace; + JVM_RaiseSignal; + JVM_RawMonitorCreate; + JVM_RawMonitorDestroy; + JVM_RawMonitorEnter; + JVM_RawMonitorExit; + JVM_Read; + JVM_Recv; + JVM_RecvFrom; + JVM_RegisterSignal; + JVM_ReleaseUTF; + JVM_ResolveClass; + JVM_ResumeThread; + JVM_Send; + JVM_SendTo; + JVM_SetArrayElement; + JVM_SetClassSigners; + JVM_SetLength; + JVM_SetPrimitiveArrayElement; + JVM_SetProtectionDomain; + JVM_SetSockOpt; + JVM_SetThreadPriority; + JVM_Sleep; + JVM_Socket; + JVM_SocketAvailable; + JVM_SocketClose; + JVM_SocketShutdown; + JVM_StartThread; + JVM_StopThread; + JVM_SuspendThread; + JVM_SupportsCX8; + JVM_Sync; + JVM_Timeout; + JVM_TotalMemory; + JVM_TraceInstructions; + JVM_TraceMethodCalls; + JVM_UnloadLibrary; + JVM_Write; + JVM_Yield; + JVM_handle_linux_signal; + + # Old reflection routines + # These do not need to be present in the product build in JDK 1.4 + # but their code has not been removed yet because there will not + # be a substantial code savings until JVM_InvokeMethod and + # JVM_NewInstanceFromConstructor can also be removed; see + # reflectionCompat.hpp. + JVM_GetClassConstructor; + JVM_GetClassConstructors; + JVM_GetClassField; + JVM_GetClassFields; + JVM_GetClassMethod; + JVM_GetClassMethods; + JVM_GetField; + JVM_GetPrimitiveField; + JVM_NewInstance; + JVM_SetField; + JVM_SetPrimitiveField; + + # Needed for dropping VM into JDK 1.3.x, 1.4 + _JVM_native_threads; + jdk_sem_init; + jdk_sem_post; + jdk_sem_wait; + jdk_pthread_sigmask; + jdk_waitpid; + + # miscellaneous functions + jio_fprintf; + jio_printf; + jio_snprintf; + jio_vfprintf; + jio_vsnprintf; + fork1; + + # Needed because there is no JVM interface for this. + sysThreadAvailableStackWithSlack; + + # This is for Forte Analyzer profiling support. + AsyncGetCallTrace; + local: + *; +}; + diff --git a/m4/classpath.m4 b/m4/classpath.m4 index c54ef6120..b5a322b8f 100644 --- a/m4/classpath.m4 +++ b/m4/classpath.m4 @@ -22,7 +22,7 @@ dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA dnl 02110-1301, USA. dnl -dnl $Id: configure.ac 7228 2007-01-19 01:13:48Z edwin $ +dnl $Id$ dnl which Java core library should we use @@ -30,7 +30,7 @@ dnl which Java core library should we use AC_DEFUN([AC_CHECK_WITH_CLASSPATH],[ AC_MSG_CHECKING(which Java core library to use) AC_ARG_WITH([classpath], - [AS_HELP_STRING(--with-classpath=,specifies which type of classpath to use as Java core library (cldc1.1,gnu) [[default=gnu]])], + [AS_HELP_STRING(--with-classpath=,specifies which type of classpath to use as Java core library (cldc1.1,gnu,sun) [[default=gnu]])], [case "${withval}" in cldc1.1) WITH_CLASSPATH=cldc1.1 @@ -42,6 +42,11 @@ AC_ARG_WITH([classpath], AC_DEFINE([WITH_CLASSPATH_GNU], 1, [use GNU Classpath]) AC_SUBST(WITH_CLASSPATH_GNU) ;; + sun) + WITH_CLASSPATH=sun + AC_DEFINE([WITH_CLASSPATH_SUN], 1, [use Sun's Java SE classes]) + AC_SUBST(WITH_CLASSPATH_SUN) + ;; *) AC_MSG_ERROR(unknown classpath ${withval}) ;; @@ -52,6 +57,7 @@ AC_ARG_WITH([classpath], AC_MSG_RESULT(${WITH_CLASSPATH}) AM_CONDITIONAL([WITH_CLASSPATH_CLDC1_1], test x"${WITH_CLASSPATH}" = "xcldc1.1") AM_CONDITIONAL([WITH_CLASSPATH_GNU], test x"${WITH_CLASSPATH}" = "xgnu") +AM_CONDITIONAL([WITH_CLASSPATH_SUN], test x"${WITH_CLASSPATH}" = "xsun") ]) @@ -110,11 +116,19 @@ AC_ARG_WITH([classpath-includedir], [CLASSPATH_INCLUDEDIR=${CLASSPATH_PREFIX}/include]) AC_MSG_RESULT(${CLASSPATH_INCLUDEDIR}) +if test x"${WITH_CLASSPATH}" = "xsun"; then + AC_CHECK_HEADER([${CLASSPATH_INCLUDEDIR}/${OS_DIR}/jni_md.h], + [AC_DEFINE_UNQUOTED([CLASSPATH_JNI_MD_H], "${CLASSPATH_INCLUDEDIR}/${OS_DIR}/jni_md.h", [Java core library jni_md.h header])], + [AC_MSG_ERROR(cannot find jni_md.h)]) +else + AC_CHECK_HEADER([${CLASSPATH_INCLUDEDIR}/jni_md.h], + [AC_DEFINE_UNQUOTED([CLASSPATH_JNI_MD_H], "${CLASSPATH_INCLUDEDIR}/jni_md.h", [Java core library jni_md.h header])], + [AC_MSG_ERROR(cannot find jni_md.h)]) +fi + AC_CHECK_HEADER([${CLASSPATH_INCLUDEDIR}/jni.h], [AC_DEFINE_UNQUOTED([CLASSPATH_JNI_H], "${CLASSPATH_INCLUDEDIR}/jni.h", [Java core library jni.h header])], - [AC_MSG_ERROR(cannot find jni.h)]) - -AC_CHECK_HEADER([${CLASSPATH_INCLUDEDIR}/jni_md.h], - [AC_DEFINE_UNQUOTED([CLASSPATH_JNI_MD_H], "${CLASSPATH_INCLUDEDIR}/jni_md.h", [Java core library jni_md.h header])], - [AC_MSG_ERROR(cannot find jni_md.h)]) + [AC_MSG_ERROR(cannot find jni.h)], + [#define __GCJ_JNI_MD_H__ + #include CLASSPATH_JNI_MD_H]) ]) diff --git a/src/cacao/Makefile.am b/src/cacao/Makefile.am index 4584b73aa..85b8cc724 100644 --- a/src/cacao/Makefile.am +++ b/src/cacao/Makefile.am @@ -24,7 +24,7 @@ ## ## Contact: cacao@cacaojvm.org ## -## $Id: Makefile.am 7338 2007-02-13 00:17:22Z twisti $ +## $Id: Makefile.am 8132 2007-06-22 11:15:47Z twisti $ ## Process this file with automake to produce Makefile.in @@ -49,6 +49,11 @@ lib_LTLIBRARIES = \ libjvm_la_LDFLAGS = \ -release $(PACKAGE_VERSION) +if WITH_CLASSPATH_SUN +libjvm_la_LDFLAGS += \ + -Xlinker --version-script=$(top_srcdir)/contrib/mapfile-vers-product +endif + cacao_LDFLAGS += \ -export-dynamic diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index d1217d2a2..efa9fb2dd 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -22,7 +22,7 @@ ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ## 02110-1301, USA. ## -## $Id: Makefile.am 7890 2007-05-09 16:05:58Z twisti $ +## $Id: Makefile.am 8132 2007-06-22 11:15:47Z twisti $ ## Process this file with automake to produce Makefile.in @@ -40,7 +40,10 @@ VM_JAVA_FILES = \ $(top_srcdir)/src/lib/gnu/java/lang/VMString.java \ $(top_srcdir)/src/lib/gnu/java/lang/VMThread.java \ $(top_srcdir)/src/lib/gnu/java/lang/VMThrowable.java \ - $(top_srcdir)/src/lib/gnu/java/security/VMAccessController.java + $(top_srcdir)/src/lib/gnu/java/lang/reflect/Field.java \ + $(top_srcdir)/src/lib/gnu/java/lang/reflect/Method.java \ + $(top_srcdir)/src/lib/gnu/java/security/VMAccessController.java \ + $(top_srcdir)/src/lib/gnu/sun/misc/Unsafe.java VM_CLASS_FILES = \ classes/gnu/classpath/VMStackWalker.class \ @@ -51,7 +54,10 @@ VM_CLASS_FILES = \ classes/java/lang/VMString.class \ classes/java/lang/VMThread.class \ classes/java/lang/VMThrowable.class \ - classes/java/security/VMAccessController.class + classes/java/lang/reflect/Field.class \ + classes/java/lang/reflect/Method.class \ + classes/java/security/VMAccessController.class \ + classes/sun/misc/Unsafe.class if ENABLE_ZLIB pkgdata_DATA = vm.zip diff --git a/src/lib/gnu/java/lang/reflect/Field.java b/src/lib/gnu/java/lang/reflect/Field.java new file mode 100644 index 000000000..efd49d9ef --- /dev/null +++ b/src/lib/gnu/java/lang/reflect/Field.java @@ -0,0 +1,661 @@ +/* java.lang.reflect.Field - reflection of Java fields + Copyright (C) 1998, 2001, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.lang.reflect; + +import gnu.java.lang.ClassHelper; + +import gnu.java.lang.reflect.FieldSignatureParser; + +/** + * The Field class represents a member variable of a class. It also allows + * dynamic access to a member, via reflection. This works for both + * static and instance fields. Operations on Field objects know how to + * do widening conversions, but throw {@link IllegalArgumentException} if + * a narrowing conversion would be necessary. You can query for information + * on this Field regardless of location, but get and set access may be limited + * by Java language access controls. If you can't do it in the compiler, you + * can't normally do it here either.

+ * + * Note: This class returns and accepts types as Classes, even + * primitive types; there are Class types defined that represent each + * different primitive type. They are java.lang.Boolean.TYPE, + * java.lang.Byte.TYPE,, also available as boolean.class, + * byte.class, etc. These are not to be confused with the + * classes java.lang.Boolean, java.lang.Byte, etc., which are + * real classes.

+ * + * 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 + * @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 clazz; + private String name; + private int slot; + + private static final int FIELD_MODIFIERS + = Modifier.FINAL | Modifier.PRIVATE | Modifier.PROTECTED + | Modifier.PUBLIC | Modifier.STATIC | Modifier.TRANSIENT + | Modifier.VOLATILE; + + /** + * This class is uninstantiable except natively. + */ + private Field(Class declaringClass, String name, int slot) + { + this.clazz = declaringClass; + this.name = name; + this.slot = slot; + } + + /** + * Gets the class that declared this field, or the class where this field + * is a non-inherited member. + * @return the class that declared this member + */ + public Class getDeclaringClass() + { + return clazz; + } + + /** + * Gets the name of this field. + * @return the name of this field + */ + public String getName() + { + return name; + } + + /** + * Return the raw modifiers for this field. + * @return the field's modifiers + */ + private native int getModifiersInternal(); + + /** + * Gets the modifiers this field uses. Use the Modifier + * 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 true if they are equal; false if not + */ + public boolean equals(Object o) + { + if (!(o instanceof Field)) + return false; + Field that = (Field)o; + if (this.getDeclaringClass() != that.getDeclaringClass()) + return false; + if (!this.getName().equals(that.getName())) + return false; + if (this.getType() != that.getType()) + return false; + return true; + } + + /** + * Get the hash code for the Field. The Field hash code is the hash code + * of its name XOR'd with the hash code of its class name. + * + * @return the hash code for the object. + */ + public int hashCode() + { + return getDeclaringClass().getName().hashCode() ^ getName().hashCode(); + } + + /** + * Get a String representation of the Field. A Field's String + * representation is "<modifiers> <type> + * <class>.<fieldname>".
Example: + * public transient boolean gnu.parse.Parser.parseComplete + * + * @return the String representation of the Field + */ + public String toString() + { + // 64 is a reasonable buffer initial size for field + StringBuilder sb = new StringBuilder(64); + Modifier.toString(getModifiers(), sb).append(' '); + sb.append(ClassHelper.getUserName(getType())).append(' '); + sb.append(getDeclaringClass().getName()).append('.'); + sb.append(getName()); + return sb.toString(); + } + + public String toGenericString() + { + StringBuilder sb = new StringBuilder(64); + Modifier.toString(getModifiers(), sb).append(' '); + sb.append(getGenericType()).append(' '); + sb.append(getDeclaringClass().getName()).append('.'); + sb.append(getName()); + return sb.toString(); + } + + /** + * Get the value of this Field. If it is primitive, it will be wrapped + * in the appropriate wrapper type (boolean = java.lang.Boolean).

+ * + * If the field is static, o will be ignored. Otherwise, if + * o is null, you get a NullPointerException, + * and if it is incompatible with the declaring class of the field, you + * get an IllegalArgumentException.

+ * + * Next, if this Field enforces access control, your runtime context is + * evaluated, and you may have an IllegalAccessException 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 + * ExceptionInInitializerError.

+ * + * 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 o is not an instance of + * the class or interface declaring this field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #getBoolean(Object) + * @see #getByte(Object) + * @see #getChar(Object) + * @see #getShort(Object) + * @see #getInt(Object) + * @see #getLong(Object) + * @see #getFloat(Object) + * @see #getDouble(Object) + */ + public native Object get(Object o) + throws IllegalAccessException; + + /** + * Get the value of this boolean Field. If the field is static, + * o 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 + * o, or if o is not an instance of the + * declaring class of this field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #get(Object) + */ + public native boolean getBoolean(Object o) + throws IllegalAccessException; + + /** + * Get the value of this byte Field. If the field is static, + * o 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 + * o, or if o is not an instance of the + * declaring class of this field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #get(Object) + */ + public native byte getByte(Object o) + throws IllegalAccessException; + + /** + * Get the value of this Field as a char. If the field is static, + * o 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 + * o, or if o is not an instance + * of the declaring class of this field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #get(Object) + */ + public native char getChar(Object o) + throws IllegalAccessException; + + /** + * Get the value of this Field as a short. If the field is static, + * o 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 o, or if o is not an instance + * of the declaring class of this field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #get(Object) + */ + public native short getShort(Object o) + throws IllegalAccessException; + + /** + * Get the value of this Field as an int. If the field is static, + * o 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 o, or if o is not an + * instance of the declaring class of this field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #get(Object) + */ + public native int getInt(Object o) + throws IllegalAccessException; + + /** + * Get the value of this Field as a long. If the field is static, + * o 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 o, or if o is not an + * instance of the declaring class of this field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #get(Object) + */ + public native long getLong(Object o) + throws IllegalAccessException; + + /** + * Get the value of this Field as a float. If the field is static, + * o 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 o, or if o is + * not an instance of the declaring class of this field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #get(Object) + */ + public native float getFloat(Object o) + throws IllegalAccessException; + + /** + * Get the value of this Field as a double. If the field is static, + * o 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 o, or if + * o is not an instance of the declaring class of this + * field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #get(Object) + */ + public native double getDouble(Object o) + throws IllegalAccessException; + + /** + * Set the value of this Field. If it is a primitive field, the value + * will be unwrapped from the passed object (boolean = java.lang.Boolean).

+ * + * If the field is static, o will be ignored. Otherwise, if + * o is null, you get a NullPointerException, + * and if it is incompatible with the declaring class of the field, you + * get an IllegalArgumentException.

+ * + * Next, if this Field enforces access control, your runtime context is + * evaluated, and you may have an IllegalAccessException 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 IllegalArgumentException; likewise, this error + * happens if value 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 + * ExceptionInInitializerError.

+ * + * 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 value cannot be + * converted by a widening conversion to the underlying type of + * the Field, or if o is not an instance of the class + * declaring this field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #setBoolean(Object, boolean) + * @see #setByte(Object, byte) + * @see #setChar(Object, char) + * @see #setShort(Object, short) + * @see #setInt(Object, int) + * @see #setLong(Object, long) + * @see #setFloat(Object, float) + * @see #setDouble(Object, double) + */ + public native void set(Object o, Object value) + throws IllegalAccessException; + + /** + * Set this boolean Field. If the field is static, o 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 + * o is not an instance of the class declaring this + * field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #set(Object, Object) + */ + public native void setBoolean(Object o, boolean value) + throws IllegalAccessException; + + /** + * Set this byte Field. If the field is static, o 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 o is not an instance + * of the class declaring this field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #set(Object, Object) + */ + public native void setByte(Object o, byte value) + throws IllegalAccessException; + + /** + * Set this char Field. If the field is static, o 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 o is not an instance + * of the class declaring this field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #set(Object, Object) + */ + public native void setChar(Object o, char value) + throws IllegalAccessException; + + /** + * Set this short Field. If the field is static, o 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 o is not an instance + * of the class declaring this field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #set(Object, Object) + */ + public native void setShort(Object o, short value) + throws IllegalAccessException; + + /** + * Set this int Field. If the field is static, o 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 o is not an instance of the + * class declaring this field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #set(Object, Object) + */ + public native void setInt(Object o, int value) + throws IllegalAccessException; + + /** + * Set this long Field. If the field is static, o 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 o is not an instance of the class + * declaring this field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #set(Object, Object) + */ + public native void setLong(Object o, long value) + throws IllegalAccessException; + + /** + * Set this float Field. If the field is static, o 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 o is not an instance of the class declaring this + * field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #set(Object, Object) + */ + public native void setFloat(Object o, float value) + throws IllegalAccessException; + + /** + * Set this double Field. If the field is static, o 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 + * o is not an instance of the class declaring this + * field + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static field triggered + * class initialization, which then failed + * @see #set(Object, Object) + */ + public native void setDouble(Object o, double value) + throws IllegalAccessException; + + /** + * Return the generic type of the field. If the field type is not a generic + * type, the method returns the same as getType(). + * + * @throws GenericSignatureFormatError if the generic signature does + * not conform to the format specified in the Virtual Machine + * specification, version 3. + * @since 1.5 + */ + public Type getGenericType() + { + String signature = getSignature(); + if (signature == null) + return getType(); + FieldSignatureParser p = new FieldSignatureParser(getDeclaringClass(), + signature); + return p.getFieldType(); + } + + /** + * Return the String in the Signature attribute for this field. If there + * is no Signature attribute, return null. + */ + private native String getSignature(); +} diff --git a/src/lib/gnu/java/lang/reflect/Method.java b/src/lib/gnu/java/lang/reflect/Method.java new file mode 100644 index 000000000..59351fdb2 --- /dev/null +++ b/src/lib/gnu/java/lang/reflect/Method.java @@ -0,0 +1,465 @@ +/* java.lang.reflect.Method - reflection of Java methods + Copyright (C) 1998, 2001, 2002, 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.java.lang.ClassHelper; + +import gnu.java.lang.reflect.MethodSignatureParser; + +import java.util.Arrays; + +/** + * The Method class represents a member method of a class. It also allows + * dynamic invocation, via reflection. This works for both static and + * instance methods. Invocation on Method objects knows how to do + * widening conversions, but throws {@link IllegalArgumentException} if + * a narrowing conversion would be necessary. You can query for information + * on this Method regardless of location, but invocation access may be limited + * by Java language access controls. If you can't do it in the compiler, you + * can't normally do it here either.

+ * + * Note: This class returns and accepts types as Classes, even + * primitive types; there are Class types defined that represent each + * different primitive type. They are java.lang.Boolean.TYPE, + * java.lang.Byte.TYPE,, also available as boolean.class, + * byte.class, etc. These are not to be confused with the + * classes java.lang.Boolean, java.lang.Byte, etc., which are + * real classes.

+ * + * 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 + * @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 +{ + Class clazz; + String name; + int slot; + + private static final int METHOD_MODIFIERS + = Modifier.ABSTRACT | Modifier.FINAL | Modifier.NATIVE + | Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC + | Modifier.STATIC | Modifier.STRICT | Modifier.SYNCHRONIZED; + + /** + * This class is uninstantiable. + */ + private Method(Class declaringClass, String name, int slot) + { + this.clazz = declaringClass; + this.name = name; + this.slot = slot; + } + + /** + * Gets the class that declared this method, or the class where this method + * is a non-inherited member. + * @return the class that declared this member + */ + public Class getDeclaringClass() + { + return clazz; + } + + /** + * Gets the name of this method. + * @return the name of this method + */ + public String getName() + { + return name; + } + + /** + * Return the raw modifiers for this method. + * @return the method's modifiers + */ + private native int getModifiersInternal(); + + /** + * Gets the modifiers this method uses. Use the Modifier + * 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 native Class getReturnType(); + + /** + * Get the parameter list for this method, in declaration order. If the + * method takes no parameters, returns a 0-length array (not null). + * + * @return a list of the types of the method's parameters + */ + public native Class[] getParameterTypes(); + + /** + * Get the exception types this method says it throws, in no particular + * order. If the method has no throws clause, returns a 0-length array + * (not null). + * + * @return a list of the types in the method's throws clause + */ + public native Class[] getExceptionTypes(); + + /** + * Compare two objects to see if they are semantically equivalent. + * Two Methods are semantically equivalent if they have the same declaring + * class, name, parameter list, and return type. + * + * @param o the object to compare to + * @return true if they are equal; false if not + */ + public boolean equals(Object o) + { + // Implementation note: + // The following is a correct but possibly slow implementation. + // + // This class has a private field 'slot' that could be used by + // the VM implementation to "link" a particular method to a Class. + // In that case equals could be simply implemented as: + // + // if (o instanceof Method) + // { + // Method m = (Method)o; + // return m.clazz == this.clazz + // && m.slot == this.slot; + // } + // return false; + // + // If a VM uses the Method class as their native/internal representation + // then just using the following would be optimal: + // + // return this == o; + // + if (!(o instanceof Method)) + return false; + Method that = (Method)o; + if (this.getDeclaringClass() != that.getDeclaringClass()) + return false; + if (!this.getName().equals(that.getName())) + return false; + if (this.getReturnType() != that.getReturnType()) + return false; + if (!Arrays.equals(this.getParameterTypes(), that.getParameterTypes())) + return false; + return true; + } + + /** + * Get the hash code for the Method. The Method hash code is the hash code + * of its name XOR'd with the hash code of its class name. + * + * @return the hash code for the object + */ + public int hashCode() + { + return getDeclaringClass().getName().hashCode() ^ getName().hashCode(); + } + + /** + * Get a String representation of the Method. A Method's String + * representation is "<modifiers> <returntype> + * <methodname>(<paramtypes>) throws <exceptions>", where + * everything after ')' is omitted if there are no exceptions.
Example: + * public static int run(java.lang.Runnable,int) + * + * @return the String representation of the Method + */ + public String toString() + { + // 128 is a reasonable buffer initial size for constructor + StringBuilder sb = new StringBuilder(128); + Modifier.toString(getModifiers(), sb).append(' '); + sb.append(ClassHelper.getUserName(getReturnType())).append(' '); + sb.append(getDeclaringClass().getName()).append('.'); + sb.append(getName()).append('('); + Class[] c = getParameterTypes(); + if (c.length > 0) + { + sb.append(ClassHelper.getUserName(c[0])); + for (int i = 1; i < c.length; i++) + sb.append(',').append(ClassHelper.getUserName(c[i])); + } + sb.append(')'); + c = getExceptionTypes(); + if (c.length > 0) + { + sb.append(" throws ").append(c[0].getName()); + for (int i = 1; i < c.length; i++) + sb.append(',').append(c[i].getName()); + } + return sb.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.

+ * + * If the method is static, o 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 NullPointerException if o is + * null, and an IllegalArgumentException 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 args.

+ * + * Next, if this Method enforces access control, your runtime context is + * evaluated, and you may have an IllegalAccessException 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 + * ExceptionInInitializerError.

+ * + * 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 + * InvocationTargetException. + * + * @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 o is not an instance of the class or interface + * declaring this method + * @throws InvocationTargetException if the method throws an exception + * @throws NullPointerException if o is null and this field + * requires an instance + * @throws ExceptionInInitializerError if accessing a static method triggered + * class initialization, which then failed + */ + public Object invoke(Object o, Object... args) + throws IllegalAccessException, InvocationTargetException + { + return invokeNative(o, args, clazz, slot); + } + + /* + * NATIVE HELPERS + */ + + private native Object invokeNative(Object o, Object[] args, + Class declaringClass, int slot) + throws IllegalAccessException, InvocationTargetException; + + /** + * Returns an array of TypeVariable 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[] 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 Type 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 Type 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(); +} diff --git a/src/lib/gnu/sun/misc/Unsafe.java b/src/lib/gnu/sun/misc/Unsafe.java new file mode 100644 index 000000000..9ddf9c063 --- /dev/null +++ b/src/lib/gnu/sun/misc/Unsafe.java @@ -0,0 +1,862 @@ +/* + * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.misc; + +import java.security.*; +import java.lang.reflect.*; + + +/** + * A collection of methods for performing low-level, unsafe operations. + * Although the class and all methods are public, use of this class is + * limited because only trusted code can obtain instances of it. + * + * @author John R. Rose + * @version 1.27, 07/05/05 + * @see #getUnsafe + */ + +public final class Unsafe { + + private static native void registerNatives(); + static { + registerNatives(); +// sun.reflect.Reflection.registerMethodsToFilter(Unsafe.class, "getUnsafe"); + } + + private Unsafe() {} + + private static final Unsafe theUnsafe = new Unsafe(); + + /** + * Provides the caller with the capability of performing unsafe + * operations. + * + *

The returned Unsafe object should be carefully guarded + * by the caller, since it can be used to read and write data at arbitrary + * memory addresses. It must never be passed to untrusted code. + * + *

Most methods in this class are very low-level, and correspond to a + * small number of hardware instructions (on typical machines). Compilers + * are encouraged to optimize these methods accordingly. + * + *

Here is a suggested idiom for using unsafe operations: + * + *

+     * class MyTrustedClass {
+     *   private static final Unsafe unsafe = Unsafe.getUnsafe();
+     *   ...
+     *   private long myCountAddress = ...;
+     *   public int getCount() { return unsafe.getByte(myCountAddress); }
+     * }
+     * 
+ * + * (It may assist compilers to make the local variable be + * final.) + * + * @exception SecurityException if a security manager exists and its + * checkPropertiesAccess method doesn't allow + * access to the system properties. + */ + public static Unsafe getUnsafe() { + Class cc = sun.reflect.Reflection.getCallerClass(2); + if (cc.getClassLoader() != null) + throw new SecurityException("Unsafe"); + return theUnsafe; + } + + /// peek and poke operations + /// (compilers should optimize these to memory ops) + + // These work on object fields in the Java heap. + // They will not work on elements of packed arrays. + + /** + * Fetches a value from a given Java variable. + * More specifically, fetches a field or array element within the given + * object o at the given offset, or (if o is + * null) from the memory address whose numerical value is the given + * offset. + *

+ * The results are undefined unless one of the following cases is true: + *

    + *
  • The offset was obtained from {@link #objectFieldOffset} on + * the {@link java.lang.reflect.Field} of some Java field and the object + * referred to by o is of a class compatible with that + * field's class. + * + *
  • The offset and object reference o (either null or + * non-null) were both obtained via {@link #staticFieldOffset} + * and {@link #staticFieldBase} (respectively) from the + * reflective {@link Field} representation of some Java field. + * + *
  • The object referred to by o is an array, and the offset + * is an integer of the form B+N*S, where N is + * a valid index into the array, and B and S are + * the values obtained by {@link #arrayBaseOffset} and {@link + * #arrayIndexScale} (respectively) from the array's class. The value + * referred to is the Nth element of the array. + * + *
+ *

+ * If one of the above cases is true, the call references a specific Java + * variable (field or array element). However, the results are undefined + * if that variable is not in fact of the type returned by this method. + *

+ * This method refers to a variable by means of two parameters, and so + * it provides (in effect) a double-register addressing mode + * for Java variables. When the object reference is null, this method + * uses its offset as an absolute address. This is similar in operation + * to methods such as {@link #getInt(long)}, which provide (in effect) a + * single-register addressing mode for non-Java variables. + * However, because Java variables may have a different layout in memory + * from non-Java variables, programmers should not assume that these + * two addressing modes are ever equivalent. Also, programmers should + * remember that offsets from the double-register addressing mode cannot + * be portably confused with longs used in the single-register addressing + * mode. + * + * @param o Java heap object in which the variable resides, if any, else + * null + * @param offset indication of where the variable resides in a Java heap + * object, if any, else a memory address locating the variable + * statically + * @return the value fetched from the indicated Java variable + * @throws RuntimeException No defined exceptions are thrown, not even + * {@link NullPointerException} + */ + public native int getInt(Object o, long offset); + + /** + * Stores a value into a given Java variable. + *

+ * The first two parameters are interpreted exactly as with + * {@link #getInt(Object, long)} to refer to a specific + * Java variable (field or array element). The given value + * is stored into that variable. + *

+ * The variable must be of the same type as the method + * parameter x. + * + * @param o Java heap object in which the variable resides, if any, else + * null + * @param offset indication of where the variable resides in a Java heap + * object, if any, else a memory address locating the variable + * statically + * @param x the value to store into the indicated Java variable + * @throws RuntimeException No defined exceptions are thrown, not even + * {@link NullPointerException} + */ + public native void putInt(Object o, long offset, int x); + + /** + * Fetches a reference value from a given Java variable. + * @see #getInt(Object, long) + */ + public native Object getObject(Object o, long offset); + + /** + * Stores a reference value into a given Java variable. + *

+ * Unless the reference x being stored is either null + * or matches the field type, the results are undefined. + * If the reference o is non-null, car marks or + * other store barriers for that object (if the VM requires them) + * are updated. + * @see #putInt(Object, int, int) + */ + public native void putObject(Object o, long offset, Object x); + + /** @see #getInt(Object, long) */ + public native boolean getBoolean(Object o, long offset); + /** @see #putInt(Object, int, int) */ + public native void putBoolean(Object o, long offset, boolean x); + /** @see #getInt(Object, long) */ + public native byte getByte(Object o, long offset); + /** @see #putInt(Object, int, int) */ + public native void putByte(Object o, long offset, byte x); + /** @see #getInt(Object, long) */ + public native short getShort(Object o, long offset); + /** @see #putInt(Object, int, int) */ + public native void putShort(Object o, long offset, short x); + /** @see #getInt(Object, long) */ + public native char getChar(Object o, long offset); + /** @see #putInt(Object, int, int) */ + public native void putChar(Object o, long offset, char x); + /** @see #getInt(Object, long) */ + public native long getLong(Object o, long offset); + /** @see #putInt(Object, int, int) */ + public native void putLong(Object o, long offset, long x); + /** @see #getInt(Object, long) */ + public native float getFloat(Object o, long offset); + /** @see #putInt(Object, int, int) */ + public native void putFloat(Object o, long offset, float x); + /** @see #getInt(Object, long) */ + public native double getDouble(Object o, long offset); + /** @see #putInt(Object, int, int) */ + public native void putDouble(Object o, long offset, double x); + + /** + * This method, like all others with 32-bit offsets, was native + * in a previous release but is now a wrapper which simply casts + * the offset to a long value. It provides backward compatibility + * with bytecodes compiled against 1.4. + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public int getInt(Object o, int offset) { + return getInt(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putInt(Object o, int offset, int x) { + putInt(o, (long)offset, x); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public Object getObject(Object o, int offset) { + return getObject(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putObject(Object o, int offset, Object x) { + putObject(o, (long)offset, x); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public boolean getBoolean(Object o, int offset) { + return getBoolean(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putBoolean(Object o, int offset, boolean x) { + putBoolean(o, (long)offset, x); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public byte getByte(Object o, int offset) { + return getByte(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putByte(Object o, int offset, byte x) { + putByte(o, (long)offset, x); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public short getShort(Object o, int offset) { + return getShort(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putShort(Object o, int offset, short x) { + putShort(o, (long)offset, x); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public char getChar(Object o, int offset) { + return getChar(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putChar(Object o, int offset, char x) { + putChar(o, (long)offset, x); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public long getLong(Object o, int offset) { + return getLong(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putLong(Object o, int offset, long x) { + putLong(o, (long)offset, x); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public float getFloat(Object o, int offset) { + return getFloat(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putFloat(Object o, int offset, float x) { + putFloat(o, (long)offset, x); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public double getDouble(Object o, int offset) { + return getDouble(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putDouble(Object o, int offset, double x) { + putDouble(o, (long)offset, x); + } + + // These work on values in the C heap. + + /** + * Fetches a value from a given memory address. If the address is zero, or + * does not point into a block obtained from {@link #allocateMemory}, the + * results are undefined. + * + * @see #allocateMemory + */ + public native byte getByte(long address); + + /** + * Stores a value into a given memory address. If the address is zero, or + * does not point into a block obtained from {@link #allocateMemory}, the + * results are undefined. + * + * @see #getByte(long) + */ + public native void putByte(long address, byte x); + + /** @see #getByte(long) */ + public native short getShort(long address); + /** @see #putByte(long, byte) */ + public native void putShort(long address, short x); + /** @see #getByte(long) */ + public native char getChar(long address); + /** @see #putByte(long, byte) */ + public native void putChar(long address, char x); + /** @see #getByte(long) */ + public native int getInt(long address); + /** @see #putByte(long, byte) */ + public native void putInt(long address, int x); + /** @see #getByte(long) */ + public native long getLong(long address); + /** @see #putByte(long, byte) */ + public native void putLong(long address, long x); + /** @see #getByte(long) */ + public native float getFloat(long address); + /** @see #putByte(long, byte) */ + public native void putFloat(long address, float x); + /** @see #getByte(long) */ + public native double getDouble(long address); + /** @see #putByte(long, byte) */ + public native void putDouble(long address, double x); + + /** + * Fetches a native pointer from a given memory address. If the address is + * zero, or does not point into a block obtained from {@link + * #allocateMemory}, the results are undefined. + * + *

If the native pointer is less than 64 bits wide, it is extended as + * an unsigned number to a Java long. The pointer may be indexed by any + * given byte offset, simply by adding that offset (as a simple integer) to + * the long representing the pointer. The number of bytes actually read + * from the target address maybe determined by consulting {@link + * #addressSize}. + * + * @see #allocateMemory + */ + public native long getAddress(long address); + + /** + * Stores a native pointer into a given memory address. If the address is + * zero, or does not point into a block obtained from {@link + * #allocateMemory}, the results are undefined. + * + *

The number of bytes actually written at the target address maybe + * determined by consulting {@link #addressSize}. + * + * @see #getAddress(long) + */ + public native void putAddress(long address, long x); + + /// wrappers for malloc, realloc, free: + + /** + * Allocates a new block of native memory, of the given size in bytes. The + * contents of the memory are uninitialized; they will generally be + * garbage. The resulting native pointer will never be zero, and will be + * aligned for all value types. Dispose of this memory by calling {@link + * #freeMemory}, or resize it with {@link #reallocateMemory}. + * + * @throws IllegalArgumentException if the size is negative or too large + * for the native size_t type + * + * @throws OutOfMemoryError if the allocation is refused by the system + * + * @see #getByte(long) + * @see #putByte(long, byte) + */ + public native long allocateMemory(long bytes); + + /** + * Resizes a new block of native memory, to the given size in bytes. The + * contents of the new block past the size of the old block are + * uninitialized; they will generally be garbage. The resulting native + * pointer will be zero if and only if the requested size is zero. The + * resulting native pointer will be aligned for all value types. Dispose + * of this memory by calling {@link #freeMemory}, or resize it with {@link + * #reallocateMemory}. The address passed to this method may be null, in + * which case an allocation will be performed. + * + * @throws IllegalArgumentException if the size is negative or too large + * for the native size_t type + * + * @throws OutOfMemoryError if the allocation is refused by the system + * + * @see #allocateMemory + */ + public native long reallocateMemory(long address, long bytes); + + /** + * Sets all bytes in a given block of memory to a fixed value + * (usually zero). + */ + public native void setMemory(long address, long bytes, byte value); + + /** + * Sets all bytes in a given block of memory to a copy of another + * block. + */ + public native void copyMemory(long srcAddress, long destAddress, + long bytes); + + /** + * Disposes of a block of native memory, as obtained from {@link + * #allocateMemory} or {@link #reallocateMemory}. The address passed to + * this method may be null, in which case no action is taken. + * + * @see #allocateMemory + */ + public native void freeMemory(long address); + + /// random queries + + /** + * This constant differs from all results that will ever be returned from + * {@link #staticFieldOffset}, {@link #objectFieldOffset}, + * or {@link #arrayBaseOffset}. + */ + public static final int INVALID_FIELD_OFFSET = -1; + + /** + * Returns the offset of a field, truncated to 32 bits. + * This method is implemented as follows: + *

+     * public int fieldOffset(Field f) {
+     *     if (Modifier.isStatic(f.getModifiers()))
+     *         return (int) staticFieldOffset(f);
+     *     else
+     *         return (int) objectFieldOffset(f);
+     * }
+     * 
+ * @deprecated As of 1.4.1, use {@link #staticFieldOffset} for static + * fields and {@link #objectFieldOffset} for non-static fields. + */ + @Deprecated + public int fieldOffset(Field f) { + if (Modifier.isStatic(f.getModifiers())) + return (int) staticFieldOffset(f); + else + return (int) objectFieldOffset(f); + } + + /** + * Returns the base address for accessing some static field + * in the given class. This method is implemented as follows: + *
+     * public Object staticFieldBase(Class c) {
+     *     Field[] fields = c.getDeclaredFields();
+     *     for (int i = 0; i < fields.length; i++) {
+     *         if (Modifier.isStatic(fields[i].getModifiers())) {
+     *             return staticFieldBase(fields[i]);
+     *         }
+     *     }
+     *     return null;
+     * }
+     * 
+ * @deprecated As of 1.4.1, use {@link #staticFieldBase(Field)} + * to obtain the base pertaining to a specific {@link Field}. + * This method works only for JVMs which store all statics + * for a given class in one place. + */ + @Deprecated + public Object staticFieldBase(Class c) { + Field[] fields = c.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + if (Modifier.isStatic(fields[i].getModifiers())) { + return staticFieldBase(fields[i]); + } + } + return null; + } + + /** + * Report the location of a given field in the storage allocation of its + * class. Do not expect to perform any sort of arithmetic on this offset; + * it is just a cookie which is passed to the unsafe heap memory accessors. + * + *

Any given field will always have the same offset and base, and no + * two distinct fields of the same class will ever have the same offset + * and base. + * + *

As of 1.4.1, offsets for fields are represented as long values, + * although the Sun JVM does not use the most significant 32 bits. + * However, JVM implementations which store static fields at absolute + * addresses can use long offsets and null base pointers to express + * the field locations in a form usable by {@link #getInt(Object,long)}. + * Therefore, code which will be ported to such JVMs on 64-bit platforms + * must preserve all bits of static field offsets. + * @see #getInt(Object, long) + */ + public native long staticFieldOffset(Field f); + + /** + * Report the location of a given static field, in conjunction with {@link + * #staticFieldBase}. + *

Do not expect to perform any sort of arithmetic on this offset; + * it is just a cookie which is passed to the unsafe heap memory accessors. + * + *

Any given field will always have the same offset, and no two distinct + * fields of the same class will ever have the same offset. + * + *

As of 1.4.1, offsets for fields are represented as long values, + * although the Sun JVM does not use the most significant 32 bits. + * It is hard to imagine a JVM technology which needs more than + * a few bits to encode an offset within a non-array object, + * However, for consistency with other methods in this class, + * this method reports its result as a long value. + * @see #getInt(Object, long) + */ + public native long objectFieldOffset(Field f); + + /** + * Report the location of a given static field, in conjunction with {@link + * #staticFieldOffset}. + *

Fetch the base "Object", if any, with which static fields of the + * given class can be accessed via methods like {@link #getInt(Object, + * long)}. This value may be null. This value may refer to an object + * which is a "cookie", not guaranteed to be a real Object, and it should + * not be used in any way except as argument to the get and put routines in + * this class. + */ + public native Object staticFieldBase(Field f); + + /** + * Ensure the given class has been initialized. This is often + * needed in conjunction with obtaining the static field base of a + * class. + */ + public native void ensureClassInitialized(Class c); + + /** + * Report the offset of the first element in the storage allocation of a + * given array class. If {@link #arrayIndexScale} returns a non-zero value + * for the same class, you may use that scale factor, together with this + * base offset, to form new offsets to access elements of arrays of the + * given class. + * + * @see #getInt(Object, long) + * @see #putInt(Object, long, int) + */ + public native int arrayBaseOffset(Class arrayClass); + + /** + * Report the scale factor for addressing elements in the storage + * allocation of a given array class. However, arrays of "narrow" types + * will generally not work properly with accessors like {@link + * #getByte(Object, int)}, so the scale factor for such classes is reported + * as zero. + * + * @see #arrayBaseOffset + * @see #getInt(Object, long) + * @see #putInt(Object, long, int) + */ + public native int arrayIndexScale(Class arrayClass); + + /** + * Report the size in bytes of a native pointer, as stored via {@link + * #putAddress}. This value will be either 4 or 8. Note that the sizes of + * other primitive types (as stored in native memory blocks) is determined + * fully by their information content. + */ + public native int addressSize(); + + /** + * Report the size in bytes of a native memory page (whatever that is). + * This value will always be a power of two. + */ + public native int pageSize(); + + + /// random trusted operations from JNI: + + /** + * Tell the VM to define a class, without security checks. By default, the + * class loader and protection domain come from the caller's class. + */ + public native Class defineClass(String name, byte[] b, int off, int len, + ClassLoader loader, + ProtectionDomain protectionDomain); + + public native Class defineClass(String name, byte[] b, int off, int len); + + /** Allocate an instance but do not run any constructor. + Initializes the class if it has not yet been. */ + public native Object allocateInstance(Class cls) + throws InstantiationException; + + /** Lock the object. It must get unlocked via {@link #monitorExit}. */ + public native void monitorEnter(Object o); + + /** + * Unlock the object. It must have been locked via {@link + * #monitorEnter}. + */ + public native void monitorExit(Object o); + + /** + * Tries to lock the object. Returns true or false to indicate + * whether the lock succeeded. If it did, the object must be + * unlocked via {@link #monitorExit}. + */ + public native boolean tryMonitorEnter(Object o); + + /** Throw the exception without telling the verifier. */ + public native void throwException(Throwable ee); + + + /** + * Atomically update Java variable to x if it is currently + * holding expected. + * @return true if successful + */ + public final native boolean compareAndSwapObject(Object o, long offset, + Object expected, + Object x); + + /** + * Atomically update Java variable to x if it is currently + * holding expected. + * @return true if successful + */ + public final native boolean compareAndSwapInt(Object o, long offset, + int expected, + int x); + + /** + * Atomically update Java variable to x if it is currently + * holding expected. + * @return true if successful + */ + public final native boolean compareAndSwapLong(Object o, long offset, + long expected, + long x); + + /** + * Fetches a reference value from a given Java variable, with volatile + * load semantics. Otherwise identical to {@link #getObject(Object, long)} + */ + public native Object getObjectVolatile(Object o, long offset); + + /** + * Stores a reference value into a given Java variable, with + * volatile store semantics. Otherwise identical to {@link #putObject(Object, long, Object)} + */ + public native void putObjectVolatile(Object o, long offset, Object x); + + /** Volatile version of {@link #getInt(Object, long)} */ + public native int getIntVolatile(Object o, long offset); + + /** Volatile version of {@link #putInt(Object, long, int)} */ + public native void putIntVolatile(Object o, long offset, int x); + + /** Volatile version of {@link #getBoolean(Object, long)} */ + public native boolean getBooleanVolatile(Object o, long offset); + + /** Volatile version of {@link #putBoolean(Object, long, boolean)} */ + public native void putBooleanVolatile(Object o, long offset, boolean x); + + /** Volatile version of {@link #getByte(Object, long)} */ + public native byte getByteVolatile(Object o, long offset); + + /** Volatile version of {@link #putByte(Object, long, byte)} */ + public native void putByteVolatile(Object o, long offset, byte x); + + /** Volatile version of {@link #getShort(Object, long)} */ + public native short getShortVolatile(Object o, long offset); + + /** Volatile version of {@link #putShort(Object, long, short)} */ + public native void putShortVolatile(Object o, long offset, short x); + + /** Volatile version of {@link #getChar(Object, long)} */ + public native char getCharVolatile(Object o, long offset); + + /** Volatile version of {@link #putChar(Object, long, char)} */ + public native void putCharVolatile(Object o, long offset, char x); + + /** Volatile version of {@link #getLong(Object, long)} */ + public native long getLongVolatile(Object o, long offset); + + /** Volatile version of {@link #putLong(Object, long, long)} */ + public native void putLongVolatile(Object o, long offset, long x); + + /** Volatile version of {@link #getFloat(Object, long)} */ + public native float getFloatVolatile(Object o, long offset); + + /** Volatile version of {@link #putFloat(Object, long, float)} */ + public native void putFloatVolatile(Object o, long offset, float x); + + /** Volatile version of {@link #getDouble(Object, long)} */ + public native double getDoubleVolatile(Object o, long offset); + + /** Volatile version of {@link #putDouble(Object, long, double)} */ + public native void putDoubleVolatile(Object o, long offset, double x); + + /** + * Version of {@link #putObjectVolatile(Object, long, Object)} + * that does not guarantee immediate visibility of the store to + * other threads. This method is generally only useful if the + * underlying field is a Java volatile (or if an array cell, one + * that is otherwise only accessed using volatile accesses). + */ + public native void putOrderedObject(Object o, long offset, Object x); + + /** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)} */ + public native void putOrderedInt(Object o, long offset, int x); + + /** Ordered/Lazy version of {@link #putLongVolatile(Object, long, long)} */ + public native void putOrderedLong(Object o, long offset, long x); + + /** + * Unblock the given thread blocked on park, or, if it is + * not blocked, cause the subsequent call to park not to + * block. Note: this operation is "unsafe" solely because the + * caller must somehow ensure that the thread has not been + * destroyed. Nothing special is usually required to ensure this + * when called from Java (in which there will ordinarily be a live + * reference to the thread) but this is not nearly-automatically + * so when calling from native code. + * @param thread the thread to unpark. + * + */ + public native void unpark(Object thread); + + /** + * Block current thread, returning when a balancing + * unpark occurs, or a balancing unpark has + * already occurred, or the thread is interrupted, or, if not + * absolute and time is not zero, the given time nanoseconds have + * elapsed, or if absolute, the given deadline in milliseconds + * since Epoch has passed, or spuriously (i.e., returning for no + * "reason"). Note: This operation is in the Unsafe class only + * because unpark is, so it would be strange to place it + * elsewhere. + */ + public native void park(boolean isAbsolute, long time); + + /** + * Gets the load average in the system run queue assigned + * to the available processors averaged over various periods of time. + * This method retrieves the given nelem samples and + * assigns to the elements of the given loadavg array. + * The system imposes a maximum of 3 samples, representing + * averages over the last 1, 5, and 15 minutes, respectively. + * + * @params loadavg an array of double of size nelems + * @params nelems the number of samples to be retrieved and + * must be 1 to 3. + * + * @return the number of samples actually retrieved; or -1 + * if the load average is unobtainable. + */ + public native int getLoadAverage(double[] loadavg, int nelems); +} diff --git a/src/native/include/Makefile.am b/src/native/include/Makefile.am index 4c65432b4..765df9c22 100644 --- a/src/native/include/Makefile.am +++ b/src/native/include/Makefile.am @@ -22,7 +22,7 @@ ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ## 02110-1301, USA. ## -## $Id: Makefile.am 8123 2007-06-20 23:50:55Z michi $ +## $Id: Makefile.am 8132 2007-06-22 11:15:47Z twisti $ ## Process this file with automake to produce Makefile.in @@ -50,26 +50,37 @@ JAVASE_HEADER_FILES = \ java_lang_ClassLoader.h \ java_lang_Cloneable.h \ java_lang_ThreadGroup.h \ - java_lang_VMThread.h \ - java_lang_VMThrowable.h \ java_util_Properties.h \ \ - gnu_classpath_Pointer.h \ - gnu_classpath_Pointer32.h \ - gnu_classpath_Pointer64.h \ java_io_File.h \ java_lang_Process.h \ java_lang_StackTraceElement.h \ - java_lang_VMObject.h \ java_lang_reflect_Constructor.h \ java_lang_reflect_Field.h \ java_lang_reflect_Method.h \ java_nio_Buffer.h \ - java_nio_DirectByteBufferImpl.h \ java_security_ProtectionDomain.h \ java_util_concurrent_atomic_AtomicLong.h \ sun_misc_Unsafe.h +if WITH_CLASSPATH_GNU +JAVASE_HEADER_FILES += \ + java_lang_VMThread.h \ + java_lang_VMThrowable.h \ + \ + gnu_classpath_Pointer.h \ + gnu_classpath_Pointer32.h \ + gnu_classpath_Pointer64.h \ + java_lang_VMObject.h \ + java_nio_DirectByteBufferImpl.h +endif + +if WITH_CLASSPATH_SUN +JAVASE_HEADER_FILES += \ + java_lang_AssertionStatusDirectives.h \ + java_nio_ByteBuffer.h +endif + JAVAME_CLDC1_1_HEADER_FILES = \ com_sun_cldc_io_ResourceInputStream.h \ com_sun_cldc_io_j2me_socket_Protocol.h \ @@ -84,9 +95,9 @@ JVMTI_HEADER_FILES = \ gnu_classpath_jdwp_VMMethod.h \ gnu_classpath_jdwp_VMVirtualMachine.h \ gnu_classpath_jdwp_event_EventRequest.h \ - gnu_classpath_jdwp_util_VariableTable.h \ - java_nio_ByteBuffer.h + gnu_classpath_jdwp_util_VariableTable.h +if WITH_CLASSPATH_GNU ADDITIONAL_IMPLEMENTED_VM_CLASSES_HEADER_FILES = \ gnu_classpath_VMStackWalker.h \ gnu_classpath_VMSystemProperties.h \ @@ -99,11 +110,12 @@ ADDITIONAL_IMPLEMENTED_VM_CLASSES_HEADER_FILES = \ java_lang_VMRuntime.h \ java_lang_VMString.h \ java_lang_VMSystem.h \ - java_lang_management_VMManagementFactory.h \ java_lang_management_MemoryUsage.h \ java_lang_management_ThreadInfo.h \ + java_lang_management_VMManagementFactory.h \ java_lang_reflect_VMProxy.h \ java_security_VMAccessController.h +endif ADDITIONAL_STATIC_CLASSPATH_HEADER_FILES = \ java_net_DatagramPacket.h \ diff --git a/src/native/jni.c b/src/native/jni.c index 22da02bb1..ef9995c64 100644 --- a/src/native/jni.c +++ b/src/native/jni.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: jni.c 8128 2007-06-21 16:29:53Z tbfg $ + $Id: jni.c 8132 2007-06-22 11:15:47Z twisti $ */ @@ -65,6 +65,10 @@ #include "native/include/java_lang_Throwable.h" #if defined(ENABLE_JAVASE) +# if defined(WITH_CLASSPATH_SUN) +# include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */ +# endif + # include "native/include/java_lang_ClassLoader.h" # include "native/include/java_lang_reflect_Constructor.h" @@ -72,7 +76,10 @@ # include "native/include/java_lang_reflect_Method.h" # include "native/include/java_nio_Buffer.h" -# include "native/include/java_nio_DirectByteBufferImpl.h" + +# if defined(WITH_CLASSPATH_GNU) +# include "native/include/java_nio_DirectByteBufferImpl.h" +# endif #endif #if defined(ENABLE_JVMTI) @@ -183,6 +190,7 @@ bool jni_init(void) !link_class(class_java_nio_Buffer)) return false; +# if defined(WITH_CLASSPATH_GNU) if (!(class_java_nio_DirectByteBufferImpl = load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) || !link_class(class_java_nio_DirectByteBufferImpl)) @@ -199,7 +207,6 @@ bool jni_init(void) utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V")))) return false; -# if defined(WITH_CLASSPATH_GNU) # if SIZEOF_VOID_P == 8 if (!(class_gnu_classpath_Pointer64 = load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) || @@ -303,7 +310,8 @@ static java_objectheader *_Jv_jni_CallObjectMethod(java_objectheader *o, static java_objectheader *_Jv_jni_CallObjectMethodA(java_objectheader *o, vftbl_t *vftbl, - methodinfo *m, jvalue *args) + methodinfo *m, + const jvalue *args) { methodinfo *resm; java_objectheader *ro; @@ -397,7 +405,7 @@ static jint _Jv_jni_CallIntMethod(java_objectheader *o, vftbl_t *vftbl, *******************************************************************************/ static jint _Jv_jni_CallIntMethodA(java_objectheader *o, vftbl_t *vftbl, - methodinfo *m, jvalue *args) + methodinfo *m, const jvalue *args) { methodinfo *resm; jint i; @@ -489,7 +497,7 @@ static jlong _Jv_jni_CallLongMethod(java_objectheader *o, vftbl_t *vftbl, *******************************************************************************/ static jlong _Jv_jni_CallLongMethodA(java_objectheader *o, vftbl_t *vftbl, - methodinfo *m, jvalue *args) + methodinfo *m, const jvalue *args) { methodinfo *resm; jlong l; @@ -574,7 +582,7 @@ static jfloat _Jv_jni_CallFloatMethod(java_objectheader *o, vftbl_t *vftbl, *******************************************************************************/ static jfloat _Jv_jni_CallFloatMethodA(java_objectheader *o, vftbl_t *vftbl, - methodinfo *m, jvalue *args) + methodinfo *m, const jvalue *args) { methodinfo *resm; jfloat f; @@ -650,7 +658,7 @@ static jdouble _Jv_jni_CallDoubleMethod(java_objectheader *o, vftbl_t *vftbl, *******************************************************************************/ static jdouble _Jv_jni_CallDoubleMethodA(java_objectheader *o, vftbl_t *vftbl, - methodinfo *m, jvalue *args) + methodinfo *m, const jvalue *args) { methodinfo *resm; jdouble d; @@ -728,7 +736,7 @@ static void _Jv_jni_CallVoidMethod(java_objectheader *o, vftbl_t *vftbl, *******************************************************************************/ static void _Jv_jni_CallVoidMethodA(java_objectheader *o, vftbl_t *vftbl, - methodinfo *m, jvalue *args) + methodinfo *m, const jvalue *args) { methodinfo *resm; @@ -1431,6 +1439,8 @@ jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg) STATISTICS(jniinvokation()); c = (classinfo *) clazz; + if (msg == NULL) + msg = ""; s = javastring_new_from_utf_string(msg); /* instantiate exception object */ @@ -1811,7 +1821,7 @@ jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz) o = builtin_new(c); - return _Jv_JNI_NewLocalRef(env, o); + return _Jv_JNI_NewLocalRef(env, (jobject) o); } @@ -1827,16 +1837,18 @@ jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz) jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...) { java_objectheader *o; + classinfo *c; methodinfo *m; va_list ap; STATISTICS(jniinvokation()); + c = (classinfo *) clazz; m = (methodinfo *) methodID; /* create object */ - o = builtin_new(clazz); + o = builtin_new(c); if (o == NULL) return NULL; @@ -1847,7 +1859,7 @@ jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...) _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap); va_end(ap); - return _Jv_JNI_NewLocalRef(env, o); + return _Jv_JNI_NewLocalRef(env, (jobject) o); } @@ -1865,15 +1877,17 @@ jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args) { java_objectheader *o; + classinfo *c; methodinfo *m; STATISTICS(jniinvokation()); + c = (classinfo *) clazz; m = (methodinfo *) methodID; /* create object */ - o = builtin_new(clazz); + o = builtin_new(c); if (o == NULL) return NULL; @@ -1882,7 +1896,7 @@ jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, _Jv_jni_CallVoidMethod(o, o->vftbl, m, args); - return _Jv_JNI_NewLocalRef(env, o); + return _Jv_JNI_NewLocalRef(env, (jobject) o); } @@ -1897,18 +1911,20 @@ jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, *******************************************************************************/ jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, - jvalue *args) + const jvalue *args) { java_objectheader *o; + classinfo *c; methodinfo *m; STATISTICS(jniinvokation()); + c = (classinfo *) clazz; m = (methodinfo *) methodID; /* create object */ - o = builtin_new(clazz); + o = builtin_new(c); if (o == NULL) return NULL; @@ -1917,7 +1933,7 @@ jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args); - return _Jv_JNI_NewLocalRef(env, o); + return _Jv_JNI_NewLocalRef(env, (jobject) o); } @@ -1977,35 +1993,38 @@ jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz) jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method) { #if defined(ENABLE_JAVASE) - methodinfo *mi; - classinfo *c; - s4 slot; + java_objectheader *o; + classinfo *c; + methodinfo *m; + s4 slot; STATISTICS(jniinvokation()); - if (method == NULL) + o = (java_objectheader *) method; + + if (o == NULL) return NULL; - if (builtin_instanceof(method, class_java_lang_reflect_Method)) { + if (builtin_instanceof(o, class_java_lang_reflect_Method)) { java_lang_reflect_Method *rm; - rm = (java_lang_reflect_Method *) method; - c = (classinfo *) (rm->declaringClass); + rm = (java_lang_reflect_Method *) method; + c = (classinfo *) (rm->clazz); slot = rm->slot; } - else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) { + else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) { java_lang_reflect_Constructor *rc; - rc = (java_lang_reflect_Constructor *) method; - c = (classinfo *) (rc->clazz); + rc = (java_lang_reflect_Constructor *) method; + c = (classinfo *) (rc->clazz); slot = rc->slot; } else return NULL; - mi = &(c->methods[slot]); + m = &(c->methods[slot]); - return (jmethodID) mi; + return (jmethodID) m; #else vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration"); @@ -2036,8 +2055,7 @@ jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field) if (rf == NULL) return NULL; - c = (classinfo *) rf->declaringClass; - + c = (classinfo *) rf->clazz; f = &(c->fields[rf->slot]); return (jfieldID) f; @@ -2113,7 +2131,7 @@ jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name, c = (classinfo *) clazz; - if (!c) + if (c == NULL) return NULL; if (!(c->state & CLASS_INITIALIZED)) @@ -2125,7 +2143,7 @@ jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name, uname = utf_new_char((char *) name); udesc = utf_new_char((char *) sig); - m = class_resolvemethod(clazz, uname, udesc); + m = class_resolvemethod(c, uname, udesc); if ((m == NULL) || (m->flags & ACC_STATIC)) { exceptions_throw_nosuchmethoderror(c, uname, udesc); @@ -2154,7 +2172,7 @@ jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, ap); va_end(ap); - return _Jv_JNI_NewLocalRef(env, ret); + return _Jv_JNI_NewLocalRef(env, (jobject) ret); } @@ -2170,12 +2188,12 @@ jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, args); - return _Jv_JNI_NewLocalRef(env, ret); + return _Jv_JNI_NewLocalRef(env, (jobject) ret); } jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, - jvalue *args) + const jvalue *args) { java_objectheader *o; methodinfo *m; @@ -2186,7 +2204,7 @@ jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, ret = _Jv_jni_CallObjectMethodA(o, o->vftbl, m, args); - return _Jv_JNI_NewLocalRef(env, ret); + return _Jv_JNI_NewLocalRef(env, (jobject) ret); } @@ -2226,7 +2244,7 @@ jboolean _Jv_JNI_CallBooleanMethodV(JNIEnv *env, jobject obj, jboolean _Jv_JNI_CallBooleanMethodA(JNIEnv *env, jobject obj, - jmethodID methodID, jvalue *args) + jmethodID methodID, const jvalue *args) { java_objectheader *o; methodinfo *m; @@ -2277,7 +2295,7 @@ jbyte _Jv_JNI_CallByteMethodV(JNIEnv *env, jobject obj, jmethodID methodID, jbyte _Jv_JNI_CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, - jvalue *args) + const jvalue *args) { log_text("JNI-Call: CallByteMethodA: IMPLEMENT ME!"); @@ -2320,7 +2338,7 @@ jchar _Jv_JNI_CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, jchar _Jv_JNI_CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, - jvalue *args) + const jvalue *args) { log_text("JNI-Call: CallCharMethodA: IMPLEMENT ME!"); @@ -2364,7 +2382,7 @@ jshort _Jv_JNI_CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, jshort _Jv_JNI_CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, - jvalue *args) + const jvalue *args) { log_text("JNI-Call: CallShortMethodA: IMPLEMENT ME!"); @@ -2408,7 +2426,7 @@ jint _Jv_JNI_CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, jint _Jv_JNI_CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, - jvalue *args) + const jvalue *args) { log_text("JNI-Call: CallIntMethodA: IMPLEMENT ME!"); @@ -2452,7 +2470,7 @@ jlong _Jv_JNI_CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, jlong _Jv_JNI_CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, - jvalue *args) + const jvalue *args) { log_text("JNI-Call: CallLongMethodA: IMPLEMENT ME!"); @@ -2497,7 +2515,7 @@ jfloat _Jv_JNI_CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, jfloat _Jv_JNI_CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, - jvalue *args) + const jvalue *args) { log_text("JNI-Call: CallFloatMethodA: IMPLEMENT ME!"); @@ -2542,7 +2560,7 @@ jdouble _Jv_JNI_CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, jdouble _Jv_JNI_CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, - jvalue *args) + const jvalue *args) { log_text("JNI-Call: CallDoubleMethodA: IMPLEMENT ME!"); @@ -2580,7 +2598,7 @@ void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, - jvalue *args) + const jvalue *args) { java_objectheader *o; methodinfo *m; @@ -2611,7 +2629,7 @@ jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap); va_end(ap); - return _Jv_JNI_NewLocalRef(env, r); + return _Jv_JNI_NewLocalRef(env, (jobject) r); } @@ -2630,13 +2648,13 @@ jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args); - return _Jv_JNI_NewLocalRef(env, r); + return _Jv_JNI_NewLocalRef(env, (jobject) r); } jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - jvalue *args) + const jvalue *args) { log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!"); @@ -2688,7 +2706,7 @@ jboolean _Jv_JNI_CallNonvirtualBooleanMethodV(JNIEnv *env, jobject obj, jboolean _Jv_JNI_CallNonvirtualBooleanMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - jvalue *args) + const jvalue *args) { log_text("JNI-Call: CallNonvirtualBooleanMethodA: IMPLEMENT ME!"); @@ -2736,7 +2754,7 @@ jbyte _Jv_JNI_CallNonvirtualByteMethodV(JNIEnv *env, jobject obj, jclass clazz, jbyte _Jv_JNI_CallNonvirtualByteMethodA(JNIEnv *env, jobject obj, jclass clazz, - jmethodID methodID, jvalue *args) + jmethodID methodID, const jvalue *args) { log_text("JNI-Call: CallNonvirtualByteMethodA: IMPLEMENT ME!"); @@ -2785,7 +2803,7 @@ jchar _Jv_JNI_CallNonvirtualCharMethodV(JNIEnv *env, jobject obj, jclass clazz, jchar _Jv_JNI_CallNonvirtualCharMethodA(JNIEnv *env, jobject obj, jclass clazz, - jmethodID methodID, jvalue *args) + jmethodID methodID, const jvalue *args) { log_text("JNI-Call: CallNonvirtualCharMethodA: IMPLEMENT ME!"); @@ -2836,7 +2854,7 @@ jshort _Jv_JNI_CallNonvirtualShortMethodV(JNIEnv *env, jobject obj, jshort _Jv_JNI_CallNonvirtualShortMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - jvalue *args) + const jvalue *args) { log_text("JNI-Call: CallNonvirtualShortMethodA: IMPLEMENT ME!"); @@ -2885,7 +2903,7 @@ jint _Jv_JNI_CallNonvirtualIntMethodV(JNIEnv *env, jobject obj, jclass clazz, jint _Jv_JNI_CallNonvirtualIntMethodA(JNIEnv *env, jobject obj, jclass clazz, - jmethodID methodID, jvalue *args) + jmethodID methodID, const jvalue *args) { log_text("JNI-Call: CallNonvirtualIntMethodA: IMPLEMENT ME!"); @@ -2934,7 +2952,7 @@ jlong _Jv_JNI_CallNonvirtualLongMethodV(JNIEnv *env, jobject obj, jclass clazz, jlong _Jv_JNI_CallNonvirtualLongMethodA(JNIEnv *env, jobject obj, jclass clazz, - jmethodID methodID, jvalue *args) + jmethodID methodID, const jvalue *args) { log_text("JNI-Call: CallNonvirtualLongMethodA: IMPLEMENT ME!"); @@ -2985,7 +3003,7 @@ jfloat _Jv_JNI_CallNonvirtualFloatMethodV(JNIEnv *env, jobject obj, jfloat _Jv_JNI_CallNonvirtualFloatMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - jvalue *args) + const jvalue *args) { log_text("JNI-Call: CallNonvirtualFloatMethodA: IMPLEMENT ME!"); @@ -3037,7 +3055,7 @@ jdouble _Jv_JNI_CallNonvirtualDoubleMethodV(JNIEnv *env, jobject obj, jdouble _Jv_JNI_CallNonvirtualDoubleMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - jvalue *args) + const jvalue *args) { log_text("JNI-Call: CallNonvirtualDoubleMethodA: IMPLEMENT ME!"); @@ -3080,7 +3098,7 @@ void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz, void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz, - jmethodID methodID, jvalue * args) + jmethodID methodID, const jvalue * args) { java_objectheader *o; classinfo *c; @@ -3106,7 +3124,7 @@ void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz, *******************************************************************************/ jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name, - const char *sig) + const char *sig) { classinfo *c; fieldinfo *f; @@ -3117,10 +3135,12 @@ jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name, c = (classinfo *) clazz; + /* XXX NPE check? */ + uname = utf_new_char((char *) name); udesc = utf_new_char((char *) sig); - f = class_findfield(clazz, uname, udesc); + f = class_findfield(c, uname, udesc); if (f == NULL) exceptions_throw_nosuchfielderror(c, uname); @@ -3145,7 +3165,7 @@ jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID) o = GET_FIELD(obj, java_objectheader*, fieldID); - return _Jv_JNI_NewLocalRef(env, o); + return _Jv_JNI_NewLocalRef(env, (jobject) o); } @@ -3399,7 +3419,7 @@ jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz, o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap); va_end(ap); - return _Jv_JNI_NewLocalRef(env, o); + return _Jv_JNI_NewLocalRef(env, (jobject) o); } @@ -3413,12 +3433,12 @@ jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz, o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args); - return _Jv_JNI_NewLocalRef(env, o); + return _Jv_JNI_NewLocalRef(env, (jobject) o); } jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz, - jmethodID methodID, jvalue *args) + jmethodID methodID, const jvalue *args) { methodinfo *m; java_objectheader *o; @@ -3427,7 +3447,7 @@ jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz, o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args); - return _Jv_JNI_NewLocalRef(env, o); + return _Jv_JNI_NewLocalRef(env, (jobject) o); } @@ -3463,7 +3483,7 @@ jboolean _Jv_JNI_CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jboolean _Jv_JNI_CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, - jmethodID methodID, jvalue *args) + jmethodID methodID, const jvalue *args) { methodinfo *m; jboolean b; @@ -3508,7 +3528,7 @@ jbyte _Jv_JNI_CallStaticByteMethodV(JNIEnv *env, jclass clazz, jbyte _Jv_JNI_CallStaticByteMethodA(JNIEnv *env, jclass clazz, - jmethodID methodID, jvalue *args) + jmethodID methodID, const jvalue *args) { methodinfo *m; jbyte b; @@ -3553,7 +3573,7 @@ jchar _Jv_JNI_CallStaticCharMethodV(JNIEnv *env, jclass clazz, jchar _Jv_JNI_CallStaticCharMethodA(JNIEnv *env, jclass clazz, - jmethodID methodID, jvalue *args) + jmethodID methodID, const jvalue *args) { methodinfo *m; jchar c; @@ -3598,7 +3618,7 @@ jshort _Jv_JNI_CallStaticShortMethodV(JNIEnv *env, jclass clazz, jshort _Jv_JNI_CallStaticShortMethodA(JNIEnv *env, jclass clazz, - jmethodID methodID, jvalue *args) + jmethodID methodID, const jvalue *args) { methodinfo *m; jshort s; @@ -3643,7 +3663,7 @@ jint _Jv_JNI_CallStaticIntMethodV(JNIEnv *env, jclass clazz, jint _Jv_JNI_CallStaticIntMethodA(JNIEnv *env, jclass clazz, - jmethodID methodID, jvalue *args) + jmethodID methodID, const jvalue *args) { methodinfo *m; jint i; @@ -3688,7 +3708,7 @@ jlong _Jv_JNI_CallStaticLongMethodV(JNIEnv *env, jclass clazz, jlong _Jv_JNI_CallStaticLongMethodA(JNIEnv *env, jclass clazz, - jmethodID methodID, jvalue *args) + jmethodID methodID, const jvalue *args) { methodinfo *m; jlong l; @@ -3734,7 +3754,7 @@ jfloat _Jv_JNI_CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jfloat _Jv_JNI_CallStaticFloatMethodA(JNIEnv *env, jclass clazz, - jmethodID methodID, jvalue *args) + jmethodID methodID, const jvalue *args) { methodinfo *m; jfloat f; @@ -3779,7 +3799,7 @@ jdouble _Jv_JNI_CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jdouble _Jv_JNI_CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, - jmethodID methodID, jvalue *args) + jmethodID methodID, const jvalue *args) { methodinfo *m; jdouble d; @@ -3818,7 +3838,7 @@ void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz, void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz, - jmethodID methodID, jvalue * args) + jmethodID methodID, const jvalue * args) { methodinfo *m; @@ -3854,7 +3874,7 @@ jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, uname = utf_new_char((char *) name); usig = utf_new_char((char *) sig); - f = class_findfield(clazz, uname, usig); + f = class_findfield(c, uname, usig); if (f == NULL) exceptions_throw_nosuchfielderror(c, uname); @@ -4260,7 +4280,11 @@ static jchar emptyStringJ[]={0,0}; jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str) { - return ((java_lang_String *) str)->count; + java_lang_String *s; + + s = (java_lang_String *) str; + + return s->count; } @@ -4371,13 +4395,18 @@ jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes) /****************** returns the utf8 length in bytes of a string *******************/ -jsize _Jv_JNI_GetStringUTFLength (JNIEnv *env, jstring string) +jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string) { - java_lang_String *s = (java_lang_String*) string; + java_lang_String *s; + s4 length; STATISTICS(jniinvokation()); - return (jsize) u2_utflength(s->value->data, s->count); + s = (java_lang_String *) string; + + length = u2_utflength(s->value->data, s->count); + + return length; } @@ -4459,17 +4488,22 @@ jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array) jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement) { - java_objectarray *oa; - s4 i; + classinfo *c; + java_objectheader *o; + java_objectarray *oa; + s4 i; STATISTICS(jniinvokation()); + c = (classinfo *) elementClass; + o = (java_objectheader *) initialElement; + if (length < 0) { exceptions_throw_negativearraysizeexception(); return NULL; } - oa = builtin_anewarray(length, elementClass); + oa = builtin_anewarray(length, c); if (oa == NULL) return NULL; @@ -4477,7 +4511,7 @@ jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length, /* set all elements to initialElement */ for (i = 0; i < length; i++) - oa->data[i] = initialElement; + oa->data[i] = o; return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa); } @@ -4486,8 +4520,8 @@ jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length, jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index) { - java_objectarray *oa; - jobject o; + java_objectarray *oa; + java_objectheader *o; STATISTICS(jniinvokation()); @@ -4500,7 +4534,7 @@ jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array, o = oa->data[index]; - return _Jv_JNI_NewLocalRef(env, o); + return _Jv_JNI_NewLocalRef(env, (jobject) o); } @@ -4526,7 +4560,7 @@ void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array, if (!builtin_canstore(oa, o)) return; - oa->data[index] = val; + oa->data[index] = o; } @@ -5168,7 +5202,7 @@ void _Jv_JNI_GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start, *******************************************************************************/ void _Jv_JNI_SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, - jsize start, jsize len, jboolean *buf) + jsize start, jsize len, const jboolean *buf) { java_booleanarray *ba; @@ -5184,7 +5218,7 @@ void _Jv_JNI_SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, void _Jv_JNI_SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, - jsize len, jbyte *buf) + jsize len, const jbyte *buf) { java_bytearray *ba; @@ -5200,7 +5234,7 @@ void _Jv_JNI_SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, void _Jv_JNI_SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, - jsize len, jchar *buf) + jsize len, const jchar *buf) { java_chararray *ca; @@ -5216,7 +5250,7 @@ void _Jv_JNI_SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, void _Jv_JNI_SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start, - jsize len, jshort *buf) + jsize len, const jshort *buf) { java_shortarray *sa; @@ -5232,7 +5266,7 @@ void _Jv_JNI_SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start, void _Jv_JNI_SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, - jsize len, jint *buf) + jsize len, const jint *buf) { java_intarray *ia; @@ -5248,7 +5282,7 @@ void _Jv_JNI_SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, void _Jv_JNI_SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, - jsize len, jlong *buf) + jsize len, const jlong *buf) { java_longarray *la; @@ -5264,7 +5298,7 @@ void _Jv_JNI_SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, void _Jv_JNI_SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start, - jsize len, jfloat *buf) + jsize len, const jfloat *buf) { java_floatarray *fa; @@ -5280,7 +5314,7 @@ void _Jv_JNI_SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start, void _Jv_JNI_SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start, - jsize len, jdouble *buf) + jsize len, const jdouble *buf) { java_doublearray *da; @@ -5310,13 +5344,18 @@ void _Jv_JNI_SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start, jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethods) { + classinfo *c; + STATISTICS(jniinvokation()); - log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!"); + c = (classinfo *) clazz; + /* XXX: if implemented this needs a call to jvmti_NativeMethodBind if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr); */ + native_method_register(c->name, methods, nMethods); + return 0; } @@ -5444,12 +5483,40 @@ void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, } +/* GetStringUTFRegion ********************************************************** + + Translates len number of Unicode characters beginning at offset + start into UTF-8 format and place the result in the given buffer + buf. + + Throws StringIndexOutOfBoundsException on index overflow. + +*******************************************************************************/ + void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, char *buf) { + java_lang_String *s; + java_chararray *ca; + s4 i; + STATISTICS(jniinvokation()); - log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!"); + s = (java_lang_String *) str; + ca = s->value; + + if ((start < 0) || (len < 0) || (start > s->count) || + (start + len > s->count)) { + exceptions_throw_stringindexoutofboundsexception(); + return; + } + + /* XXX not sure if this is correct */ + + for (i = 0; i < len; i++) + buf[i] = ca->data[start + i]; + + buf[i] = '\0'; } @@ -5469,7 +5536,7 @@ void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, /* do the same as Kaffe does */ - bp = _Jv_JNI_GetByteArrayElements(env, ba, isCopy); + bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy); return (void *) bp; } @@ -5548,9 +5615,12 @@ jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj) hashtable_global_ref_entry *gre; u4 key; /* hashkey */ u4 slot; /* slot in hashtable */ + java_objectheader *o; STATISTICS(jniinvokation()); + o = (java_objectheader *) obj; + LOCK_MONITOR_ENTER(hashtable_global_ref->header); /* normally addresses are aligned to 4, 8 or 16 bytes */ @@ -5562,7 +5632,7 @@ jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj) /* search external hash chain for the entry */ while (gre) { - if (gre->o == obj) { + if (gre->o == o) { /* global object found, increment the reference */ gre->refs++; @@ -5579,7 +5649,7 @@ jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj) gre = NEW(hashtable_global_ref_entry); - gre->o = obj; + gre->o = o; gre->refs = 1; /* insert entry into hashtable */ @@ -5610,9 +5680,12 @@ void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef) hashtable_global_ref_entry *prevgre; u4 key; /* hashkey */ u4 slot; /* slot in hashtable */ + java_objectheader *o; STATISTICS(jniinvokation()); + o = (java_objectheader *) globalRef; + LOCK_MONITOR_ENTER(hashtable_global_ref->header); /* normally addresses are aligned to 4, 8 or 16 bytes */ @@ -5628,7 +5701,7 @@ void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef) /* search external hash chain for the entry */ while (gre) { - if (gre->o == globalRef) { + if (gre->o == o) { /* global object found, decrement the reference count */ gre->refs--; @@ -5692,8 +5765,9 @@ jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env) jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity) { -#if defined(ENABLE_JAVASE) +#if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU) java_objectheader *nbuf; + # if SIZEOF_VOID_P == 8 gnu_classpath_Pointer64 *paddress; # else @@ -5745,7 +5819,7 @@ jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity) void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf) { -#if defined(ENABLE_JAVASE) +#if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU) java_nio_DirectByteBufferImpl *nbuf; # if SIZEOF_VOID_P == 8 gnu_classpath_Pointer64 *address; @@ -5789,15 +5863,18 @@ void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf) jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf) { -#if defined(ENABLE_JAVASE) - java_nio_Buffer *nbuf; +#if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU) + java_objectheader *o; + java_nio_Buffer *nbuf; STATISTICS(jniinvokation()); - if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl)) + o = (java_objectheader *) buf; + + if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl)) return -1; - nbuf = (java_nio_Buffer *) buf; + nbuf = (java_nio_Buffer *) o; return (jlong) nbuf->cap; #else @@ -5991,7 +6068,7 @@ jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args) /* JNI invocation table *******************************************************/ -const struct JNIInvokeInterface _Jv_JNIInvokeInterface = { +const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = { NULL, NULL, NULL, @@ -6006,7 +6083,7 @@ const struct JNIInvokeInterface _Jv_JNIInvokeInterface = { /* JNI function table *********************************************************/ -struct JNINativeInterface _Jv_JNINativeInterface = { +struct JNINativeInterface_ _Jv_JNINativeInterface = { NULL, NULL, NULL, diff --git a/src/native/jni.h b/src/native/jni.h index 693f1e3de..8848d5245 100644 --- a/src/native/jni.h +++ b/src/native/jni.h @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: jni.h 7921 2007-05-20 23:14:11Z michi $ + $Id: jni.h 8132 2007-06-22 11:15:47Z twisti $ */ @@ -43,8 +43,11 @@ #include "config.h" -#include CLASSPATH_JNI_H +/* XXX quick hack to not include GCJ's jni_md.h */ +#define __GCJ_JNI_MD_H__ +#include CLASSPATH_JNI_MD_H +#include CLASSPATH_JNI_H #ifndef _JNI_H #define _JNI_H @@ -66,7 +69,7 @@ typedef struct localref_table localref_table; typedef struct _Jv_JNIEnv _Jv_JNIEnv; struct _Jv_JNIEnv { - const struct JNINativeInterface *env; /* This MUST be the first entry */ + const struct JNINativeInterface_ *env; /* This MUST be the first entry */ }; @@ -75,7 +78,7 @@ struct _Jv_JNIEnv { typedef struct _Jv_JavaVM _Jv_JavaVM; struct _Jv_JavaVM { - const struct JNIInvokeInterface *functions;/* This MUST be the first entry*/ + const struct JNIInvokeInterface_ *functions;/*This MUST be the first entry*/ /* JVM instance-specific variables */ @@ -92,8 +95,8 @@ struct _Jv_JavaVM { /* CACAO related stuff ********************************************************/ -extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface; -extern struct JNINativeInterface _Jv_JNINativeInterface; +extern const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface; +extern struct JNINativeInterface_ _Jv_JNINativeInterface; /* local reference table ******************************************************/ diff --git a/src/native/native.c b/src/native/native.c index 9e102cb33..5cc8cc024 100644 --- a/src/native/native.c +++ b/src/native/native.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: native.c 8092 2007-06-14 16:12:35Z twisti $ + $Id: native.c 8132 2007-06-22 11:15:47Z twisti $ */ @@ -36,6 +36,8 @@ # include #endif +#include + #include "vm/types.h" #include "mm/memory.h" @@ -125,11 +127,6 @@ bool native_init(void) tree_native_methods = avl_create(&native_tree_native_methods_comparator); - /* register the intern native functions */ - - if (!nativevm_init()) - return false; - /* everything's ok */ return true; @@ -447,12 +444,13 @@ static utf *native_method_symbol(utf *classname, utf *methodname) *******************************************************************************/ -void native_method_register(utf *classname, JNINativeMethod *methods, s4 count) +void native_method_register(utf *classname, const JNINativeMethod *methods, + int32_t count) { native_methods_node_t *nmn; utf *name; utf *descriptor; - s4 i; + int32_t i; /* insert all methods passed */ @@ -523,6 +521,12 @@ lt_dlhandle native_library_open(utf *filename) { lt_dlhandle handle; + if (opt_verbosejni) { + printf("[Loading native library "); + utf_display_printable_ascii(filename); + printf(" ... "); + } + /* try to open the library */ handle = lt_dlopen(filename->text); @@ -743,6 +747,7 @@ functionptr native_findfunction(utf *cname, utf *mname, utf *desc, functionptr native_resolve_function(methodinfo *m) { + java_objectheader *cl; utf *name; utf *newname; functionptr f; @@ -750,6 +755,12 @@ functionptr native_resolve_function(methodinfo *m) hashtable_library_name_entry *ne; u4 key; /* hashkey */ u4 slot; /* slot in hashtable */ +#if defined(WITH_CLASSPATH_SUN) + methodinfo *method_findNative; + java_objectheader *s; +#endif + + cl = m->class->classloader; /* verbose output */ @@ -776,7 +787,7 @@ functionptr native_resolve_function(methodinfo *m) /* normally addresses are aligned to 4, 8 or 16 bytes */ - key = ((u4) (ptrint) m->class->classloader) >> 4; /* align to 16-byte */ + key = ((u4) (ptrint) cl) >> 4; /* align to 16-byte */ slot = key & (hashtable_library->size - 1); le = hashtable_library->ptr[slot]; @@ -799,6 +810,40 @@ functionptr native_resolve_function(methodinfo *m) le = le->hashlink; } +#if defined(WITH_CLASSPATH_SUN) + if (f == NULL) { + /* We can resolve the function directly from + java.lang.ClassLoader as it's a static function. */ + /* XXX should be done in native_init */ + + method_findNative = + class_resolveclassmethod(class_java_lang_ClassLoader, + utf_findNative, + utf_java_lang_ClassLoader_java_lang_String__J, + class_java_lang_ClassLoader, + true); + + if (method_findNative == NULL) + return NULL; + + /* try the normal name */ + + s = javastring_new(name); + + f = (functionptr) (intptr_t) vm_call_method_long(method_findNative, + NULL, cl, s); + + /* if not found, try the mangled name */ + + if (f == NULL) { + s = javastring_new(newname); + + f = (functionptr) (intptr_t) vm_call_method_long(method_findNative, + NULL, cl, s); + } + } +#endif + if (f != NULL) if (opt_verbosejni) printf("JNI ]\n"); diff --git a/src/native/native.h b/src/native/native.h index f294e2983..62dc3ba20 100644 --- a/src/native/native.h +++ b/src/native/native.h @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: native.h 8062 2007-06-11 08:12:14Z twisti $ + $Id: native.h 8132 2007-06-22 11:15:47Z twisti $ */ @@ -36,6 +36,8 @@ # include #endif +#include + #include "native/jni.h" #include "vm/global.h" @@ -115,7 +117,8 @@ struct nativecompref { bool native_init(void); -void native_method_register(utf *classname, JNINativeMethod *methods, s4 count); +void native_method_register(utf *classname, const JNINativeMethod *methods, + int32_t count); #if defined(WITH_STATIC_CLASSPATH) diff --git a/src/native/vm/Makefile.am b/src/native/vm/Makefile.am index 5cd7dee95..12c3aa945 100644 --- a/src/native/vm/Makefile.am +++ b/src/native/vm/Makefile.am @@ -32,7 +32,8 @@ LIBS = DIST_SUBDIRS = \ cldc1.1 \ - gnu + gnu \ + sun if WITH_CLASSPATH_CLDC1_1 SUBDIRS = \ @@ -50,6 +51,14 @@ NATIVEVM_LIB = \ gnu/libnativevmcore.la endif +if WITH_CLASSPATH_SUN +SUBDIRS = \ + sun + +NATIVEVM_LIB = \ + sun/libnativevmcore.la +endif + if ENABLE_JAVASE CLASSLOADER_SOURCES = \ java_lang_ClassLoader.c \ diff --git a/src/native/vm/gnu/java_lang_reflect_Field.c b/src/native/vm/gnu/java_lang_reflect_Field.c index 66871ef72..af9fb08d8 100644 --- a/src/native/vm/gnu/java_lang_reflect_Field.c +++ b/src/native/vm/gnu/java_lang_reflect_Field.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: java_lang_reflect_Field.c 8123 2007-06-20 23:50:55Z michi $ + $Id: java_lang_reflect_Field.c 8132 2007-06-22 11:15:47Z twisti $ */ @@ -127,7 +127,7 @@ static void *cacao_get_field_address(java_lang_reflect_Field *this, classinfo *c; fieldinfo *f; - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* check field access */ @@ -186,7 +186,7 @@ JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getModifiersInternal(JNIE classinfo *c; fieldinfo *f; - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &(c->fields[this->slot]); return f->flags; @@ -204,7 +204,7 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_reflect_Field_getType(JNIEnv * typedesc *desc; classinfo *ret; - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; desc = c->fields[this->slot].parseddesc; if (desc == NULL) @@ -228,7 +228,7 @@ JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_Field_get(JNIEnv *env fieldinfo *f; void *addr; - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get address of the source field value */ @@ -358,7 +358,7 @@ JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getBoolean(JNIEnv *env, j /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get the address of the field with an internal helper */ @@ -391,7 +391,7 @@ JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getByte(JNIEnv *env, java /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get the address of the field with an internal helper */ @@ -424,7 +424,7 @@ JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getChar(JNIEnv *env, java /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get the address of the field with an internal helper */ @@ -457,7 +457,7 @@ JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getShort(JNIEnv *env, jav /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get the address of the field with an internal helper */ @@ -491,7 +491,7 @@ JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getInt(JNIEnv *env , java /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get the address of the field with an internal helper */ @@ -527,7 +527,7 @@ JNIEXPORT int64_t JNICALL Java_java_lang_reflect_Field_getLong(JNIEnv *env, java /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get the address of the field with an internal helper */ @@ -565,7 +565,7 @@ JNIEXPORT float JNICALL Java_java_lang_reflect_Field_getFloat(JNIEnv *env, java_ /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get the address of the field with an internal helper */ @@ -605,7 +605,7 @@ JNIEXPORT double JNICALL Java_java_lang_reflect_Field_getDouble(JNIEnv *env , ja /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get the address of the field with an internal helper */ @@ -649,7 +649,7 @@ JNIEXPORT void JNICALL Java_java_lang_reflect_Field_set(JNIEnv *env, java_lang_r /* get the class and the field */ - dc = (classinfo *) this->declaringClass; + dc = (classinfo *) this->clazz; df = &dc->fields[this->slot]; /* get the address of the destination field */ @@ -920,7 +920,7 @@ JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setBoolean(JNIEnv *env, java /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get the address of the field with an internal helper */ @@ -955,7 +955,7 @@ JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setByte(JNIEnv *env, java_la /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get the address of the field with an internal helper */ @@ -1001,7 +1001,7 @@ JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setChar(JNIEnv *env, java_la /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get the address of the field with an internal helper */ @@ -1046,7 +1046,7 @@ JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setShort(JNIEnv *env, java_l /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get the address of the field with an internal helper */ @@ -1091,7 +1091,7 @@ JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setInt(JNIEnv *env, java_lan /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get the address of the field with an internal helper */ @@ -1135,7 +1135,7 @@ JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setLong(JNIEnv *env, java_la /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get the address of the field with an internal helper */ @@ -1176,7 +1176,7 @@ JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setFloat(JNIEnv *env, java_l /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get the address of the field with an internal helper */ @@ -1214,7 +1214,7 @@ JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setDouble(JNIEnv *env, java_ /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; /* get the address of the field with an internal helper */ @@ -1249,7 +1249,7 @@ JNIEXPORT java_lang_String* JNICALL Java_java_lang_reflect_Field_getSignature(JN /* get the class and the field */ - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; f = &c->fields[this->slot]; if (f->signature == NULL) diff --git a/src/native/vm/gnu/java_lang_reflect_Method.c b/src/native/vm/gnu/java_lang_reflect_Method.c index ea9ccaab8..96888b080 100644 --- a/src/native/vm/gnu/java_lang_reflect_Method.c +++ b/src/native/vm/gnu/java_lang_reflect_Method.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: java_lang_reflect_Method.c 8123 2007-06-20 23:50:55Z michi $ + $Id: java_lang_reflect_Method.c 8132 2007-06-22 11:15:47Z twisti $ */ @@ -93,7 +93,7 @@ JNIEXPORT s4 JNICALL Java_java_lang_reflect_Method_getModifiersInternal(JNIEnv * classinfo *c; methodinfo *m; - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; m = &(c->methods[this->slot]); return m->flags; @@ -111,7 +111,7 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_reflect_Method_getReturnType(J methodinfo *m; classinfo *result; - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; m = &(c->methods[this->slot]); result = method_returntype_get(m); @@ -130,7 +130,7 @@ JNIEXPORT java_objectarray* JNICALL Java_java_lang_reflect_Method_getParameterTy classinfo *c; methodinfo *m; - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; m = &(c->methods[this->slot]); return method_get_parametertypearray(m); @@ -147,7 +147,7 @@ JNIEXPORT java_objectarray* JNICALL Java_java_lang_reflect_Method_getExceptionTy classinfo *c; methodinfo *m; - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; m = &(c->methods[this->slot]); return method_get_exceptionarray(m); @@ -159,11 +159,11 @@ JNIEXPORT java_objectarray* JNICALL Java_java_lang_reflect_Method_getExceptionTy * Method: invokeNative * Signature: (Ljava/lang/Object;[Ljava/lang/Object;Ljava/lang/Class;I)Ljava/lang/Object; */ -JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_Method_invokeNative(JNIEnv *env, java_lang_reflect_Method *this, java_lang_Object *o, java_objectarray *args, java_lang_Class *declaringClass, s4 slot) +JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_Method_invokeNative(JNIEnv *env, java_lang_reflect_Method *this, java_lang_Object *o, java_objectarray *args, java_lang_Class *clazz, s4 slot) { /* just to be sure */ - assert(this->declaringClass == declaringClass); + assert(this->clazz == clazz); assert(this->slot == slot); return _Jv_java_lang_reflect_Method_invoke(this, o, args); @@ -181,7 +181,7 @@ JNIEXPORT java_lang_String* JNICALL Java_java_lang_reflect_Method_getSignature(J methodinfo *m; java_objectheader *o; - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; m = &(c->methods[this->slot]); if (m->signature == NULL) diff --git a/src/native/vm/java_lang_Class.c b/src/native/vm/java_lang_Class.c index 35aa13985..e2bdad005 100644 --- a/src/native/vm/java_lang_Class.c +++ b/src/native/vm/java_lang_Class.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: java_lang_Class.c 8089 2007-06-14 16:06:31Z twisti $ + $Id: java_lang_Class.c 8132 2007-06-22 11:15:47Z twisti $ */ @@ -39,21 +39,28 @@ #include "native/jni.h" #include "native/native.h" -#if defined(ENABLE_JAVAME_CLDC1_1) -# include "native/include/java_lang_String.h"/* required by java_lang_Class.h */ +/* keep this order of the native includes */ + +#include "native/include/java_lang_String.h" + +#if defined(ENABLE_JAVASE) +# if defined(WITH_CLASSPATH_SUN) +# include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */ +# endif +# include "native/include/java_lang_ClassLoader.h" #endif -#include "native/include/java_lang_Class.h" #include "native/include/java_lang_Object.h" +#include "native/include/java_lang_Class.h" #if defined(ENABLE_JAVASE) -# include "native/include/java_lang_ClassLoader.h" # include "native/include/java_lang_reflect_Constructor.h" # include "native/include/java_lang_reflect_Field.h" # include "native/include/java_lang_reflect_Method.h" #endif #include "native/vm/java_lang_Class.h" +#include "native/vm/java_lang_String.h" #include "toolbox/logging.h" @@ -586,9 +593,32 @@ java_objectarray *_Jv_java_lang_Class_getDeclaredFields(java_lang_Class *klass, rf = (java_lang_reflect_Field *) o; - rf->declaringClass = (java_lang_Class *) c; - rf->name = (java_lang_String *) javastring_new(f->name); +#if defined(WITH_CLASSPATH_GNU) + + rf->clazz = (java_lang_Class *) c; + + /* The name needs to be interned */ + /* XXX implement me better! */ + + rf->name = _Jv_java_lang_String_intern((java_lang_String *) javastring_new(f->name)); + rf->slot = i; + +#elif defined(WITH_CLASSPATH_SUN) + + rf->clazz = (java_lang_Class *) c; + + /* The name needs to be interned */ + /* XXX implement me better! */ + + rf->name = _Jv_java_lang_String_intern((java_lang_String *) javastring_new(f->name)); + rf->type = (java_lang_Class *) field_get_type(f); + rf->modifiers = f->flags; rf->slot = i; + rf->signature = f->signature ? (java_lang_String *) javastring_new(f->signature) : NULL; + rf->annotations = NULL; +#else +# error unknown classpath configuration +#endif /* store object into array */ @@ -659,9 +689,37 @@ java_objectarray *_Jv_java_lang_Class_getDeclaredMethods(java_lang_Class *klass, rm = (java_lang_reflect_Method *) o; - rm->declaringClass = (java_lang_Class *) m->class; - rm->name = (java_lang_String *) javastring_new(m->name); - rm->slot = i; +#if defined(WITH_CLASSPATH_GNU) + + rm->clazz = (java_lang_Class *) m->class; + + /* The name needs to be interned */ + /* XXX implement me better! */ + + rm->name = _Jv_java_lang_String_intern((java_lang_String *) javastring_new(m->name)); + rm->slot = i; + +#elif defined(WITH_CLASSPATH_SUN) + + rm->clazz = (java_lang_Class *) m->class; + + /* The name needs to be interned */ + /* XXX implement me better! */ + + rm->name = _Jv_java_lang_String_intern((java_lang_String *) javastring_new(m->name)); + rm->parameterTypes = method_get_parametertypearray(m); + rm->returnType = (java_lang_Class *) method_returntype_get(m); + rm->exceptionTypes = method_get_exceptionarray(m); + rm->modifiers = m->flags & ACC_CLASS_REFLECT_MASK; + rm->slot = i; + rm->signature = m->signature ? (java_lang_String *) javastring_new(m->signature) : NULL; + rm->annotations = NULL; + rm->parameterAnnotations = NULL; + rm->annotationDefault = NULL; + +#else +# error unknown classpath configuration +#endif /* store object into array */ @@ -721,8 +779,25 @@ java_objectarray *_Jv_java_lang_Class_getDeclaredConstructors(java_lang_Class *k rc = (java_lang_reflect_Constructor *) o; - rc->clazz = (java_lang_Class *) c; - rc->slot = i; +#if defined(WITH_CLASSPATH_GNU) + + rc->clazz = (java_lang_Class *) c; + rc->slot = i; + +#elif defined(WITH_CLASSPATH_SUN) + + rc->clazz = (java_lang_Class *) c; + rc->parameterTypes = method_get_parametertypearray(m); + rc->exceptionTypes = method_get_exceptionarray(m); + rc->modifiers = m->flags & ACC_CLASS_REFLECT_MASK; + rc->slot = i; + rc->signature = m->signature ? (java_lang_String *) javastring_new(m->signature) : NULL; + rc->annotations = NULL; + rc->parameterAnnotations = NULL; + +#else +# error unknown classpath configuration +#endif /* store object into array */ @@ -966,7 +1041,14 @@ java_lang_reflect_Method *_Jv_java_lang_Class_getEnclosingMethod(java_lang_Class rm = (java_lang_reflect_Method *) o; - rm->declaringClass = (java_lang_Class *) m->class; +#if defined(WITH_CLASSPATH_GNU) + rm->clazz = (java_lang_Class *) m->class; +#elif defined(WITH_CLASSPATH_SUN) + rm->clazz = (java_lang_Class *) m->class; +#else +# error unknown classpath configuration +#endif + rm->name = (java_lang_String *) javastring_new(m->name); rm->slot = m - m->class->methods; /* calculate method slot */ diff --git a/src/native/vm/java_lang_ClassLoader.c b/src/native/vm/java_lang_ClassLoader.c index b3480e1b9..07c3ff088 100644 --- a/src/native/vm/java_lang_ClassLoader.c +++ b/src/native/vm/java_lang_ClassLoader.c @@ -40,12 +40,19 @@ #include "native/jni.h" +/* keep this order of the native includes */ + #include "native/include/java_lang_Object.h" #if defined(ENABLE_JAVASE) -# include "native/include/java_lang_String.h"/* required by java_lang_Class.h */ +# include "native/include/java_lang_String.h" /* required by j.l.C */ + +# if defined(WITH_CLASSPATH_SUN) +# include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */ +# endif + +# include "native/include/java_lang_ClassLoader.h" /* required by j.l.C */ # include "native/include/java_lang_Class.h" -# include "native/include/java_lang_ClassLoader.h" # include "native/include/java_security_ProtectionDomain.h" #endif @@ -72,6 +79,7 @@ java_lang_Class *_Jv_java_lang_ClassLoader_defineClass(java_lang_ClassLoader *cl utf *utfname; classinfo *c; java_lang_Class *o; + #if defined(ENABLE_JVMTI) jint new_class_data_len = 0; unsigned char* new_class_data = NULL; @@ -125,11 +133,15 @@ java_lang_Class *_Jv_java_lang_ClassLoader_defineClass(java_lang_ClassLoader *cl if (c == NULL) return NULL; - /* set ProtectionDomain */ + /* for convenience */ o = (java_lang_Class *) c; +#if defined(WITH_CLASSPATH_GNU) + /* set ProtectionDomain */ + o->pd = pd; +#endif return o; } diff --git a/src/native/vm/java_lang_Object.c b/src/native/vm/java_lang_Object.c index adadd0d0b..be107dde0 100644 --- a/src/native/vm/java_lang_Object.c +++ b/src/native/vm/java_lang_Object.c @@ -35,21 +35,24 @@ #include "native/jni.h" -#if defined(ENABLE_JAVAME_CLDC1_1) -# include "native/include/java_lang_String.h"/* required by java_lang_Class.h */ -#endif - -#include "native/include/java_lang_Class.h" +#include "native/include/java_lang_Object.h" +#include "native/include/java_lang_String.h" /* required by j.l.CL */ #if defined(ENABLE_JAVASE) +# if defined(WITH_CLASSPATH_SUN) +# include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */ +# endif + +# include "native/include/java_lang_ClassLoader.h" /* required by j.l.C */ # include "native/include/java_lang_Cloneable.h" #endif -#include "native/include/java_lang_Object.h" +#include "native/include/java_lang_Class.h" #include "threads/lock-common.h" #include "vm/builtin.h" +#include "vm/exceptions.h" #include "vmcore/options.h" @@ -65,12 +68,17 @@ */ java_lang_Class *_Jv_java_lang_Object_getClass(java_lang_Object *obj) { - classinfo *c; + java_objectheader *o; + classinfo *c; + + o = (java_objectheader *) obj; - if (obj == NULL) + if (o == NULL) { + exceptions_throw_nullpointerexception(); return NULL; + } - c = ((java_objectheader *) obj)->vftbl->class; + c = o->vftbl->class; return (java_lang_Class *) c; } diff --git a/src/native/vm/java_lang_Object.h b/src/native/vm/java_lang_Object.h index 9d7146513..a33e4bcfd 100644 --- a/src/native/vm/java_lang_Object.h +++ b/src/native/vm/java_lang_Object.h @@ -35,12 +35,19 @@ #include "native/jni.h" -#include "native/include/java_lang_Class.h" - #if defined(ENABLE_JAVASE) +# include "native/include/java_lang_String.h" /* required by j.l.CL */ + +# if defined(WITH_CLASSPATH_SUN) +# include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */ +# endif + +# include "native/include/java_lang_ClassLoader.h" /* required by j.l.C */ # include "native/include/java_lang_Cloneable.h" #endif +#include "native/include/java_lang_Class.h" + #include "native/include/java_lang_Object.h" diff --git a/src/native/vm/java_lang_Thread.c b/src/native/vm/java_lang_Thread.c index b13766677..421c1823e 100644 --- a/src/native/vm/java_lang_Thread.c +++ b/src/native/vm/java_lang_Thread.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: java_lang_Thread.c 7833 2007-04-26 13:07:05Z twisti $ + $Id: java_lang_Thread.c 8132 2007-06-22 11:15:47Z twisti $ */ @@ -40,7 +40,10 @@ #if defined(ENABLE_JAVASE) # include "native/include/java_lang_ThreadGroup.h" -# include "native/include/java_lang_VMThread.h" + +# if defined(WITH_CLASSPATH_GNU) +# include "native/include/java_lang_VMThread.h" +# endif #endif #include "threads/lock-common.h" @@ -123,15 +126,30 @@ void _Jv_java_lang_Thread_interrupt(java_lang_Thread *this) s4 _Jv_java_lang_Thread_isAlive(java_lang_Thread *this) { #if defined(ENABLE_THREADS) - threadobject *thread; + threadobject *t; -#if defined(WITH_CLASSPATH_GNU) - thread = (threadobject *) this->vmThread->vmdata; -#elif defined(WITH_CLASSPATH_CLDC1_1) - thread = (threadobject *) this->vm_thread; -#endif +# if defined(WITH_CLASSPATH_GNU) + t = (threadobject *) this->vmThread->vmdata; +# elif defined(WITH_CLASSPATH_SUN) + /* XXX this is just a quick hack */ - return threads_thread_is_alive(thread); + for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) { + if (t->object == this) + break; + } + + /* The threadobject is null when a thread is created in Java. The + priority is set later during startup. */ + + if (t == NULL) + return 0; +# elif defined(WITH_CLASSPATH_CLDC1_1) + t = (threadobject *) this->vm_thread; +# else +# error unknown classpath configuration +# endif + + return threads_thread_is_alive(t); #else /* if threads are disabled, the only thread running is alive */ @@ -148,15 +166,24 @@ s4 _Jv_java_lang_Thread_isAlive(java_lang_Thread *this) s4 _Jv_java_lang_Thread_isInterrupted(java_lang_Thread *this) { #if defined(ENABLE_THREADS) - threadobject *thread; + threadobject *t; -#if defined(WITH_CLASSPATH_GNU) - thread = (threadobject *) this->vmThread->vmdata; -#elif defined(WITH_CLASSPATH_CLDC1_1) - thread = (threadobject *) this->vm_thread; -#endif +# if defined(WITH_CLASSPATH_GNU) + t = (threadobject *) this->vmThread->vmdata; +# elif defined(WITH_CLASSPATH_SUN) + /* XXX this is just a quick hack */ + + for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) { + if (t->object == this) + break; + } +# elif defined(WITH_CLASSPATH_CLDC1_1) + t = (threadobject *) this->vm_thread; +# else +# error unknown classpath configuration +# endif - return threads_thread_has_been_interrupted(thread); + return threads_thread_has_been_interrupted(t); #else return 0; #endif @@ -195,21 +222,36 @@ void _Jv_java_lang_Thread_resume(java_lang_Thread *this) void _Jv_java_lang_Thread_setPriority(java_lang_Thread *this, s4 priority) { #if defined(ENABLE_THREADS) - threadobject *thread; + threadobject *t; -#if defined(WITH_CLASSPATH_GNU) - thread = (threadobject *) this->vmThread->vmdata; -#elif defined(WITH_CLASSPATH_CLDC1_1) - thread = (threadobject *) this->vm_thread; +# if defined(WITH_CLASSPATH_GNU) + t = (threadobject *) this->vmThread->vmdata; +# elif defined(WITH_CLASSPATH_SUN) + /* XXX this is just a quick hack */ + + for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) { + if (t->object == this) + break; + } /* The threadobject is null when a thread is created in Java. The priority is set later during startup. */ - if (thread == NULL) + if (t == NULL) return; -#endif +# elif defined(WITH_CLASSPATH_CLDC1_1) + t = (threadobject *) this->vm_thread; + + /* The threadobject is null when a thread is created in Java. The + priority is set later during startup. */ + + if (t == NULL) + return; +# else +# error unknown classpath configuration +# endif - threads_set_thread_priority(thread->tid, priority); + threads_set_thread_priority(t->tid, priority); #endif } diff --git a/src/native/vm/java_lang_reflect_Constructor.c b/src/native/vm/java_lang_reflect_Constructor.c index 2f133e82b..584b00f4e 100644 --- a/src/native/vm/java_lang_reflect_Constructor.c +++ b/src/native/vm/java_lang_reflect_Constructor.c @@ -37,8 +37,14 @@ #include "native/jni.h" #include "native/native.h" +#if defined(WITH_CLASSPATH_SUN) +# include "native/include/java_lang_String.h" /* required by j.l.CL */ +# include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */ +# include "native/include/java_lang_ClassLoader.h" /* required my j.l.C */ +#endif + +#include "native/include/java_lang_Object.h" /* required my j.l.C */ #include "native/include/java_lang_Class.h" -#include "native/include/java_lang_Object.h" #include "native/include/java_lang_String.h" #include "native/include/java_lang_reflect_Constructor.h" @@ -116,6 +122,7 @@ java_lang_Object *_Jv_java_lang_reflect_Constructor_newInstance(JNIEnv *env, jav { classinfo *c; methodinfo *m; + s4 override; java_objectheader *o; c = (classinfo *) this->clazz; @@ -125,7 +132,15 @@ java_lang_Object *_Jv_java_lang_reflect_Constructor_newInstance(JNIEnv *env, jav /* check if we should bypass security checks (AccessibleObject) */ - if (this->flag == false) { +#if defined(WITH_CLASSPATH_GNU) + override = this->flag; +#elif defined(WITH_CLASSPATH_SUN) + override = this->override; +#else +# error unknown classpath configuration +#endif + + if (override == false) { if (!access_check_method(m, 1)) return NULL; } diff --git a/src/native/vm/java_lang_reflect_Method.c b/src/native/vm/java_lang_reflect_Method.c index 9d3f3d12b..0830afd22 100644 --- a/src/native/vm/java_lang_reflect_Method.c +++ b/src/native/vm/java_lang_reflect_Method.c @@ -57,15 +57,24 @@ java_lang_Object *_Jv_java_lang_reflect_Method_invoke(java_lang_reflect_Method * { classinfo *c; methodinfo *m; + s4 override; - c = (classinfo *) this->declaringClass; + c = (classinfo *) this->clazz; m = &(c->methods[this->slot]); /* check method access */ /* check if we should bypass security checks (AccessibleObject) */ - if (this->flag == false) { +#if defined(WITH_CLASSPATH_GNU) + override = this->flag; +#elif defined(WITH_CLASSPATH_SUN) + override = this->override; +#else +# error unknown classpath configuration +#endif + + if (override == false) { if (!access_check_method(m, 1)) return NULL; } @@ -78,7 +87,7 @@ java_lang_Object *_Jv_java_lang_reflect_Method_invoke(java_lang_reflect_Method * /* call the Java method via a helper function */ - return (java_lang_Object *) _Jv_jni_invokeNative(m, (jobject) o, args); + return (java_lang_Object *) _Jv_jni_invokeNative(m, (java_objectheader *) o, args); } diff --git a/src/native/vm/nativevm.c b/src/native/vm/nativevm.c index 6c81da055..fdf4aa063 100644 --- a/src/native/vm/nativevm.c +++ b/src/native/vm/nativevm.c @@ -32,14 +32,25 @@ #include "native/vm/nativevm.h" +#include "vmcore/method.h" -/* nativevm_init *************************************************************** +#if defined(WITH_CLASSPATH_SUN) +# include "native/native.h" - Initialize the implementation specific native stuff. +# include "vm/vm.h" + +# include "vmcore/class.h" +# include "vmcore/utf8.h" +#endif + + +/* nativevm_preinit ************************************************************ + + Pre-initialize the implementation specific native stuff. *******************************************************************************/ -bool nativevm_init(void) +bool nativevm_preinit(void) { /* register native methods of all classes implemented */ @@ -70,6 +81,18 @@ bool nativevm_init(void) _Jv_java_util_concurrent_atomic_AtomicLong_init(); _Jv_sun_misc_Unsafe_init(); +# elif defined(WITH_CLASSPATH_SUN) + + utf *u; + lt_dlhandle handle; + + u = utf_new_char(CLASSPATH_LIBDIR"/libjava.so"); + + handle = native_library_open(u); + native_library_add(u, NULL, handle); + + _Jv_sun_misc_Unsafe_init(); + # else # error unknown classpath configuration @@ -105,6 +128,57 @@ bool nativevm_init(void) } +/* nativevm_init *************************************************************** + + Initialize the implementation specific native stuff. + +*******************************************************************************/ + +bool nativevm_init(void) +{ +#if defined(ENABLE_JAVASE) + +# if defined(WITH_CLASSPATH_GNU) + + /* nothing to do */ + +# elif defined(WITH_CLASSPATH_SUN) + + methodinfo *m; + + m = class_resolveclassmethod(class_java_lang_System, + utf_new_char("initializeSystemClass"), + utf_void__void, + class_java_lang_Object, + false); + + if (m == NULL) + return false; + + (void) vm_call_method(m, NULL); + +# else + +# error unknown classpath configuration + +# endif + +#elif defined(ENABLE_JAVAME_CLDC1_1) + + /* nothing to do */ + +#else + +# error unknown Java configuration + +#endif + + /* everything's ok */ + + return true; +} + + /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where diff --git a/src/native/vm/nativevm.h b/src/native/vm/nativevm.h index edddff327..8920fa859 100644 --- a/src/native/vm/nativevm.h +++ b/src/native/vm/nativevm.h @@ -38,6 +38,7 @@ /* function prototypes ********************************************************/ +bool nativevm_preinit(void); bool nativevm_init(void); #if defined(ENABLE_JAVASE) @@ -67,6 +68,10 @@ void _Jv_java_security_VMAccessController_init(); void _Jv_java_util_concurrent_atomic_AtomicLong_init(); void _Jv_sun_misc_Unsafe_init(); +# elif defined(WITH_CLASSPATH_SUN) + +void _Jv_sun_misc_Unsafe_init(); + # else # error unknown classpath configuration diff --git a/src/native/vm/sun/Makefile.am b/src/native/vm/sun/Makefile.am new file mode 100644 index 000000000..c1d2705a3 --- /dev/null +++ b/src/native/vm/sun/Makefile.am @@ -0,0 +1,46 @@ +## src/native/vm/sun/Makefile.am +## +## Copyright (C) 2007 R. Grafl, A. Krall, C. Kruegel, +## C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring, +## E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, +## J. Wenninger, Institut f. Computersprachen - TU Wien +## +## This file is part of CACAO. +## +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation; either version 2, or (at +## your option) any later version. +## +## This program is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +## 02110-1301, USA. +## +## $Id: Makefile.am 6233 2006-12-26 23:13:16Z twisti $ + +## Process this file with automake to produce Makefile.in + +AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR) -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR)/$(OS_DIR) -I$(top_builddir)/src + +LIBS = + +noinst_LTLIBRARIES = \ + libnativevmcore.la + +libnativevmcore_la_SOURCES = \ + jvm.c + + +## Local variables: +## mode: Makefile +## indent-tabs-mode: t +## c-basic-offset: 4 +## tab-width: 8 +## compile-command: "automake --add-missing" +## End: diff --git a/src/native/vm/sun/jvm.c b/src/native/vm/sun/jvm.c new file mode 100644 index 000000000..8babfc579 --- /dev/null +++ b/src/native/vm/sun/jvm.c @@ -0,0 +1,2432 @@ +#define PRINTJVM 0 + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#if defined(HAVE_SYS_IOCTL_H) +#define BSD_COMP /* Get FIONREAD on Solaris2 */ +#include +#endif + +#include +#include + +#include "vm/types.h" + +#include "mm/memory.h" + +#include "native/jni.h" +#include "native/native.h" + +#include "native/include/java_lang_AssertionStatusDirectives.h" +#include "native/include/java_lang_String.h" /* required by j.l.CL */ +#include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */ +#include "native/include/java_lang_ClassLoader.h" /* required by j.l.C */ +#include "native/include/java_lang_StackTraceElement.h" +#include "native/include/java_lang_Throwable.h" +#include "native/include/java_security_ProtectionDomain.h" + +#include "native/vm/java_lang_Class.h" +#include "native/vm/java_lang_ClassLoader.h" +#include "native/vm/java_lang_Object.h" +#include "native/vm/java_lang_Runtime.h" +#include "native/vm/java_lang_String.h" +#include "native/vm/java_lang_Thread.h" +#include "native/vm/java_lang_reflect_Constructor.h" +#include "native/vm/java_lang_reflect_Method.h" +#include "native/vm/java_util_concurrent_atomic_AtomicLong.h" + +#include "threads/lock-common.h" + +#include "toolbox/logging.h" + +#include "vm/builtin.h" +#include "vm/exceptions.h" +#include "vm/initialize.h" +#include "vm/properties.h" +#include "vm/stringlocal.h" +#include "vm/vm.h" + +#include "vm/jit/stacktrace.h" + +#include "vmcore/classcache.h" +#include "vmcore/primitive.h" + + +/* debugging macro ************************************************************/ + +#if !defined(NDEBUG) +# define DEBUG_JVM(x) \ + do { \ + if (opt_TraceJVM) { \ + log_println("%s", (x)); \ + } \ + } while (0) +#else +# define DEBUG_JVM(x) +#endif + + +typedef struct { + /* Naming convention of RE build version string: n.n.n[_uu[c]][-]-bxx */ + unsigned int jvm_version; /* Consists of major, minor, micro (n.n.n) */ + /* and build number (xx) */ + unsigned int update_version : 8; /* Update release version (uu) */ + unsigned int special_update_version : 8; /* Special update release version (c) */ + unsigned int reserved1 : 16; + unsigned int reserved2; + + /* The following bits represents JVM supports that JDK has dependency on. + * JDK can use these bits to determine which JVM version + * and support it has to maintain runtime compatibility. + * + * When a new bit is added in a minor or update release, make sure + * the new bit is also added in the main/baseline. + */ + unsigned int is_attachable : 1; + unsigned int : 31; + unsigned int : 32; + unsigned int : 32; +} jvm_version_info; + + +/* + * A structure used to a capture exception table entry in a Java method. + */ +typedef struct { + jint start_pc; + jint end_pc; + jint handler_pc; + jint catchType; +} JVM_ExceptionTableEntryType; + + +int jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args) +{ + return vsnprintf(str, count, fmt, args); +} + + +int jio_snprintf(char *str, size_t count, const char *fmt, ...) +{ + log_println("jio_snprintf: IMPLEMENT ME!"); +} + + +int jio_fprintf(FILE* f, const char *fmt, ...) +{ + log_println("jio_fprintf: IMPLEMENT ME!"); +} + + +int jio_vfprintf(FILE* f, const char *fmt, va_list args) +{ + log_println("jio_vfprintf: IMPLEMENT ME!"); +} + + +int jio_printf(const char *fmt, ...) +{ + log_println("jio_printf: IMPLEMENT ME!"); +} + + +/* JVM_GetInterfaceVersion */ + +jint JVM_GetInterfaceVersion() +{ + /* This is defined in hotspot/src/share/vm/prims/jvm.h */ + +#define JVM_INTERFACE_VERSION 4 + + return JVM_INTERFACE_VERSION; +} + + +/* JVM_CurrentTimeMillis */ + +jlong JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored) +{ +#if PRINTJVM + log_println("JVM_CurrentTimeMillis"); +#endif + return (jlong) builtin_currenttimemillis(); +} + + +/* JVM_NanoTime */ + +jlong JVM_NanoTime(JNIEnv *env, jclass ignored) +{ +#if PRINTJVM + log_println("JVM_NanoTime"); +#endif + return (jlong) builtin_nanotime(); +} + + +/* JVM_ArrayCopy */ + +void JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos, jobject dst, jint dst_pos, jint length) +{ +#if PRINTJVM + log_println("JVM_ArrayCopy: src=%p, src_pos=%d, dst=%p, dst_pos=%d, length=%d", src, src_pos, dst, dst_pos, length); +#endif + builtin_arraycopy(src, src_pos, dst, dst_pos, length); +} + + +/* JVM_InitProperties */ + +jobject JVM_InitProperties(JNIEnv *env, jobject properties) +{ +#if PRINTJVM + log_println("JVM_InitProperties: properties=%d", properties); +#endif + properties_system_add_all((java_objectheader *) properties); +} + + +/* JVM_Exit */ + +void JVM_Exit(jint code) +{ + log_println("JVM_Exit: IMPLEMENT ME!"); +} + + +/* JVM_Halt */ + +void JVM_Halt(jint code) +{ +#if PRINTJVM + log_println("JVM_Halt: code=%d", code); +#endif +/* vm_exit(code); */ + vm_shutdown(code); +} + + +/* JVM_OnExit(void (*func)) */ + +void JVM_OnExit(void (*func)(void)) +{ + log_println("JVM_OnExit(void (*func): IMPLEMENT ME!"); +} + + +/* JVM_GC */ + +void JVM_GC(void) +{ +#if PRINTJVM + log_println("JVM_GC"); +#endif + _Jv_java_lang_Runtime_gc(); +} + + +/* JVM_MaxObjectInspectionAge */ + +jlong JVM_MaxObjectInspectionAge(void) +{ + log_println("JVM_MaxObjectInspectionAge: IMPLEMENT ME!"); +} + + +/* JVM_TraceInstructions */ + +void JVM_TraceInstructions(jboolean on) +{ + log_println("JVM_TraceInstructions: IMPLEMENT ME!"); +} + + +/* JVM_TraceMethodCalls */ + +void JVM_TraceMethodCalls(jboolean on) +{ + log_println("JVM_TraceMethodCalls: IMPLEMENT ME!"); +} + + +/* JVM_TotalMemory */ + +jlong JVM_TotalMemory(void) +{ +#if PRINTJVM + log_println("JVM_TotalMemory"); +#endif + return _Jv_java_lang_Runtime_totalMemory(); +} + + +/* JVM_FreeMemory */ + +jlong JVM_FreeMemory(void) +{ +#if PRINTJVM + log_println("JVM_FreeMemory"); +#endif + return _Jv_java_lang_Runtime_freeMemory(); +} + + +/* JVM_MaxMemory */ + +jlong JVM_MaxMemory(void) +{ + log_println("JVM_MaxMemory: IMPLEMENT ME!"); +} + + +/* JVM_ActiveProcessorCount */ + +jint JVM_ActiveProcessorCount(void) +{ + log_println("JVM_ActiveProcessorCount: IMPLEMENT ME!"); +} + + +/* JVM_FillInStackTrace */ + +void JVM_FillInStackTrace(JNIEnv *env, jobject receiver) +{ + java_lang_Throwable *o; + stacktracecontainer *stc; + +#if PRINTJVM + log_println("JVM_FillInStackTrace: receiver=%p", receiver); +#endif + + o = (java_lang_Throwable *) receiver; + + stc = stacktrace_fillInStackTrace(); + + if (stc == NULL) + return; + + o->backtrace = (java_lang_Object *) stc; +} + + +/* JVM_PrintStackTrace */ + +void JVM_PrintStackTrace(JNIEnv *env, jobject receiver, jobject printable) +{ + log_println("JVM_PrintStackTrace: IMPLEMENT ME!"); +} + + +/* JVM_GetStackTraceDepth */ + +jint JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable) +{ + java_lang_Throwable *o; + stacktracecontainer *stc; + stacktracebuffer *stb; + +#if PRINTJVM + log_println("JVM_GetStackTraceDepth: throwable=%p", throwable); +#endif + + o = (java_lang_Throwable *) throwable; + stc = (stacktracecontainer *) o->backtrace; + stb = &(stc->stb); + + return stb->used; +} + + +/* JVM_GetStackTraceElement */ + +jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index) +{ + java_lang_Throwable *t; + stacktracecontainer *stc; + stacktracebuffer *stb; + stacktrace_entry *ste; + java_lang_StackTraceElement *o; + java_lang_String *declaringclass; + java_lang_String *filename; + s4 linenumber; + +#if PRINTJVM + log_println("JVM_GetStackTraceElement: throwable=%p, index=%d", throwable, index); +#endif + + t = (java_lang_Throwable *) throwable; + stc = (stacktracecontainer *) t->backtrace; + stb = &(stc->stb); + + if ((index < 0) || (index >= stb->used)) { + /* XXX This should be an IndexOutOfBoundsException (check this + again). */ + + exceptions_throw_arrayindexoutofboundsexception(); + return NULL; + } + + ste = &(stb->entries[index]); + + /* allocate a new StackTraceElement */ + + o = (java_lang_StackTraceElement *) + builtin_new(class_java_lang_StackTraceElement); + + if (o == NULL) + return NULL; + + /* get filename */ + + if (!(ste->method->flags & ACC_NATIVE)) { + if (ste->method->class->sourcefile) + filename = (java_lang_String *) javastring_new(ste->method->class->sourcefile); + else + filename = NULL; + } + else + filename = NULL; + + /* get line number */ + + if (ste->method->flags & ACC_NATIVE) + linenumber = -2; + else + linenumber = (ste->linenumber == 0) ? -1 : ste->linenumber; + + /* get declaring class name */ + + declaringclass = + _Jv_java_lang_Class_getName((java_lang_Class *) ste->method->class); + + /* fill the java.lang.StackTraceElement element */ + + o->declaringClass = declaringclass; + o->methodName = (java_lang_String *) javastring_new(ste->method->name); + o->fileName = filename; + o->lineNumber = linenumber; + + return o; +} + + +/* JVM_IHashCode */ + +jint JVM_IHashCode(JNIEnv* env, jobject handle) +{ +#if PRINTJVM + log_println("JVM_IHashCode: jobject=%p", handle); +#endif + return (jint) ((ptrint) handle); +} + + +/* JVM_MonitorWait */ + +void JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms) +{ +#if PRINTJVM + log_println("JVM_MonitorWait: handle=%p, ms=%ld", handle, ms); +#endif + _Jv_java_lang_Object_wait((java_lang_Object *) handle, ms, 0); +} + + +/* JVM_MonitorNotify */ + +void JVM_MonitorNotify(JNIEnv* env, jobject handle) +{ +#if PRINTJVM + log_println("JVM_MonitorNotify: IMPLEMENT ME!"); +#endif + _Jv_java_lang_Object_notify((java_lang_Object *) handle); +} + + +/* JVM_MonitorNotifyAll */ + +void JVM_MonitorNotifyAll(JNIEnv* env, jobject handle) +{ +#if PRINTJVM + log_println("JVM_MonitorNotifyAll: handle=%p", handle); +#endif + _Jv_java_lang_Object_notifyAll((java_lang_Object *) handle); +} + + +/* JVM_Clone */ + +jobject JVM_Clone(JNIEnv* env, jobject handle) +{ +#if PRINTJVM + log_println("JVM_Clone: handle=%p", handle); +#endif + return (jobject) builtin_clone(env, (java_objectheader *) handle); +} + + +/* JVM_InitializeCompiler */ + +void JVM_InitializeCompiler (JNIEnv *env, jclass compCls) +{ + log_println("JVM_InitializeCompiler : IMPLEMENT ME!"); +} + + +/* JVM_IsSilentCompiler */ + +jboolean JVM_IsSilentCompiler(JNIEnv *env, jclass compCls) +{ + log_println("JVM_IsSilentCompiler: IMPLEMENT ME!"); +} + + +/* JVM_CompileClass */ + +jboolean JVM_CompileClass(JNIEnv *env, jclass compCls, jclass cls) +{ + log_println("JVM_CompileClass: IMPLEMENT ME!"); +} + + +/* JVM_CompileClasses */ + +jboolean JVM_CompileClasses(JNIEnv *env, jclass cls, jstring jname) +{ + log_println("JVM_CompileClasses: IMPLEMENT ME!"); +} + + +/* JVM_CompilerCommand */ + +jobject JVM_CompilerCommand(JNIEnv *env, jclass compCls, jobject arg) +{ + log_println("JVM_CompilerCommand: IMPLEMENT ME!"); +} + + +/* JVM_EnableCompiler */ + +void JVM_EnableCompiler(JNIEnv *env, jclass compCls) +{ + log_println("JVM_EnableCompiler: IMPLEMENT ME!"); +} + + +/* JVM_DisableCompiler */ + +void JVM_DisableCompiler(JNIEnv *env, jclass compCls) +{ + log_println("JVM_DisableCompiler: IMPLEMENT ME!"); +} + + +/* JVM_GetLastErrorString */ + +jint JVM_GetLastErrorString(char *buf, int len) +{ + const char *s; + int n; + + if (errno == 0) { + return 0; + } + else { + s = strerror(errno); + n = strlen(s); + + if (n >= len) + n = len - 1; + + strncpy(buf, s, n); + + buf[n] = '\0'; + + return n; + } +} + + +/* JVM_NativePath */ + +char* JVM_NativePath(char* path) +{ +#if PRINTJVM + log_println("JVM_NativePath: path=%s", path); +#endif + /* XXX is this correct? */ + + return path; +} + + +/* JVM_GetCallerClass */ + +jclass JVM_GetCallerClass(JNIEnv* env, int depth) +{ + java_objectarray *oa; + +#if PRINTJVM + log_println("JVM_GetCallerClass: depth=%d", depth); +#endif + + oa = stacktrace_getClassContext(); + + if (oa == NULL) + return NULL; + + if (oa->header.size < depth) + return NULL; + + return (jclass) oa->data[depth - 1]; + +} + + +/* JVM_FindPrimitiveClass */ + +jclass JVM_FindPrimitiveClass(JNIEnv* env, const char* utf) +{ +#if PRINTVM + log_println("JVM_FindPrimitiveClass: utf=%s", utf); +#endif + return (jclass) primitive_class_get_by_name(utf_new_char(utf)); +} + + +/* JVM_ResolveClass */ + +void JVM_ResolveClass(JNIEnv* env, jclass cls) +{ + log_println("JVM_ResolveClass: IMPLEMENT ME!"); +} + + +/* JVM_FindClassFromClassLoader */ + +jclass JVM_FindClassFromClassLoader(JNIEnv* env, const char* name, jboolean init, jobject loader, jboolean throwError) +{ + classinfo *c; + +#if PRINTJVM + log_println("JVM_FindClassFromClassLoader: name=%s, init=%d, loader=%p, throwError=%d", name, init, loader, throwError); +#endif + + c = load_class_from_classloader(utf_new_char(name), (java_objectheader *) loader); + + if (c == NULL) + return NULL; + + if (init) + if (!(c->state & CLASS_INITIALIZED)) + if (!initialize_class(c)) + return NULL; + + return (jclass) c; +} + + +/* JVM_FindClassFromClass */ + +jclass JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init, jclass from) +{ + log_println("JVM_FindClassFromClass: IMPLEMENT ME!"); +} + + +/* JVM_DefineClass */ + +jclass JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd) +{ + log_println("JVM_DefineClass: IMPLEMENT ME!"); +} + + +/* JVM_DefineClassWithSource */ + +jclass JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source) +{ +#if PRINTJVM + log_println("JVM_DefineClassWithSource: name=%s, loader=%p, buf=%p, len=%d, pd=%p, source=%s", name, loader, buf, len, pd, source); +#endif + /* XXX do something with pd and source */ + + return (jclass) class_define(utf_new_char(name), (java_objectheader *) loader, len, (u1 *) buf); + +} + + +/* JVM_FindLoadedClass */ + +jclass JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name) +{ +#if PRINTJVM + log_println("JVM_FindLoadedClass: loader=%p, name=%p", loader, name); +#endif + return (jclass) classcache_lookup((classloader *) loader, javastring_toutf(name, true)); +} + + +/* JVM_GetClassName */ + +jstring JVM_GetClassName(JNIEnv *env, jclass cls) +{ +#if PRINTJVM + log_println("JVM_GetClassName: cls=%p", cls); +#endif + return (jstring) _Jv_java_lang_Class_getName((java_lang_Class *) cls); +} + + +/* JVM_GetClassInterfaces */ + +jobjectArray JVM_GetClassInterfaces(JNIEnv *env, jclass cls) +{ +#if PRINTJVM + log_println("JVM_GetClassInterfaces: cls=%p", cls); +#endif + return (jobjectArray) _Jv_java_lang_Class_getInterfaces((java_lang_Class *) cls); +} + + +/* JVM_GetClassLoader */ + +jobject JVM_GetClassLoader(JNIEnv *env, jclass cls) +{ +#if PRINTJVM + log_println("JVM_GetClassLoader: cls=%p", cls); +#endif + return (jobject) _Jv_java_lang_Class_getClassLoader((java_lang_Class *) cls); +} + + +/* JVM_IsInterface */ + +jboolean JVM_IsInterface(JNIEnv *env, jclass cls) +{ +#if PRINTJVM + log_println("JVM_IsInterface: cls=%p", cls); +#endif + return _Jv_java_lang_Class_isInterface((java_lang_Class *) cls); +} + + +/* JVM_GetClassSigners */ + +jobjectArray JVM_GetClassSigners(JNIEnv *env, jclass cls) +{ + log_println("JVM_GetClassSigners: IMPLEMENT ME!"); +} + + +/* JVM_SetClassSigners */ + +void JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers) +{ + log_println("JVM_SetClassSigners: IMPLEMENT ME!"); +} + + +/* JVM_GetProtectionDomain */ + +jobject JVM_GetProtectionDomain(JNIEnv *env, jclass cls) +{ + classinfo *c; + +#if PRINTJVM || 1 + log_println("JVM_GetProtectionDomain: cls=%p"); +#endif + + c = (classinfo *) cls; + + if (c == NULL) { + exceptions_throw_nullpointerexception(); + return NULL; + } + + /* Primitive types do not have a protection domain. */ + + if (primitive_class_is_primitive(c)) + return NULL; +} + + +/* JVM_SetProtectionDomain */ + +void JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protection_domain) +{ + log_println("JVM_SetProtectionDomain: IMPLEMENT ME!"); +} + + +/* JVM_DoPrivileged */ + +jobject JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject context, jboolean wrapException) +{ + java_objectheader *o; + classinfo *c; + methodinfo *m; + java_objectheader *result; + java_objectheader *e; + +#if PRINTJVM + log_println("JVM_DoPrivileged: action=%p, context=%p, wrapException=%d", action, context, wrapException); +#endif + + o = (java_objectheader *) action; + c = o->vftbl->class; + + if (action == NULL) { + exceptions_throw_nullpointerexception(); + return NULL; + } + + /* lookup run() method (throw no exceptions) */ + + m = class_resolveclassmethod(c, utf_run, utf_void__java_lang_Object, c, + false); + + if ((m == NULL) || !(m->flags & ACC_PUBLIC) || (m->flags & ACC_STATIC)) { + exceptions_throw_internalerror("No run method"); + return NULL; + } + + /* XXX It seems something with a privileged stack needs to be done + here. */ + + result = vm_call_method(m, o); + + e = exceptions_get_and_clear_exception(); + + if (e != NULL) { + exceptions_throw_privilegedactionexception(e); + return NULL; + } + + return (jobject) result; +} + + +/* JVM_GetInheritedAccessControlContext */ + +jobject JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls) +{ + log_println("JVM_GetInheritedAccessControlContext: IMPLEMENT ME!"); +} + + +/* JVM_GetStackAccessControlContext */ + +jobject JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls) +{ + log_println("JVM_GetStackAccessControlContext: IMPLEMENT ME!"); +} + + +/* JVM_IsArrayClass */ + +jboolean JVM_IsArrayClass(JNIEnv *env, jclass cls) +{ +#if PRINTJVM + log_println("JVM_IsArrayClass: cls=%p", cls); +#endif + return _Jv_java_lang_Class_isArray((java_lang_Class *) cls); +} + + +/* JVM_IsPrimitiveClass */ + +jboolean JVM_IsPrimitiveClass(JNIEnv *env, jclass cls) +{ +#if PRINTJVM + log_println("JVM_IsPrimitiveClass: cls=%p", cls); +#endif + return primitive_class_is_primitive((classinfo *) cls); +} + + +/* JVM_GetComponentType */ + +jclass JVM_GetComponentType(JNIEnv *env, jclass cls) +{ +#if PRINTJVM + log_println("JVM_GetComponentType: cls=%p", cls); +#endif + return (jclass) _Jv_java_lang_Class_getComponentType((java_lang_Class *) cls); +} + + +/* JVM_GetClassModifiers */ + +jint JVM_GetClassModifiers(JNIEnv *env, jclass cls) +{ + classinfo *c; + +#if PRINTJVM + log_println("JVM_GetClassModifiers: cls=%p", cls); +#endif + + c = (classinfo *) cls; + + /* XXX is this correct? */ + + return c->flags & ACC_CLASS_REFLECT_MASK; +} + + +/* JVM_GetDeclaredClasses */ + +jobjectArray JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass) +{ + log_println("JVM_GetDeclaredClasses: IMPLEMENT ME!"); +} + + +/* JVM_GetDeclaringClass */ + +jclass JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass) +{ + log_println("JVM_GetDeclaringClass: IMPLEMENT ME!"); +} + + +/* JVM_GetClassSignature */ + +jstring JVM_GetClassSignature(JNIEnv *env, jclass cls) +{ + log_println("JVM_GetClassSignature: IMPLEMENT ME!"); +} + + +/* JVM_GetClassAnnotations */ + +jbyteArray JVM_GetClassAnnotations(JNIEnv *env, jclass cls) +{ + log_println("JVM_GetClassAnnotations: IMPLEMENT ME!"); +} + + +/* JVM_GetFieldAnnotations */ + +jbyteArray JVM_GetFieldAnnotations(JNIEnv *env, jobject field) +{ + log_println("JVM_GetFieldAnnotations: IMPLEMENT ME!"); +} + + +/* JVM_GetMethodAnnotations */ + +jbyteArray JVM_GetMethodAnnotations(JNIEnv *env, jobject method) +{ + log_println("JVM_GetMethodAnnotations: IMPLEMENT ME!"); +} + + +/* JVM_GetMethodDefaultAnnotationValue */ + +jbyteArray JVM_GetMethodDefaultAnnotationValue(JNIEnv *env, jobject method) +{ + log_println("JVM_GetMethodDefaultAnnotationValue: IMPLEMENT ME!"); +} + + +/* JVM_GetMethodParameterAnnotations */ + +jbyteArray JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject method) +{ + log_println("JVM_GetMethodParameterAnnotations: IMPLEMENT ME!"); +} + + +/* JVM_GetClassDeclaredFields */ + +jobjectArray JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly) +{ +#if PRINTJVM + log_println("JVM_GetClassDeclaredFields: ofClass=%p, publicOnly=%d", ofClass, publicOnly); +#endif + return (jobjectArray) _Jv_java_lang_Class_getDeclaredFields((java_lang_Class *) ofClass, publicOnly); +} + + +/* JVM_GetClassDeclaredMethods */ + +jobjectArray JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly) +{ +#if PRINTJVM + log_println("JVM_GetClassDeclaredMethods: ofClass=%p, publicOnly=%d", ofClass, publicOnly); +#endif + return (jobjectArray) _Jv_java_lang_Class_getDeclaredMethods((java_lang_Class *) ofClass, publicOnly); +} + + +/* JVM_GetClassDeclaredConstructors */ + +jobjectArray JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly) +{ +#if PRINTJVM + log_println("JVM_GetClassDeclaredConstructors: ofClass=%p, publicOnly=%d", ofClass, publicOnly); +#endif + return (jobjectArray) _Jv_java_lang_Class_getDeclaredConstructors((java_lang_Class *) ofClass, publicOnly); +} + + +/* JVM_GetClassAccessFlags */ + +jint JVM_GetClassAccessFlags(JNIEnv *env, jclass cls) +{ + classinfo *c; + +#if PRINTJVM + log_println("JVM_GetClassAccessFlags: cls=%p", cls); +#endif + + c = (classinfo *) cls; + + return c->flags & ACC_CLASS_REFLECT_MASK; +} + + +/* JVM_GetClassConstantPool */ + +jobject JVM_GetClassConstantPool(JNIEnv *env, jclass cls) +{ + log_println("JVM_GetClassConstantPool: IMPLEMENT ME!"); +} + + +/* JVM_ConstantPoolGetSize */ + +jint JVM_ConstantPoolGetSize(JNIEnv *env, jobject unused, jobject jcpool) +{ + log_println("JVM_ConstantPoolGetSize: IMPLEMENT ME!"); +} + + +/* JVM_ConstantPoolGetClassAt */ + +jclass JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject unused, jobject jcpool, jint index) +{ + log_println("JVM_ConstantPoolGetClassAt: IMPLEMENT ME!"); +} + + +/* JVM_ConstantPoolGetClassAtIfLoaded */ + +jclass JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject unused, jobject jcpool, jint index) +{ + log_println("JVM_ConstantPoolGetClassAtIfLoaded: IMPLEMENT ME!"); +} + + +/* JVM_ConstantPoolGetMethodAt */ + +jobject JVM_ConstantPoolGetMethodAt(JNIEnv *env, jobject unused, jobject jcpool, jint index) +{ + log_println("JVM_ConstantPoolGetMethodAt: IMPLEMENT ME!"); +} + + +/* JVM_ConstantPoolGetMethodAtIfLoaded */ + +jobject JVM_ConstantPoolGetMethodAtIfLoaded(JNIEnv *env, jobject unused, jobject jcpool, jint index) +{ + log_println("JVM_ConstantPoolGetMethodAtIfLoaded: IMPLEMENT ME!"); +} + + +/* JVM_ConstantPoolGetFieldAt */ + +jobject JVM_ConstantPoolGetFieldAt(JNIEnv *env, jobject unused, jobject jcpool, jint index) +{ + log_println("JVM_ConstantPoolGetFieldAt: IMPLEMENT ME!"); +} + + +/* JVM_ConstantPoolGetFieldAtIfLoaded */ + +jobject JVM_ConstantPoolGetFieldAtIfLoaded(JNIEnv *env, jobject unused, jobject jcpool, jint index) +{ + log_println("JVM_ConstantPoolGetFieldAtIfLoaded: IMPLEMENT ME!"); +} + + +/* JVM_ConstantPoolGetMemberRefInfoAt */ + +jobjectArray JVM_ConstantPoolGetMemberRefInfoAt(JNIEnv *env, jobject unused, jobject jcpool, jint index) +{ + log_println("JVM_ConstantPoolGetMemberRefInfoAt: IMPLEMENT ME!"); +} + + +/* JVM_ConstantPoolGetIntAt */ + +jint JVM_ConstantPoolGetIntAt(JNIEnv *env, jobject unused, jobject jcpool, jint index) +{ + log_println("JVM_ConstantPoolGetIntAt: IMPLEMENT ME!"); +} + + +/* JVM_ConstantPoolGetLongAt */ + +jlong JVM_ConstantPoolGetLongAt(JNIEnv *env, jobject unused, jobject jcpool, jint index) +{ + log_println("JVM_ConstantPoolGetLongAt: IMPLEMENT ME!"); +} + + +/* JVM_ConstantPoolGetFloatAt */ + +jfloat JVM_ConstantPoolGetFloatAt(JNIEnv *env, jobject unused, jobject jcpool, jint index) +{ + log_println("JVM_ConstantPoolGetFloatAt: IMPLEMENT ME!"); +} + + +/* JVM_ConstantPoolGetDoubleAt */ + +jdouble JVM_ConstantPoolGetDoubleAt(JNIEnv *env, jobject unused, jobject jcpool, jint index) +{ + log_println("JVM_ConstantPoolGetDoubleAt: IMPLEMENT ME!"); +} + + +/* JVM_ConstantPoolGetStringAt */ + +jstring JVM_ConstantPoolGetStringAt(JNIEnv *env, jobject unused, jobject jcpool, jint index) +{ + log_println("JVM_ConstantPoolGetStringAt: IMPLEMENT ME!"); +} + + +/* JVM_ConstantPoolGetUTF8At */ + +jstring JVM_ConstantPoolGetUTF8At(JNIEnv *env, jobject unused, jobject jcpool, jint index) +{ + log_println("JVM_ConstantPoolGetUTF8At: IMPLEMENT ME!"); +} + + +/* JVM_DesiredAssertionStatus */ + +jboolean JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls) +{ + log_println("JVM_DesiredAssertionStatus: cls=%p, IMPLEMENT ME!", cls); + + return false; +} + + +/* JVM_AssertionStatusDirectives */ + +jobject JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused) +{ + classinfo *c; + java_lang_AssertionStatusDirectives *o; + java_objectarray *classes; + java_objectarray *packages; + +#if PRINTJVM || 1 + log_println("JVM_AssertionStatusDirectives"); +#endif + /* XXX this is not completely implemented */ + + c = load_class_bootstrap(utf_new_char("java/lang/AssertionStatusDirectives")); + + if (c == NULL) + return NULL; + + o = (java_lang_AssertionStatusDirectives *) builtin_new(c); + + if (o == NULL) + return NULL; + + classes = builtin_anewarray(0, class_java_lang_Object); + + if (classes == NULL) + return NULL; + + packages = builtin_anewarray(0, class_java_lang_Object); + + if (packages == NULL) + return NULL; + + /* set instance fields */ + + o->classes = classes; + o->packages = packages; + + return (jobject) o; +} + + +/* JVM_GetClassNameUTF */ + +const char* JVM_GetClassNameUTF(JNIEnv *env, jclass cls) +{ + log_println("JVM_GetClassNameUTF: IMPLEMENT ME!"); +} + + +/* JVM_GetClassCPTypes */ + +void JVM_GetClassCPTypes(JNIEnv *env, jclass cls, unsigned char *types) +{ + log_println("JVM_GetClassCPTypes: IMPLEMENT ME!"); +} + + +/* JVM_GetClassCPEntriesCount */ + +jint JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cls) +{ + log_println("JVM_GetClassCPEntriesCount: IMPLEMENT ME!"); +} + + +/* JVM_GetClassFieldsCount */ + +jint JVM_GetClassFieldsCount(JNIEnv *env, jclass cls) +{ + log_println("JVM_GetClassFieldsCount: IMPLEMENT ME!"); +} + + +/* JVM_GetClassMethodsCount */ + +jint JVM_GetClassMethodsCount(JNIEnv *env, jclass cls) +{ + log_println("JVM_GetClassMethodsCount: IMPLEMENT ME!"); +} + + +/* JVM_GetMethodIxExceptionIndexes */ + +void JVM_GetMethodIxExceptionIndexes(JNIEnv *env, jclass cls, jint method_index, unsigned short *exceptions) +{ + log_println("JVM_GetMethodIxExceptionIndexes: IMPLEMENT ME!"); +} + + +/* JVM_GetMethodIxExceptionsCount */ + +jint JVM_GetMethodIxExceptionsCount(JNIEnv *env, jclass cls, jint method_index) +{ + log_println("JVM_GetMethodIxExceptionsCount: IMPLEMENT ME!"); +} + + +/* JVM_GetMethodIxByteCode */ + +void JVM_GetMethodIxByteCode(JNIEnv *env, jclass cls, jint method_index, unsigned char *code) +{ + log_println("JVM_GetMethodIxByteCode: IMPLEMENT ME!"); +} + + +/* JVM_GetMethodIxByteCodeLength */ + +jint JVM_GetMethodIxByteCodeLength(JNIEnv *env, jclass cls, jint method_index) +{ + log_println("JVM_GetMethodIxByteCodeLength: IMPLEMENT ME!"); +} + + +/* JVM_GetMethodIxExceptionTableEntry */ + +void JVM_GetMethodIxExceptionTableEntry(JNIEnv *env, jclass cls, jint method_index, jint entry_index, JVM_ExceptionTableEntryType *entry) +{ + log_println("JVM_GetMethodIxExceptionTableEntry: IMPLEMENT ME!"); +} + + +/* JVM_GetMethodIxExceptionTableLength */ + +jint JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cls, int method_index) +{ + log_println("JVM_GetMethodIxExceptionTableLength: IMPLEMENT ME!"); +} + + +/* JVM_GetMethodIxModifiers */ + +jint JVM_GetMethodIxModifiers(JNIEnv *env, jclass cls, int method_index) +{ + log_println("JVM_GetMethodIxModifiers: IMPLEMENT ME!"); +} + + +/* JVM_GetFieldIxModifiers */ + +jint JVM_GetFieldIxModifiers(JNIEnv *env, jclass cls, int field_index) +{ + log_println("JVM_GetFieldIxModifiers: IMPLEMENT ME!"); +} + + +/* JVM_GetMethodIxLocalsCount */ + +jint JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cls, int method_index) +{ + log_println("JVM_GetMethodIxLocalsCount: IMPLEMENT ME!"); +} + + +/* JVM_GetMethodIxArgsSize */ + +jint JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cls, int method_index) +{ + log_println("JVM_GetMethodIxArgsSize: IMPLEMENT ME!"); +} + + +/* JVM_GetMethodIxMaxStack */ + +jint JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cls, int method_index) +{ + log_println("JVM_GetMethodIxMaxStack: IMPLEMENT ME!"); +} + + +/* JVM_IsConstructorIx */ + +jboolean JVM_IsConstructorIx(JNIEnv *env, jclass cls, int method_index) +{ + log_println("JVM_IsConstructorIx: IMPLEMENT ME!"); +} + + +/* JVM_GetMethodIxNameUTF */ + +const char* JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cls, jint method_index) +{ + log_println("JVM_GetMethodIxNameUTF: IMPLEMENT ME!"); +} + + +/* JVM_GetMethodIxSignatureUTF */ + +const char* JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cls, jint method_index) +{ + log_println("JVM_GetMethodIxSignatureUTF: IMPLEMENT ME!"); +} + + +/* JVM_GetCPFieldNameUTF */ + +const char* JVM_GetCPFieldNameUTF(JNIEnv *env, jclass cls, jint cp_index) +{ + log_println("JVM_GetCPFieldNameUTF: IMPLEMENT ME!"); +} + + +/* JVM_GetCPMethodNameUTF */ + +const char* JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cls, jint cp_index) +{ + log_println("JVM_GetCPMethodNameUTF: IMPLEMENT ME!"); +} + + +/* JVM_GetCPMethodSignatureUTF */ + +const char* JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cls, jint cp_index) +{ + log_println("JVM_GetCPMethodSignatureUTF: IMPLEMENT ME!"); +} + + +/* JVM_GetCPFieldSignatureUTF */ + +const char* JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cls, jint cp_index) +{ + log_println("JVM_GetCPFieldSignatureUTF: IMPLEMENT ME!"); +} + + +/* JVM_GetCPClassNameUTF */ + +const char* JVM_GetCPClassNameUTF(JNIEnv *env, jclass cls, jint cp_index) +{ + log_println("JVM_GetCPClassNameUTF: IMPLEMENT ME!"); +} + + +/* JVM_GetCPFieldClassNameUTF */ + +const char* JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cls, jint cp_index) +{ + log_println("JVM_GetCPFieldClassNameUTF: IMPLEMENT ME!"); +} + + +/* JVM_GetCPMethodClassNameUTF */ + +const char* JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cls, jint cp_index) +{ + log_println("JVM_GetCPMethodClassNameUTF: IMPLEMENT ME!"); +} + + +/* JVM_GetCPFieldModifiers */ + +jint JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls) +{ + log_println("JVM_GetCPFieldModifiers: IMPLEMENT ME!"); +} + + +/* JVM_GetCPMethodModifiers */ + +jint JVM_GetCPMethodModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls) +{ + log_println("JVM_GetCPMethodModifiers: IMPLEMENT ME!"); +} + + +/* JVM_ReleaseUTF */ + +void JVM_ReleaseUTF(const char *utf) +{ + log_println("JVM_ReleaseUTF: IMPLEMENT ME!"); +} + + +/* JVM_IsSameClassPackage */ + +jboolean JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2) +{ + log_println("JVM_IsSameClassPackage: IMPLEMENT ME!"); +} + + +/* JVM_Open */ + +jint JVM_Open(const char *fname, jint flags, jint mode) +{ + int result; + +#if PRINTJVM + log_println("JVM_Open: fname=%s, flags=%d, mode=%d", fname, flags, mode); +#endif + + result = open(fname, flags, mode); + + if (result >= 0) { + return result; + } + else { + switch(errno) { + case EEXIST: + /* XXX don't know what to do here */ +/* return JVM_EEXIST; */ + return -1; + default: + return -1; + } + } +} + + +/* JVM_Close */ + +jint JVM_Close(jint fd) +{ +#if PRINTJVM + log_println("JVM_Close: fd=%d", fd); +#endif + return close(fd); +} + + +/* JVM_Read */ + +jint JVM_Read(jint fd, char *buf, jint nbytes) +{ +#if PRINTJVM + log_println("JVM_Read: fd=%d, buf=%p, nbytes=%d", fd, buf, nbytes); +#endif + return read(fd, buf, nbytes); +} + + +/* JVM_Write */ + +jint JVM_Write(jint fd, char *buf, jint nbytes) +{ +#if PRINTJVM + log_println("JVM_Write: fd=%d, buf=%s, nbytes=%d", fd, buf, nbytes); +#endif + return write(fd, buf, nbytes); +} + + +/* JVM_Available */ + +jint JVM_Available(jint fd, jlong *pbytes) +{ +#if defined(FIONREAD) && 0 + ssize_t n; + + *pbytes = 0; + + if (ioctl(fd, FIONREAD, (char *) &n) != 0) + return errno; + + *pbytes = n; + + return 0; +#elif defined(HAVE_FSTAT) + struct stat statBuffer; + off_t n; + int result; + + *pbytes = 0; + + if ((fstat(fd, &statBuffer) == 0) && S_ISREG (statBuffer.st_mode)) { + n = lseek (fd, 0, SEEK_CUR); + + if (n != -1) { + *pbytes = statBuffer.st_size - n; + result = 0; + } + else { + result = errno; + } + } + else { + result = errno; + } + + return result; +#elif defined(HAVE_SELECT) + fd_set filedescriptset; + struct timeval tv; + int result; + + *pbytes = 0; + + FD_ZERO (&filedescriptset); + FD_SET (fd,&filedescriptset); + memset (&tv, 0, sizeof(tv)); + + switch (select (fd+1, &filedescriptset, NULL, NULL, &tv)) + { + case -1: + result=errno; + break; + case 0: + *pbytes = 0; + result = CPNATIVE_OK; + break; + default: + *pbytes = 1; + result = CPNATIVE_OK; + break; + } + return result; +#else + *pbytes = 0; + return ENOTSUP; +#endif +} + + +/* JVM_Lseek */ + +jlong JVM_Lseek(jint fd, jlong offset, jint whence) +{ +#if PRINTJVM + log_println("JVM_Lseek: fd=%d, offset=%ld, whence=%d", fd, offset, whence); +#endif + return (jlong) lseek(fd, (off_t) offset, whence); +} + + +/* JVM_SetLength */ + +jint JVM_SetLength(jint fd, jlong length) +{ + log_println("JVM_SetLength: IMPLEMENT ME!"); +} + + +/* JVM_Sync */ + +jint JVM_Sync(jint fd) +{ + log_println("JVM_Sync: IMPLEMENT ME!"); +} + + +/* JVM_StartThread */ + +void JVM_StartThread(JNIEnv* env, jobject jthread) +{ +#if PRINTJVM + log_println("JVM_StartThread: jthread=%p", jthread); +#endif + _Jv_java_lang_Thread_start((java_lang_Thread *) jthread, 0); +} + + +/* JVM_StopThread */ + +void JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable) +{ + log_println("JVM_StopThread: IMPLEMENT ME!"); +} + + +/* JVM_IsThreadAlive */ + +jboolean JVM_IsThreadAlive(JNIEnv* env, jobject jthread) +{ +#if PRINTJVM + log_println("JVM_IsThreadAlive: jthread=%p", jthread); +#endif + return _Jv_java_lang_Thread_isAlive((java_lang_Thread *) jthread); +} + + +/* JVM_SuspendThread */ + +void JVM_SuspendThread(JNIEnv* env, jobject jthread) +{ + log_println("JVM_SuspendThread: IMPLEMENT ME!"); +} + + +/* JVM_ResumeThread */ + +void JVM_ResumeThread(JNIEnv* env, jobject jthread) +{ + log_println("JVM_ResumeThread: IMPLEMENT ME!"); +} + + +/* JVM_SetThreadPriority */ + +void JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio) +{ +#if PRINTJVM + log_println("JVM_SetThreadPriority: jthread=%p, prio=%d", jthread, prio); +#endif + _Jv_java_lang_Thread_setPriority((java_lang_Thread *) jthread, prio); +} + + +/* JVM_Yield */ + +void JVM_Yield(JNIEnv *env, jclass threadClass) +{ + log_println("JVM_Yield: IMPLEMENT ME!"); +} + + +/* JVM_Sleep */ + +void JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis) +{ +#if PRINTJVM + log_println("JVM_Sleep: threadClass=%p, millis=%ld", threadClass, millis); +#endif + _Jv_java_lang_Thread_sleep(millis); +} + + +/* JVM_CurrentThread */ + +jobject JVM_CurrentThread(JNIEnv* env, jclass threadClass) +{ +#if PRINTJVM + log_println("JVM_CurrentThread: threadClass=%p", threadClass); +#endif + return (jobject) _Jv_java_lang_Thread_currentThread(); +} + + +/* JVM_CountStackFrames */ + +jint JVM_CountStackFrames(JNIEnv* env, jobject jthread) +{ + log_println("JVM_CountStackFrames: IMPLEMENT ME!"); +} + + +/* JVM_Interrupt */ + +void JVM_Interrupt(JNIEnv* env, jobject jthread) +{ + log_println("JVM_Interrupt: IMPLEMENT ME!"); +} + + +/* JVM_IsInterrupted */ + +jboolean JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrupted) +{ +#if PRINTJVM + log_println("JVM_IsInterrupted: jthread=%p, clear_interrupted=%d", jthread, clear_interrupted); +#endif + /* XXX do something with clear_interrupted */ + return _Jv_java_lang_Thread_isInterrupted((java_lang_Thread *) jthread); +} + + +/* JVM_HoldsLock */ + +jboolean JVM_HoldsLock(JNIEnv* env, jclass threadClass, jobject obj) +{ + log_println("JVM_HoldsLock: IMPLEMENT ME!"); +} + + +/* JVM_DumpAllStacks */ + +void JVM_DumpAllStacks(JNIEnv* env, jclass unused) +{ + log_println("JVM_DumpAllStacks: IMPLEMENT ME!"); +} + + +/* JVM_CurrentLoadedClass */ + +jclass JVM_CurrentLoadedClass(JNIEnv *env) +{ + log_println("JVM_CurrentLoadedClass: IMPLEMENT ME!"); +} + + +/* JVM_CurrentClassLoader */ + +jobject JVM_CurrentClassLoader(JNIEnv *env) +{ + log_println("JVM_CurrentClassLoader: IMPLEMENT ME!"); +} + + +/* JVM_GetClassContext */ + +jobjectArray JVM_GetClassContext(JNIEnv *env) +{ +#if PRINTJVM + log_println("JVM_GetClassContext"); +#endif + return (jobjectArray) stacktrace_getClassContext(); +} + + +/* JVM_ClassDepth */ + +jint JVM_ClassDepth(JNIEnv *env, jstring name) +{ + log_println("JVM_ClassDepth: IMPLEMENT ME!"); +} + + +/* JVM_ClassLoaderDepth */ + +jint JVM_ClassLoaderDepth(JNIEnv *env) +{ + log_println("JVM_ClassLoaderDepth: IMPLEMENT ME!"); +} + + +/* JVM_GetSystemPackage */ + +jstring JVM_GetSystemPackage(JNIEnv *env, jstring name) +{ + log_println("JVM_GetSystemPackage: IMPLEMENT ME!"); +} + + +/* JVM_GetSystemPackages */ + +jobjectArray JVM_GetSystemPackages(JNIEnv *env) +{ + log_println("JVM_GetSystemPackages: IMPLEMENT ME!"); +} + + +/* JVM_AllocateNewObject */ + +jobject JVM_AllocateNewObject(JNIEnv *env, jobject receiver, jclass currClass, jclass initClass) +{ + log_println("JVM_AllocateNewObject: IMPLEMENT ME!"); +} + + +/* JVM_AllocateNewArray */ + +jobject JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currClass, jint length) +{ + log_println("JVM_AllocateNewArray: IMPLEMENT ME!"); +} + + +/* JVM_LatestUserDefinedLoader */ + +jobject JVM_LatestUserDefinedLoader(JNIEnv *env) +{ + log_println("JVM_LatestUserDefinedLoader: IMPLEMENT ME!"); +} + + +/* JVM_LoadClass0 */ + +jclass JVM_LoadClass0(JNIEnv *env, jobject receiver, jclass currClass, jstring currClassName) +{ + log_println("JVM_LoadClass0: IMPLEMENT ME!"); +} + + +/* JVM_GetArrayLength */ + +jint JVM_GetArrayLength(JNIEnv *env, jobject arr) +{ + log_println("JVM_GetArrayLength: IMPLEMENT ME!"); +} + + +/* JVM_GetArrayElement */ + +jobject JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index) +{ + log_println("JVM_GetArrayElement: IMPLEMENT ME!"); +} + + +/* JVM_GetPrimitiveArrayElement */ + +jvalue JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode) +{ + log_println("JVM_GetPrimitiveArrayElement: IMPLEMENT ME!"); +} + + +/* JVM_SetArrayElement */ + +void JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val) +{ + log_println("JVM_SetArrayElement: IMPLEMENT ME!"); +} + + +/* JVM_SetPrimitiveArrayElement */ + +void JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v, unsigned char vCode) +{ + log_println("JVM_SetPrimitiveArrayElement: IMPLEMENT ME!"); +} + + +/* JVM_NewArray */ + +jobject JVM_NewArray(JNIEnv *env, jclass eltClass, jint length) +{ +#if PRINTJVM + log_println("JVM_NewArray: eltClass=%p, length=%d", eltClass, length); +#endif + return (jobject) builtin_anewarray(length, (classinfo *) eltClass); +} + + +/* JVM_NewMultiArray */ + +jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim) +{ + log_println("JVM_NewMultiArray: IMPLEMENT ME!"); +} + + +/* JVM_InitializeSocketLibrary */ + +jint JVM_InitializeSocketLibrary() +{ + log_println("JVM_InitializeSocketLibrary: IMPLEMENT ME!"); +} + + +/* JVM_Socket */ + +jint JVM_Socket(jint domain, jint type, jint protocol) +{ +#if PRINTJVM || 1 + log_println("JVM_Socket: domain=%d, type=%d, protocol=%d", domain, type, protocol); +#endif + return socket(domain, type, protocol); +} + + +/* JVM_SocketClose */ + +jint JVM_SocketClose(jint fd) +{ +#if PRINTJVM || 1 + log_println("JVM_SocketClose: fd=%d", fd); +#endif + return close(fd); +} + + +/* JVM_SocketShutdown */ + +jint JVM_SocketShutdown(jint fd, jint howto) +{ +#if PRINTJVM || 1 + log_println("JVM_SocketShutdown: fd=%d, howto=%d", fd, howto); +#endif + return shutdown(fd, howto); +} + + +/* JVM_Recv */ + +jint JVM_Recv(jint fd, char *buf, jint nBytes, jint flags) +{ + log_println("JVM_Recv: IMPLEMENT ME!"); +} + + +/* JVM_Send */ + +jint JVM_Send(jint fd, char *buf, jint nBytes, jint flags) +{ + log_println("JVM_Send: IMPLEMENT ME!"); +} + + +/* JVM_Timeout */ + +jint JVM_Timeout(int fd, long timeout) +{ + log_println("JVM_Timeout: IMPLEMENT ME!"); +} + + +/* JVM_Listen */ + +jint JVM_Listen(jint fd, jint count) +{ +#if PRINTJVM || 1 + log_println("JVM_Listen: fd=%d, count=%d", fd, count); +#endif + return listen(fd, count); +} + + +/* JVM_Connect */ + +jint JVM_Connect(jint fd, struct sockaddr *him, jint len) +{ +#if PRINTJVM || 1 + log_println("JVM_Connect: fd=%d, him=%p, len=%d", fd, him, len); +#endif + return connect(fd, him, len); +} + + +/* JVM_Bind */ + +jint JVM_Bind(jint fd, struct sockaddr *him, jint len) +{ + log_println("JVM_Bind: IMPLEMENT ME!"); +} + + +/* JVM_Accept */ + +jint JVM_Accept(jint fd, struct sockaddr *him, jint *len) +{ +#if PRINTJVM || 1 + log_println("JVM_Accept: fd=%d, him=%p, len=%p", fd, him, len); +#endif + return accept(fd, him, (socklen_t *) len); +} + + +/* JVM_RecvFrom */ + +jint JVM_RecvFrom(jint fd, char *buf, int nBytes, int flags, struct sockaddr *from, int *fromlen) +{ + log_println("JVM_RecvFrom: IMPLEMENT ME!"); +} + + +/* JVM_GetSockName */ + +jint JVM_GetSockName(jint fd, struct sockaddr *him, int *len) +{ +#if PRINTJVM || 1 + log_println("JVM_GetSockName: fd=%d, him=%p, len=%p", fd, him, len); +#endif + return getsockname(fd, him, (socklen_t *) len); +} + + +/* JVM_SendTo */ + +jint JVM_SendTo(jint fd, char *buf, int len, int flags, struct sockaddr *to, int tolen) +{ + log_println("JVM_SendTo: IMPLEMENT ME!"); +} + + +/* JVM_SocketAvailable */ + +jint JVM_SocketAvailable(jint fd, jint *pbytes) +{ + log_println("JVM_SocketAvailable: IMPLEMENT ME!"); +} + + +/* JVM_GetSockOpt */ + +jint JVM_GetSockOpt(jint fd, int level, int optname, char *optval, int *optlen) +{ + log_println("JVM_GetSockOpt: IMPLEMENT ME!"); +} + + +/* JVM_SetSockOpt */ + +jint JVM_SetSockOpt(jint fd, int level, int optname, const char *optval, int optlen) +{ +#if PRINTJVM || 1 + log_println("JVM_SetSockOpt: fd=%d, level=%d, optname=%d, optval=%s, optlen=%d", fd, level, optname, optval, optlen); +#endif + return setsockopt(fd, level, optname, optval, optlen); +} + + +/* JVM_GetHostName */ + +int JVM_GetHostName(char* name, int namelen) +{ +#if PRINTJVM || 1 + log_println("JVM_GetHostName: name=%s, namelen=%d", name, namelen); +#endif + return gethostname(name, namelen); +} + + +/* JVM_GetHostByAddr */ + +struct hostent* JVM_GetHostByAddr(const char* name, int len, int type) +{ + log_println("JVM_GetHostByAddr: IMPLEMENT ME!"); +} + + +/* JVM_GetHostByName */ + +struct hostent* JVM_GetHostByName(char* name) +{ + log_println("JVM_GetHostByName: IMPLEMENT ME!"); +} + + +/* JVM_GetProtoByName */ + +struct protoent* JVM_GetProtoByName(char* name) +{ + log_println("JVM_GetProtoByName: IMPLEMENT ME!"); +} + + +/* JVM_LoadLibrary */ + +void* JVM_LoadLibrary(const char* name) +{ +#if PRINTJVM + log_println("JVM_LoadLibrary: name=%s", name); +#endif + return native_library_open(utf_new_char(name)); +} + + +/* JVM_UnloadLibrary */ + +void JVM_UnloadLibrary(void* handle) +{ + log_println("JVM_UnloadLibrary: IMPLEMENT ME!"); +} + + +/* JVM_FindLibraryEntry */ + +void* JVM_FindLibraryEntry(void* handle, const char* name) +{ + lt_ptr symbol; + +#if PRINTJVM + log_println("JVM_FindLibraryEntry: handle=%p, name=%s", handle, name); +#endif + + symbol = lt_dlsym(handle, name); + + return symbol; +} + + +/* JVM_IsNaN */ + +jboolean JVM_IsNaN(jdouble a) +{ + log_println("JVM_IsNaN: IMPLEMENT ME!"); +} + + +/* JVM_IsSupportedJNIVersion */ + +jboolean JVM_IsSupportedJNIVersion(jint version) +{ +#if PRINTJVM + log_println("JVM_IsSupportedJNIVersion: version=%d", version); +#endif + switch (version) { + case JNI_VERSION_1_1: + case JNI_VERSION_1_2: + case JNI_VERSION_1_4: + return true; + default: + return false; + } +} + + +/* JVM_InternString */ + +jstring JVM_InternString(JNIEnv *env, jstring str) +{ +#if PRINTJVM + log_println("JVM_InternString: str=%p", str); +#endif + return (jstring) _Jv_java_lang_String_intern((java_lang_String *) str); +} + + +/* JVM_RawMonitorCreate */ + +JNIEXPORT void* JNICALL JVM_RawMonitorCreate(void) +{ + java_objectheader *o; + +#if PRINTJVM + log_println("JVM_RawMonitorCreate"); +#endif + + o = NEW(java_objectheader); + + lock_init_object_lock(o); + + return o; +} + + +/* JVM_RawMonitorDestroy */ + +JNIEXPORT void JNICALL JVM_RawMonitorDestroy(void *mon) +{ +#if PRINTJVM + log_println("JVM_RawMonitorDestroy: mon=%p", mon); +#endif + FREE(mon, java_objectheader); +} + + +/* JVM_RawMonitorEnter */ + +JNIEXPORT jint JNICALL JVM_RawMonitorEnter(void *mon) +{ +#if PRINTJVM + log_println("JVM_RawMonitorEnter: mon=%p", mon); +#endif + (void) lock_monitor_enter((java_objectheader *) mon); + + return 0; +} + + +/* JVM_RawMonitorExit */ + +JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon) +{ +#if PRINTJVM + log_println("JVM_RawMonitorExit: mon=%p", mon); +#endif + (void) lock_monitor_exit((java_objectheader *) mon); +} + + +/* JVM_SetPrimitiveFieldValues */ + +void JVM_SetPrimitiveFieldValues(JNIEnv *env, jclass cb, jobject obj, jlongArray fieldIDs, jcharArray typecodes, jbyteArray data) +{ + log_println("JVM_SetPrimitiveFieldValues: IMPLEMENT ME!"); +} + + +/* JVM_GetPrimitiveFieldValues */ + +void JVM_GetPrimitiveFieldValues(JNIEnv *env, jclass cb, jobject obj, jlongArray fieldIDs, jcharArray typecodes, jbyteArray data) +{ + log_println("JVM_GetPrimitiveFieldValues: IMPLEMENT ME!"); +} + + +/* JVM_AccessVMBooleanFlag */ + +jboolean JVM_AccessVMBooleanFlag(const char* name, jboolean* value, jboolean is_get) +{ + log_println("JVM_AccessVMBooleanFlag: IMPLEMENT ME!"); +} + + +/* JVM_AccessVMIntFlag */ + +jboolean JVM_AccessVMIntFlag(const char* name, jint* value, jboolean is_get) +{ + log_println("JVM_AccessVMIntFlag: IMPLEMENT ME!"); +} + + +/* JVM_VMBreakPoint */ + +void JVM_VMBreakPoint(JNIEnv *env, jobject obj) +{ + log_println("JVM_VMBreakPoint: IMPLEMENT ME!"); +} + + +/* JVM_GetClassFields */ + +jobjectArray JVM_GetClassFields(JNIEnv *env, jclass cls, jint which) +{ + log_println("JVM_GetClassFields: IMPLEMENT ME!"); +} + + +/* JVM_GetClassMethods */ + +jobjectArray JVM_GetClassMethods(JNIEnv *env, jclass cls, jint which) +{ + log_println("JVM_GetClassMethods: IMPLEMENT ME!"); +} + + +/* JVM_GetClassConstructors */ + +jobjectArray JVM_GetClassConstructors(JNIEnv *env, jclass cls, jint which) +{ + log_println("JVM_GetClassConstructors: IMPLEMENT ME!"); +} + + +/* JVM_GetClassField */ + +jobject JVM_GetClassField(JNIEnv *env, jclass cls, jstring name, jint which) +{ + log_println("JVM_GetClassField: IMPLEMENT ME!"); +} + + +/* JVM_GetClassMethod */ + +jobject JVM_GetClassMethod(JNIEnv *env, jclass cls, jstring name, jobjectArray types, jint which) +{ + log_println("JVM_GetClassMethod: IMPLEMENT ME!"); +} + + +/* JVM_GetClassConstructor */ + +jobject JVM_GetClassConstructor(JNIEnv *env, jclass cls, jobjectArray types, jint which) +{ + log_println("JVM_GetClassConstructor: IMPLEMENT ME!"); +} + + +/* JVM_NewInstance */ + +jobject JVM_NewInstance(JNIEnv *env, jclass cls) +{ + log_println("JVM_NewInstance: IMPLEMENT ME!"); +} + + +/* JVM_GetField */ + +jobject JVM_GetField(JNIEnv *env, jobject field, jobject obj) +{ + log_println("JVM_GetField: IMPLEMENT ME!"); +} + + +/* JVM_GetPrimitiveField */ + +jvalue JVM_GetPrimitiveField(JNIEnv *env, jobject field, jobject obj, unsigned char wCode) +{ + log_println("JVM_GetPrimitiveField: IMPLEMENT ME!"); +} + + +/* JVM_SetField */ + +void JVM_SetField(JNIEnv *env, jobject field, jobject obj, jobject val) +{ + log_println("JVM_SetField: IMPLEMENT ME!"); +} + + +/* JVM_SetPrimitiveField */ + +void JVM_SetPrimitiveField(JNIEnv *env, jobject field, jobject obj, jvalue v, unsigned char vCode) +{ + log_println("JVM_SetPrimitiveField: IMPLEMENT ME!"); +} + + +/* JVM_InvokeMethod */ + +jobject JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0) +{ +#if PRINTJVM || 1 + log_println("JVM_InvokeMethod: method=%p, obj=%p, args0=%p", method, obj, args0); +#endif + return (jobject) _Jv_java_lang_reflect_Method_invoke((java_lang_reflect_Method *) method, (java_lang_Object *) obj, (java_objectarray *) args0); +} + + +/* JVM_NewInstanceFromConstructor */ + +jobject JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args0) +{ +#if PRINTJVM + log_println("JVM_NewInstanceFromConstructor: c=%p, args0=%p", c, args0); +#endif + return (jobject) _Jv_java_lang_reflect_Constructor_newInstance(env, (java_lang_reflect_Constructor *) c, (java_objectarray *) args0); +} + + +/* JVM_SupportsCX8 */ + +jboolean JVM_SupportsCX8() +{ +#if PRINTJVM + log_println("JVM_SupportsCX8"); +#endif + return _Jv_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8(NULL, NULL); +} + + +/* JVM_CX8Field */ + +jboolean JVM_CX8Field(JNIEnv *env, jobject obj, jfieldID fid, jlong oldVal, jlong newVal) +{ + log_println("JVM_CX8Field: IMPLEMENT ME!"); +} + + +/* JVM_GetAllThreads */ + +jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy) +{ + log_println("JVM_GetAllThreads: IMPLEMENT ME!"); +} + + +/* JVM_DumpThreads */ + +jobjectArray JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads) +{ + log_println("JVM_DumpThreads: IMPLEMENT ME!"); +} + + +/* JVM_GetManagement */ + +void* JVM_GetManagement(jint version) +{ + log_println("JVM_GetManagement: IMPLEMENT ME!"); +} + + +/* JVM_InitAgentProperties */ + +jobject JVM_InitAgentProperties(JNIEnv *env, jobject properties) +{ + log_println("JVM_InitAgentProperties: IMPLEMENT ME!"); +} + + +/* JVM_GetEnclosingMethodInfo */ + +jobjectArray JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass ofClass) +{ + log_println("JVM_GetEnclosingMethodInfo: IMPLEMENT ME!"); +} + + +/* JVM_GetThreadStateValues */ + +jintArray JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState) +{ + log_println("JVM_GetThreadStateValues: IMPLEMENT ME!"); +} + + +/* JVM_GetThreadStateValues */ + +jobjectArray JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArray values) +{ + log_println("JVM_GetThreadStateValues: IMPLEMENT ME!"); +} + + +/* JVM_GetVersionInfo */ + +void JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size) +{ + log_println("JVM_GetVersionInfo: IMPLEMENT ME!"); +} + + +/* OS: JVM_RegisterSignal */ + +void* JVM_RegisterSignal(jint sig, void* handler) +{ + log_println("JVM_RegisterSignal: sig=%d, handler=%p, IMPLEMENT ME!", sig, handler); + return NULL; +} + + +/* OS: JVM_FindSignal */ + +jint JVM_FindSignal(const char *name) +{ + log_println("JVM_FindSignal: name=%s", name); + return 0; +} + + +/* + * These are local overrides for various environment variables in Emacs. + * Please do not remove this and leave it at the end of the file, where + * Emacs will automagically detect them. + * --------------------------------------------------------------------- + * Local variables: + * mode: c + * indent-tabs-mode: t + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ diff --git a/src/native/vm/sun_misc_Unsafe.c b/src/native/vm/sun_misc_Unsafe.c index 82c54860e..3635b2a8c 100644 --- a/src/native/vm/sun_misc_Unsafe.c +++ b/src/native/vm/sun_misc_Unsafe.c @@ -31,43 +31,63 @@ #include +#include "mm/memory.h" + #include "native/jni.h" #include "native/native.h" -#include "native/include/java_lang_Object.h" +#include "native/include/java_lang_Object.h" /* before c.l.C */ +#include "native/include/java_lang_String.h" /* required by j.l.CL */ + +#if defined(WITH_CLASSPATH_SUN) +# include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */ +#endif + +#include "native/include/java_lang_ClassLoader.h" /* required by j.l.C */ +#include "native/include/java_lang_Class.h" #include "native/include/java_lang_reflect_Field.h" #include "native/include/java_lang_Thread.h" /* required by s.m.U */ +#include "native/include/java_lang_Throwable.h" + +#if defined(WITH_CLASSPATH_SUN) +# include "native/include/java_security_ProtectionDomain.h" /* required by smU*/ +#endif #include "native/include/sun_misc_Unsafe.h" +#include "vm/exceptions.h" +#include "vm/initialize.h" + #include "vmcore/utf8.h" /* native methods implemented by this file ************************************/ static JNINativeMethod methods[] = { - { "objectFieldOffset", "(Ljava/lang/reflect/Field;)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_objectFieldOffset }, - { "compareAndSwapInt", "(Ljava/lang/Object;JII)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapInt }, -#if 0 - { "compareAndSwapLong", "(Ljava/lang/Object;JJJ)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapLong }, - { "compareAndSwapObject", "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapObject }, - { "putOrderedInt", "(Ljava/lang/Object;JI)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putOrderedInt }, - { "putOrderedLong", "(Ljava/lang/Object;JJ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putOrderedLong }, - { "putOrderedObject", "(Ljava/lang/Object;JLjava/lang/Object;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putOrderedObject }, - { "putIntVolatile", "(Ljava/lang/Object;JI)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putIntVolatile }, - { "getIntVolatile", "(Ljava/lang/Object;J)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_getIntVolatile }, - { "putLongVolatile", "(Ljava/lang/Object;JJ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putLongVolatile }, - { "putLong", "(Ljava/lang/Object;JJ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putLong }, - { "getLongVolatile", "(Ljava/lang/Object;J)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_getLongVolatile }, - { "getLong", "(Ljava/lang/Object;J)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_getLong }, - { "putObjectVolatile", "(Ljava/lang/Object;JLjava/lang/Object;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putObjectVolatile }, - { "putObject", "(Ljava/lang/Object;JLjava/lang/Object;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putObject }, - { "getObjectVolatile", "(Ljava/lang/Object;J)Ljava/lang/Object;", (void *) (intptr_t) &Java_sun_misc_Unsafe_getObjectVolatile }, - { "arrayBaseOffset", "(Ljava/lang/Class;)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_arrayBaseOffset }, - { "arrayIndexScale", "(Ljava/lang/Class;)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_arrayIndexScale }, - { "unpark", "(Ljava/lang/Thread;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_unpark }, - { "park", "(ZJ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_park }, -#endif + { "registerNatives", "()V", (void *) (intptr_t) &Java_sun_misc_Unsafe_registerNatives }, + { "getInt", "(Ljava/lang/Object;J)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J }, + { "getBoolean", "(Ljava/lang/Object;J)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_getBoolean }, + { "putBoolean", "(Ljava/lang/Object;JZ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putBoolean }, + { "getByte", "(Ljava/lang/Object;J)B", (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J }, + { "putByte", "(Ljava/lang/Object;JB)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB }, + { "getChar", "(Ljava/lang/Object;J)C", (void *) (intptr_t) &Java_sun_misc_Unsafe_getChar__Ljava_lang_Object_2J }, + { "putChar", "(Ljava/lang/Object;JC)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC }, + { "getByte", "(J)B", (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__J }, + { "getInt", "(J)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_getInt__J }, + { "getLong", "(J)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_getLong__J }, + { "putLong", "(JJ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putLong__JJ }, + { "objectFieldOffset", "(Ljava/lang/reflect/Field;)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_objectFieldOffset }, + { "allocateMemory", "(J)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_allocateMemory }, + { "freeMemory", "(J)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_freeMemory }, + { "staticFieldOffset", "(Ljava/lang/reflect/Field;)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldOffset }, + { "staticFieldBase", "(Ljava/lang/reflect/Field;)Ljava/lang/Object;", (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldBase }, + { "ensureClassInitialized", "(Ljava/lang/Class;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_ensureClassInitialized }, + { "throwException", "(Ljava/lang/Throwable;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_throwException }, + { "compareAndSwapObject", "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapObject }, + { "compareAndSwapInt", "(Ljava/lang/Object;JII)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapInt }, + { "compareAndSwapLong", "(Ljava/lang/Object;JJJ)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapLong }, + { "getObjectVolatile", "(Ljava/lang/Object;J)Ljava/lang/Object;", (void *) (intptr_t) &Java_sun_misc_Unsafe_getObjectVolatile }, + { "getIntVolatile", "(Ljava/lang/Object;J)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_getIntVolatile }, }; @@ -89,227 +109,436 @@ void _Jv_sun_misc_Unsafe_init(void) /* * Class: sun/misc/Unsafe - * Method: objectFieldOffset - * Signature: (Ljava/lang/reflect/Field;)J + * Method: registerNatives + * Signature: ()V */ -JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_objectFieldOffset(JNIEnv *env, sun_misc_Unsafe* this, java_lang_reflect_Field* field) +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JNIEnv *env, jclass clazz) { - classinfo *c; - fieldinfo *f; + /* The native methods of this function are already registered in + _Jv_sun_misc_Unsafe_init() which is called during VM + startup. */ +} - c = (classinfo *) field->declaringClass; - f = &c->fields[field->slot]; - return (int64_t) f->offset; +/* + * Class: sun/misc/Unsafe + * Method: getInt + * Signature: (Ljava/lang/Object;J)I + */ +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset) +{ + int32_t *p; + int32_t value; + + p = (int32_t *) (((uint8_t *) o) + offset); + + value = *p; + + return value; } /* * Class: sun/misc/Unsafe - * Method: compareAndSwapInt - * Signature: (Ljava/lang/Object;JII)Z + * Method: getBoolean + * Signature: (Ljava/lang/Object;J)Z */ -JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapInt(JNIEnv *env, sun_misc_Unsafe* this, java_lang_Object* obj, int64_t offset, int32_t expect, int32_t update) +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset) { int32_t *p; int32_t value; - p = (int32_t *) (((u1 *) obj) + offset); + p = (int32_t *) (((uint8_t *) o) + offset); - /* XXX this should be atomic */ + value = *p; + + return value; +} + + +/* + * Class: sun/misc/Unsafe + * Method: putBoolean + * Signature: (Ljava/lang/Object;JZ)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x) +{ + int32_t *p; + + p = (int32_t *) (((uint8_t *) o) + offset); + + *p = x; +} + + +/* + * Class: sun/misc/Unsafe + * Method: getByte + * Signature: (Ljava/lang/Object;J)B + */ +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset) +{ + int32_t *p; + int32_t value; + + p = (int32_t *) (((uint8_t *) o) + offset); value = *p; - if (value == expect) { - *p = update; + return value; +} - return true; - } - return false; +/* + * Class: sun/misc/Unsafe + * Method: putByte + * Signature: (Ljava/lang/Object;JB)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x) +{ + int32_t *p; + + p = (int32_t *) (((uint8_t *) o) + offset); + + *p = x; } -#if 0 /* * Class: sun/misc/Unsafe - * Method: compareAndSwapLong - * Signature: (Ljava/lang/Object;JJJ)Z + * Method: getChar + * Signature: (Ljava/lang/Object;J)C */ -JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapLong(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, int64_t par3, int64_t par4) +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getChar__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset) { + int32_t *p; + int32_t value; + + p = (int32_t *) (((uint8_t *) o) + offset); + + value = *p; + + return value; } /* * Class: sun/misc/Unsafe - * Method: compareAndSwapObject - * Signature: (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z + * Method: putChar + * Signature: (Ljava/lang/Object;JC)V */ -JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, struct java_lang_Object* par3, struct java_lang_Object* par4) +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x) { + int32_t *p; + + p = (int32_t *) (((uint8_t *) o) + offset); + + *p = x; } /* * Class: sun/misc/Unsafe - * Method: putOrderedInt - * Signature: (Ljava/lang/Object;JI)V + * Method: getByte + * Signature: (J)B */ -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedInt(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, int32_t par3) +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getByte__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address) { + int8_t *p; + int8_t value; + + p = (int8_t *) (intptr_t) address; + + value = *p; + + return (int32_t) value; } /* * Class: sun/misc/Unsafe - * Method: putOrderedLong - * Signature: (Ljava/lang/Object;JJ)V + * Method: getInt + * Signature: (J)I */ -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedLong(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, int64_t par3) +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address) { + int32_t *p; + int32_t value; + + p = (int32_t *) (intptr_t) address; + + value = *p; + + return value; } /* * Class: sun/misc/Unsafe - * Method: putOrderedObject - * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V + * Method: getLong + * Signature: (J)J */ -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedObject(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, struct java_lang_Object* par3) +JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLong__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address) { + int64_t *p; + int64_t value; + + p = (int64_t *) (intptr_t) address; + + value = *p; + + return value; } /* * Class: sun/misc/Unsafe - * Method: putIntVolatile - * Signature: (Ljava/lang/Object;JI)V + * Method: putLong + * Signature: (JJ)V */ -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putIntVolatile(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, int32_t par3) +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__JJ(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int64_t value) { + int64_t *p; + + p = (int64_t *) (intptr_t) address; + + *p = value; } /* * Class: sun/misc/Unsafe - * Method: getIntVolatile - * Signature: (Ljava/lang/Object;J)I + * Method: objectFieldOffset + * Signature: (Ljava/lang/reflect/Field;)J */ -JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getIntVolatile(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2) +JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_objectFieldOffset(JNIEnv *env, sun_misc_Unsafe* this, java_lang_reflect_Field* field) { + classinfo *c; + fieldinfo *f; + + c = (classinfo *) field->clazz; + f = &c->fields[field->slot]; + + return (int64_t) f->offset; } /* * Class: sun/misc/Unsafe - * Method: putLongVolatile - * Signature: (Ljava/lang/Object;JJ)V + * Method: allocateMemory + * Signature: (J)J */ -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLongVolatile(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, int64_t par3) +JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_allocateMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t bytes) { + size_t length; + void *p; + + length = (size_t) bytes; + + if ((length != (uint64_t) bytes) || (bytes < 0)) { + exceptions_throw_illegalargumentexception(); + return 0; + } + + p = MNEW(uint8_t, length); + + return (int64_t) (intptr_t) p; } /* * Class: sun/misc/Unsafe - * Method: putLong - * Signature: (Ljava/lang/Object;JJ)V + * Method: freeMemory + * Signature: (J)V */ -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, int64_t par3) +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t address) { + void *p; + + p = (void *) (intptr_t) address; + + if (p == NULL) + return; + + /* we pass length 1 to trick the free function */ + + MFREE(p, uint8_t, 1); } /* * Class: sun/misc/Unsafe - * Method: getLongVolatile - * Signature: (Ljava/lang/Object;J)J + * Method: staticFieldOffset + * Signature: (Ljava/lang/reflect/Field;)J */ -JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLongVolatile(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2) +JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_staticFieldOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *field) { + classinfo *c; + fieldinfo *f; + + c = (classinfo *) field->clazz; + f = &(c->fields[field->slot]); + + return (int64_t) (intptr_t) &(f->value); } /* * Class: sun/misc/Unsafe - * Method: getLong - * Signature: (Ljava/lang/Object;J)J + * Method: staticFieldBase + * Signature: (Ljava/lang/reflect/Field;)Ljava/lang/Object; */ -JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLong(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2) +JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_staticFieldBase(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *f) { + /* In CACAO we return the absolute address in staticFieldOffset. */ + + return NULL; } /* * Class: sun/misc/Unsafe - * Method: putObjectVolatile - * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V + * Method: ensureClassInitialized + * Signature: (Ljava/lang/Class;)V */ -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObjectVolatile(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, struct java_lang_Object* par3) +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *class) { + classinfo *c; + + c = (classinfo *) class; + + if (!(c->state & CLASS_INITIALIZED)) + initialize_class(c); } /* * Class: sun/misc/Unsafe - * Method: putObject - * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V + * Method: throwException + * Signature: (Ljava/lang/Throwable;)V */ -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObject(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, struct java_lang_Object* par3) +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Throwable *ee) { + java_objectheader *o; + + o = (java_objectheader *) ee; + + exceptions_set_exception(o); } /* * Class: sun/misc/Unsafe - * Method: getObjectVolatile - * Signature: (Ljava/lang/Object;J)Ljava/lang/Object; + * Method: compareAndSwapObject + * Signature: (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z */ -JNIEXPORT struct java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2) +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *expected, java_lang_Object *x) { + void **p; + void *value; + + p = (void **) (((uint8_t *) o) + offset); + + /* XXX this should be atomic */ + + value = *p; + + if (value == expected) { + *p = x; + + return true; + } + + return false; } /* * Class: sun/misc/Unsafe - * Method: arrayBaseOffset - * Signature: (Ljava/lang/Class;)I + * Method: compareAndSwapInt + * Signature: (Ljava/lang/Object;JII)Z */ -JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Class* par1) +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapInt(JNIEnv *env, sun_misc_Unsafe* this, java_lang_Object* obj, int64_t offset, int32_t expect, int32_t update) { + int32_t *p; + int32_t value; + + p = (int32_t *) (((uint8_t *) obj) + offset); + + /* XXX this should be atomic */ + + value = *p; + + if (value == expect) { + *p = update; + + return true; + } + + return false; } /* * Class: sun/misc/Unsafe - * Method: arrayIndexScale - * Signature: (Ljava/lang/Class;)I + * Method: compareAndSwapLong + * Signature: (Ljava/lang/Object;JJJ)Z */ -JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayIndexScale(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Class* par1) +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapLong(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int64_t expected, int64_t x) { + int64_t *p; + int64_t value; + + p = (int64_t *) (((uint8_t *) o) + offset); + + /* XXX this should be atomic */ + + value = *p; + + if (value == expected) { + *p = x; + + return true; + } + + return false; } /* * Class: sun/misc/Unsafe - * Method: unpark - * Signature: (Ljava/lang/Thread;)V + * Method: getObjectVolatile + * Signature: (Ljava/lang/Object;J)Ljava/lang/Object; */ -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Thread* par1) +JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset) { + volatile void **p; + volatile void *value; + + p = (volatile void **) (((uint8_t *) o) + offset); + + value = *p; + + return (java_lang_Object *) value; } /* * Class: sun/misc/Unsafe - * Method: park - * Signature: (ZJ)V + * Method: getIntVolatile + * Signature: (Ljava/lang/Object;J)I */ -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_park(JNIEnv *env, struct sun_misc_Unsafe* this, int32_t par1, int64_t par2) +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getIntVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset) { + volatile int32_t *p; + volatile int32_t value; + + p = (volatile int32_t *) (((uint8_t *) o) + offset); + + value = *p; + + return value; } -#endif /* diff --git a/src/threads/native/threads.c b/src/threads/native/threads.c index 13f387db1..27dbc63c2 100644 --- a/src/threads/native/threads.c +++ b/src/threads/native/threads.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: threads.c 8091 2007-06-14 16:10:33Z twisti $ + $Id: threads.c 8132 2007-06-22 11:15:47Z twisti $ */ @@ -875,7 +875,16 @@ bool threads_init(void) (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY, false); + +#elif defined(WITH_CLASSPATH_SUN) + + /* We trick java.lang.Thread.init, which sets the priority of the + current thread to the parent's one. */ + + t->priority = NORM_PRIORITY; + #elif defined(WITH_CLASSPATH_CLDC1_1) + /* set the thread */ t->vm_thread = (java_lang_Object *) mainthread; @@ -885,6 +894,8 @@ bool threads_init(void) o = (java_objectheader *) t; (void) vm_call_method(method_thread_init, o, threadname); +#else +# error unknown classpath configuration #endif if (exceptions_get_exception()) @@ -893,6 +904,7 @@ bool threads_init(void) #if defined(ENABLE_JAVASE) t->group = threadgroup; +# if defined(WITH_CLASSPATH_GNU) /* add main thread to java.lang.ThreadGroup */ m = class_resolveclassmethod(class_java_lang_ThreadGroup, @@ -907,6 +919,9 @@ bool threads_init(void) if (exceptions_get_exception()) return false; +# else +# warning Do not know what to do here +# endif #endif threads_set_thread_priority(pthread_self(), NORM_PRIORITY); @@ -1045,9 +1060,11 @@ static void *threads_startup_thread(void *arg) java.lang.VMThread. Since this is a final class, we can use the class object directly. */ - c = class_java_lang_VMThread; -#elif defined(WITH_CLASSPATH_CLDC1_1) - c = thread->object->header.vftbl->class; + c = class_java_lang_VMThread; +#elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1) + c = thread->object->header.vftbl->class; +#else +# error unknown classpath configuration #endif m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true); @@ -1071,8 +1088,10 @@ static void *threads_startup_thread(void *arg) vmt = (java_lang_VMThread *) thread->object->vmThread; o = (java_objectheader *) vmt; -#elif defined(WITH_CLASSPATH_CLDC1_1) +#elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1) o = (java_objectheader *) thread->object; +#else +# error unknown classpath configuration #endif /* run the thread */ @@ -1298,6 +1317,7 @@ bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon) #endif #if defined(WITH_CLASSPATH_GNU) + /* create a java.lang.VMThread object */ vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread); @@ -1310,8 +1330,17 @@ bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon) vmt->thread = t; vmt->vmdata = (java_lang_Object *) thread; + +#elif defined(WITH_CLASSPATH_SUN) + + vm_abort("threads_attach_current_thread: IMPLEMENT ME!"); + #elif defined(WITH_CLASSPATH_CLDC1_1) + t->vm_thread = (java_lang_Object *) thread; + +#else +# error unknown classpath configuration #endif if (vm_aargs != NULL) { @@ -1398,11 +1427,21 @@ bool threads_detach_thread(threadobject *thread) /* XXX TWISTI: should all threads be in a ThreadGroup? */ if (group != NULL) { +# if defined(WITH_CLASSPATH_GNU) m = class_resolveclassmethod(group->header.vftbl->class, utf_removeThread, utf_java_lang_Thread__V, class_java_lang_ThreadGroup, true); +# elif defined(WITH_CLASSPATH_SUN) + m = class_resolveclassmethod(group->header.vftbl->class, + utf_remove, + utf_java_lang_Thread__V, + class_java_lang_ThreadGroup, + true); +# else +# error unknown classpath configuration +# endif if (m == NULL) return false; diff --git a/src/threads/threads-common.c b/src/threads/threads-common.c index 0437e39f6..1282fafbc 100644 --- a/src/threads/threads-common.c +++ b/src/threads/threads-common.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: threads-common.c 8114 2007-06-20 18:57:41Z twisti $ + $Id: threads-common.c 8132 2007-06-22 11:15:47Z twisti $ */ @@ -517,12 +517,14 @@ void threads_thread_print_info(threadobject *t) if (object != NULL) { /* get thread name */ -#if defined(ENABLE_JAVASE) +#if defined(WITH_CLASSPATH_GNU) name = javastring_toutf((java_objectheader *) object->name, false); -#elif defined(ENABLE_JAVAME_CLDC1_1) +#elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1) /* FIXME: In cldc the name is a char[] */ /* name = object->name; */ name = utf_null; +#else +# error unknown classpath configuration #endif printf("\""); diff --git a/src/vm/properties.c b/src/vm/properties.c index 32b064f66..19dc3f71c 100644 --- a/src/vm/properties.c +++ b/src/vm/properties.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: properties.c 7783 2007-04-20 13:28:27Z twisti $ + $Id: properties.c 8132 2007-06-22 11:15:47Z twisti $ */ @@ -82,17 +82,20 @@ static list_t *list_properties = NULL; bool properties_init(void) { #if defined(ENABLE_JAVASE) - char *cwd; char *env_java_home; + char *java_home; + s4 len; + +# if defined(WITH_CLASSPATH_GNU) + char *cwd; char *env_user; char *env_home; char *env_lang; - char *java_home; char *extdirs; char *lang; char *country; struct utsname *utsnamebuf; - s4 len; +# endif #endif /* create the properties list */ @@ -100,17 +103,10 @@ bool properties_init(void) list_properties = list_create(OFFSET(list_properties_entry, linkage)); #if defined(ENABLE_JAVASE) + /* get properties from system */ - cwd = _Jv_getcwd(); env_java_home = getenv("JAVA_HOME"); - env_user = getenv("USER"); - env_home = getenv("HOME"); - env_lang = getenv("LANG"); - - utsnamebuf = NEW(struct utsname); - - uname(utsnamebuf); /* set JAVA_HOME to default prefix if not defined */ @@ -119,10 +115,6 @@ bool properties_init(void) /* fill in system properties */ - properties_add("java.version", JAVA_VERSION); - properties_add("java.vendor", "GNU Classpath"); - properties_add("java.vendor.url", "http://www.gnu.org/software/classpath/"); - /* add /jre to java.home property */ len = strlen(env_java_home) + strlen("/jre") + strlen("0"); @@ -140,14 +132,34 @@ bool properties_init(void) properties_add("java.vm.version", VERSION); properties_add("java.vm.vendor", "CACAO Team"); properties_add("java.vm.name", "CACAO"); + +# if defined(WITH_CLASSPATH_GNU) + + /* get properties from system */ + + cwd = _Jv_getcwd(); + + env_user = getenv("USER"); + env_home = getenv("HOME"); + env_lang = getenv("LANG"); + + utsnamebuf = NEW(struct utsname); + + uname(utsnamebuf); + + properties_add("java.runtime.version", VERSION); + properties_add("java.runtime.name", "CACAO"); + properties_add("java.specification.version", "1.5"); properties_add("java.specification.vendor", "Sun Microsystems Inc."); properties_add("java.specification.name", "Java Platform API Specification"); - properties_add("java.class.version", CLASS_VERSION); - properties_add("java.class.path", _Jv_classpath); - properties_add("java.runtime.version", VERSION); - properties_add("java.runtime.name", "CACAO"); + properties_add("java.version", JAVA_VERSION); + properties_add("java.vendor", "GNU Classpath"); + properties_add("java.vendor.url", "http://www.gnu.org/software/classpath/"); + + properties_add("java.class.path", _Jv_classpath); + properties_add("java.class.version", CLASS_VERSION); /* Set bootclasspath properties. One for GNU classpath and the other for compatibility with Sun (required by most @@ -156,20 +168,20 @@ bool properties_init(void) properties_add("java.boot.class.path", _Jv_bootclasspath); properties_add("sun.boot.class.path", _Jv_bootclasspath); -#if defined(WITH_STATIC_CLASSPATH) +# if defined(WITH_STATIC_CLASSPATH) properties_add("gnu.classpath.boot.library.path", "."); properties_add("java.library.path" , "."); -#else +# else /* fill gnu.classpath.boot.library.path with GNU Classpath library path */ properties_add("gnu.classpath.boot.library.path", classpath_libdir); properties_add("java.library.path", _Jv_java_library_path); -#endif +# endif properties_add("java.io.tmpdir", "/tmp"); -#if defined(ENABLE_INTRP) +# if defined(ENABLE_INTRP) if (opt_intrp) { /* XXX We don't support java.lang.Compiler */ /* properties_add("java.compiler", "cacao.intrp"); */ @@ -177,7 +189,7 @@ bool properties_init(void) properties_add("gnu.java.compiler.name", "cacao.intrp"); } else -#endif +# endif { /* XXX We don't support java.lang.Compiler */ /* properties_add("java.compiler", "cacao.jit"); */ @@ -198,7 +210,7 @@ bool properties_init(void) properties_add("java.endorsed.dirs", ""CACAO_PREFIX"/jre/lib/endorsed"); -#if defined(DISABLE_GC) +# if defined(DISABLE_GC) /* When we disable the GC, we mmap the whole heap to a specific address, so we can compare call traces. For this reason we have to add the same properties on different machines, otherwise @@ -208,46 +220,47 @@ bool properties_init(void) properties_add("os.arch", "unknown"); properties_add("os.name", "unknown"); properties_add("os.version", "unknown"); -#else +# else /* We need to set the os.arch hardcoded to be compatible with SUN. */ -# if defined(__I386__) +# if defined(__I386__) /* map all x86 architectures (i386, i486, i686) to i386 */ properties_add("os.arch", "i386"); -# elif defined(__POWERPC__) +# elif defined(__POWERPC__) properties_add("os.arch", "ppc"); -# elif defined(__X86_64__) +# elif defined(__X86_64__) properties_add("os.arch", "amd64"); -# else +# else /* default to what uname returns */ properties_add("os.arch", utsnamebuf->machine); -# endif +# endif properties_add("os.name", utsnamebuf->sysname); properties_add("os.version", utsnamebuf->release); -#endif - - properties_add("file.separator", "/"); - properties_add("path.separator", ":"); - properties_add("line.separator", "\n"); - properties_add("user.name", env_user ? env_user : "null"); - properties_add("user.home", env_home ? env_home : "null"); - properties_add("user.dir", cwd ? cwd : "null"); +# endif -#if defined(WITH_STATIC_CLASSPATH) +# if defined(WITH_STATIC_CLASSPATH) /* This is just for debugging purposes and can cause troubles in GNU Classpath. */ properties_add("gnu.cpu.endian", "unknown"); -#else -# if WORDS_BIGENDIAN == 1 +# else +# if WORDS_BIGENDIAN == 1 properties_add("gnu.cpu.endian", "big"); -# else +# else properties_add("gnu.cpu.endian", "little"); -# endif -#endif +# endif +# endif + + properties_add("file.separator", "/"); + properties_add("path.separator", ":"); + properties_add("line.separator", "\n"); + + properties_add("user.name", env_user ? env_user : "null"); + properties_add("user.home", env_home ? env_home : "null"); + properties_add("user.dir", cwd ? cwd : "null"); /* get locale */ @@ -278,13 +291,28 @@ bool properties_init(void) properties_add("user.language", "en"); properties_add("user.country", "US"); } + +# elif defined(WITH_CLASSPATH_SUN) + + properties_add("sun.boot.library.path", classpath_libdir); + +# else + +# error unknown classpath configuration + +# endif + #elif defined(ENABLE_JAVAME_CLDC1_1) + properties_add("microedition.configuration", "CLDC-1.1"); properties_add("microedition.platform", "generic"); properties_add("microedition.encoding", "ISO8859_1"); properties_add("microedition.profiles", ""); + #else -#error unknown Java configuration + +# error unknown Java configuration + #endif /* everything's ok */ diff --git a/src/vm/vm.c b/src/vm/vm.c index 7859fd153..66f36bd10 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: vm.c 8128 2007-06-21 16:29:53Z tbfg $ + $Id: vm.c 8132 2007-06-22 11:15:47Z twisti $ */ @@ -51,7 +51,15 @@ #include "native/jni.h" #include "native/native.h" -#include "native/include/java_lang_String.h" /* required by java_lang_Class.h */ + +#include "native/include/java_lang_Object.h" /* required by j.l.C */ +#include "native/include/java_lang_String.h" /* required by j.l.C */ + +#if defined(WITH_CLASSPATH_SUN) +# include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */ +# include "native/include/java_lang_ClassLoader.h" /* required by j.l.C */ +#endif + #include "native/include/java_lang_Class.h" #include "native/include/java_lang_Byte.h" @@ -63,6 +71,8 @@ #include "native/include/java_lang_Float.h" #include "native/include/java_lang_Double.h" +#include "native/vm/nativevm.h" + #include "threads/threads-common.h" #include "toolbox/logging.h" @@ -866,7 +876,12 @@ bool vm_create(JavaVMInitArgs *vm_args) #else cacao_prefix = CACAO_PREFIX; cacao_libjvm = CACAO_LIBDIR"/libjvm"; + +# if defined(WITH_CLASSPATH_GNU) classpath_libdir = CLASSPATH_LIBDIR"/classpath"; +# else + classpath_libdir = CLASSPATH_LIBDIR; +# endif #endif /* set the bootclasspath */ @@ -1633,16 +1648,23 @@ bool vm_create(JavaVMInitArgs *vm_args) if (!primitive_init()) vm_abort("vm_create: primitive_init failed"); + if (!exceptions_init()) + vm_abort("vm_create: exceptions_init failed"); + + if (!builtin_init()) + vm_abort("vm_create: builtin_init failed"); + /* Initialize the native subsystem. */ + /* BEFORE: threads_init */ if (!native_init()) vm_abort("vm_create: native_init failed"); - if (!exceptions_init()) - vm_abort("vm_create: exceptions_init failed"); + /* Register the native methods implemented in the VM. */ + /* BEFORE: threads_init */ - if (!builtin_init()) - vm_abort("vm_create: builtin_init failed"); + if (!nativevm_preinit()) + vm_abort("vm_create: nativevm_preinit failed"); #if defined(ENABLE_JNI) /* Initialize the JNI subsystem (must be done _before_ @@ -1658,6 +1680,12 @@ bool vm_create(JavaVMInitArgs *vm_args) vm_abort("vm_create: threads_init failed"); #endif + /* Initialize the native VM subsystem. */ + /* AFTER: threads_init (at least for SUN's classes) */ + + if (!nativevm_init()) + vm_abort("vm_create: nativevm_init failed"); + #if defined(ENABLE_PROFILING) /* initialize profiling */ @@ -2625,7 +2653,7 @@ uint64_t *vm_array_from_valist(methodinfo *m, java_objectheader *o, va_list ap) #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o, - vm_arg *vmargs, jvalue *args) + vm_arg *vmargs, const jvalue *args) { typedesc *paramtypes; s4 i; @@ -2683,7 +2711,7 @@ static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o, } #else static uint64_t *vm_array_from_jvalue(methodinfo *m, java_objectheader *o, - jvalue *args) + const jvalue *args) { methoddesc *md; paramdesc *pd; @@ -3221,7 +3249,7 @@ java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o, *******************************************************************************/ java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o, - jvalue *args) + const jvalue *args) { #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__) s4 vmargscount; @@ -3496,7 +3524,8 @@ int32_t vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list a *******************************************************************************/ #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) -s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args) +s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, + const jvalue *args) { s4 vmargscount; vm_arg *vmargs; @@ -3530,7 +3559,8 @@ s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args) return i; } #else -int32_t vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args) +int32_t vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, + const jvalue *args) { int32_t dumpsize; uint64_t *array; @@ -3713,7 +3743,8 @@ int64_t vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list *******************************************************************************/ #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__) -s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args) +s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, + const jvalue *args) { s4 vmargscount; vm_arg *vmargs; @@ -3747,7 +3778,8 @@ s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args) return l; } #else -int64_t vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args) +int64_t vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, + const jvalue *args) { int32_t dumpsize; uint64_t *array; @@ -3932,7 +3964,7 @@ float vm_call_method_float_valist(methodinfo *m, java_objectheader *o, va_list a #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__) float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o, - jvalue *args) + const jvalue *args) { s4 vmargscount; vm_arg *vmargs; @@ -3966,7 +3998,7 @@ float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o, return f; } #else -float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o, jvalue *args) +float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o, const jvalue *args) { int32_t dumpsize; uint64_t *array; @@ -4154,7 +4186,7 @@ double vm_call_method_double_valist(methodinfo *m, java_objectheader *o, va_list #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__) double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o, - jvalue *args) + const jvalue *args) { s4 vmargscount; vm_arg *vmargs; @@ -4188,7 +4220,7 @@ double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o, return d; } #else -double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o, jvalue *args) +double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o, const jvalue *args) { int32_t dumpsize; uint64_t *array; diff --git a/src/vm/vm.h b/src/vm/vm.h index 8a0558039..93d0d89f8 100644 --- a/src/vm/vm.h +++ b/src/vm/vm.h @@ -116,7 +116,7 @@ java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...); java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o, va_list ap); java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o, - jvalue *args); + const jvalue *args); #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__) java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount, @@ -135,23 +135,25 @@ double vm_call_double_array(methodinfo *m, uint64_t *array); s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...); s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap); -s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args); +s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, + const jvalue *args); s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...); s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap); -s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args); +s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, + const jvalue *args); float vm_call_method_float(methodinfo *m, java_objectheader *o, ...); float vm_call_method_float_valist(methodinfo *m, java_objectheader *o, va_list ap); float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o, - jvalue *args); + const jvalue *args); double vm_call_method_double(methodinfo *m, java_objectheader *o, ...); double vm_call_method_double_valist(methodinfo *m, java_objectheader *o, va_list ap); double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o, - jvalue *args); + const jvalue *args); #endif /* _VM_H */ diff --git a/src/vmcore/class.h b/src/vmcore/class.h index 051853363..5dec548cd 100644 --- a/src/vmcore/class.h +++ b/src/vmcore/class.h @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: class.h 8060 2007-06-10 20:00:40Z twisti $ + $Id: class.h 8132 2007-06-22 11:15:47Z twisti $ */ @@ -39,6 +39,9 @@ typedef struct castinfo castinfo; #include "config.h" + +#include + #include "vm/types.h" #include "toolbox/list.h" @@ -82,7 +85,15 @@ typedef struct castinfo castinfo; typedef struct { java_objectheader header; - ptrint padding[4]; +#if defined(WITH_CLASSPATH_GNU) + intptr_t padding[4]; +#elif defined(WITH_CLASSPATH_SUN) + intptr_t padding[19]; +#elif defined(WITH_CLASSPATH_CLDC1_1) + intptr_t padding[3]; +#else +# error unknown classpath configuration +#endif } dummy_java_lang_Class; struct classinfo { /* class structure */ diff --git a/src/vmcore/field.c b/src/vmcore/field.c index 01b5f72b8..4f8dcff7a 100644 --- a/src/vmcore/field.c +++ b/src/vmcore/field.c @@ -22,22 +22,57 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: field.c 7246 2007-01-29 18:49:05Z twisti $ + $Id: field.c 8132 2007-06-22 11:15:47Z twisti $ */ #include "config.h" +#include #include #include "vm/types.h" +#include "vmcore/class.h" #include "vmcore/field.h" +#include "vmcore/primitive.h" #include "vmcore/references.h" #include "vmcore/utf8.h" +/* field_get_type ************************************************************** + + Returns the type of the field as class. + +*******************************************************************************/ + +classinfo *field_get_type(fieldinfo *f) +{ + typedesc *td; + utf *u; + classinfo *c; + + td = f->parseddesc; + + if (td->type == TYPE_ADR) { + assert(td->classref); + + u = td->classref->name; + + /* load the class of the field-type with the field's + classloader */ + + c = load_class_from_classloader(u, f->class->classloader); + } + else { + c = primitive_class_get_by_type(td->decltype); + } + + return c; +} + + /* field_free ****************************************************************** Frees a fields' resources. diff --git a/src/vmcore/field.h b/src/vmcore/field.h index dcbd1eec8..00616399d 100644 --- a/src/vmcore/field.h +++ b/src/vmcore/field.h @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: field.h 7246 2007-01-29 18:49:05Z twisti $ + $Id: field.h 8132 2007-06-22 11:15:47Z twisti $ */ @@ -72,7 +72,8 @@ struct fieldinfo { /* field of a class */ /* function prototypes ********************************************************/ -void field_free(fieldinfo *f); +classinfo *field_get_type(fieldinfo *f); +void field_free(fieldinfo *f); #if !defined(NDEBUG) void field_printflags(fieldinfo *f); diff --git a/src/vmcore/utf8.c b/src/vmcore/utf8.c index 4575dc2dc..d9893ef00 100644 --- a/src/vmcore/utf8.c +++ b/src/vmcore/utf8.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: utf8.c 8123 2007-06-20 23:50:55Z michi $ + $Id: utf8.c 8132 2007-06-22 11:15:47Z twisti $ */ @@ -171,6 +171,7 @@ utf *utf_get; utf *utf_value; utf *utf_fillInStackTrace; +utf *utf_findNative; utf *utf_getSystemClassLoader; utf *utf_initCause; utf *utf_loadClass; @@ -200,6 +201,7 @@ utf *utf_double__void; /* (D)V */ utf *utf_void__java_lang_ClassLoader; /* ()Ljava/lang/ClassLoader; */ utf *utf_void__java_lang_Object; /* ()Ljava/lang/Object; */ utf *utf_void__java_lang_Throwable; /* ()Ljava/lang/Throwable; */ +utf *utf_java_lang_ClassLoader_java_lang_String__J; utf *utf_java_lang_Exception__V; /* (Ljava/lang/Exception;)V */ utf *utf_java_lang_Object__java_lang_Object; utf *utf_java_lang_String__void; /* (Ljava/lang/String;)V */ @@ -410,6 +412,7 @@ bool utf8_init(void) utf_value = utf_new_char("value"); utf_fillInStackTrace = utf_new_char("fillInStackTrace"); + utf_findNative = utf_new_char("findNative"); utf_getSystemClassLoader = utf_new_char("getSystemClassLoader"); utf_initCause = utf_new_char("initCause"); utf_loadClass = utf_new_char("loadClass"); @@ -441,6 +444,9 @@ bool utf8_init(void) utf_void__java_lang_ClassLoader = utf_new_char("()Ljava/lang/ClassLoader;"); + utf_java_lang_ClassLoader_java_lang_String__J = + utf_new_char("(Ljava/lang/ClassLoader;Ljava/lang/String;)J"); + utf_java_lang_Exception__V = utf_new_char("(Ljava/lang/Exception;)V"); utf_java_lang_Object__java_lang_Object = diff --git a/src/vmcore/utf8.h b/src/vmcore/utf8.h index da788d774..b6a6992ab 100644 --- a/src/vmcore/utf8.h +++ b/src/vmcore/utf8.h @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: utf8.h 8123 2007-06-20 23:50:55Z michi $ + $Id: utf8.h 8132 2007-06-22 11:15:47Z twisti $ */ @@ -167,6 +167,7 @@ extern utf *utf_get; extern utf *utf_value; extern utf *utf_fillInStackTrace; +extern utf *utf_findNative; extern utf *utf_getSystemClassLoader; extern utf *utf_initCause; extern utf *utf_loadClass; @@ -196,6 +197,7 @@ extern utf *utf_double__void; extern utf *utf_void__java_lang_ClassLoader; extern utf *utf_void__java_lang_Object; extern utf *utf_void__java_lang_Throwable; +extern utf *utf_java_lang_ClassLoader_java_lang_String__J; extern utf *utf_java_lang_Exception__V; extern utf *utf_java_lang_Object__java_lang_Object; extern utf *utf_java_lang_String__void;