Merged revisions 7407-7440 via svnmerge from
authormichi <none@none>
Fri, 2 Mar 2007 23:13:10 +0000 (23:13 +0000)
committermichi <none@none>
Fri, 2 Mar 2007 23:13:10 +0000 (23:13 +0000)
svn+ssh://michi@c1.complang.tuwien.ac.at/ahome/cacao/svn/cacao/trunk

........
  r7408 | twisti | 2007-02-26 23:11:38 +0100 (Mon, 26 Feb 2007) | 15 lines

  * src/native/vm/java_lang_ClassLoader.c: New file.
  * src/native/vm/java_lang_ClassLoader.h: Likewise.

  * src/native/vm/gnu/java_lang_VMClassLoader.c
  (native/vm/java_lang_ClassLoader.h): Added.
  (defineClass): Removed code and call
  _Jv_java_lang_ClassLoader_defineClass.

  * src/native/vm/Makefile.am (libnativevm_la_SOURCES): Added
  java_lang_ClassLoader.[ch].

  * src/native/jni.c [ENABLE_JAVASE]
  (native/vm/java_lang_ClassLoader.h): Added.
  (_Jv_JNI_DefineClass): Removed env and NULL arguments.
........
  r7409 | ajordan | 2007-02-27 03:07:00 +0100 (Tue, 27 Feb 2007) | 8 lines

  * configure.ac: added solaris specific stuff: arch defines, libintl dependency and solaris subdir makefile.

  * src/vm/jit/stacktrace.h: declared SPARC specific functions.

  * src/vm/jit/sparc64/emit.c: fixed call to builtin_verbosecall_exit.

  * src/vm/jit/sparc64/solaris/md-os.c: signal handling disabled, can't test right now.
........
  r7412 | twisti | 2007-02-27 22:13:26 +0100 (Tue, 27 Feb 2007) | 2 lines

  * src/vm/jit/sparc64/solaris: Set ignore-properties.
........
  r7414 | pm | 2007-02-28 08:22:04 +0100 (Wed, 28 Feb 2007) | 5 lines

  * src/vm/jit/s390/codegen.c (codegen): Added ICMD_AASTORE.
  * src/vm/jit/s390/asmpart.S (asm_patcher_wrapper): Added exception handler.
  * src/vm/jit/s390/asmpart.S (asm_call_jit_compiler): Likewise.
........
  r7415 | twisti | 2007-02-28 14:23:54 +0100 (Wed, 28 Feb 2007) | 3 lines

  * src/native/vm/java_lang_ClassLoader.c (defineClass): Added
  loader-variable for convenience.
........
  r7416 | twisti | 2007-02-28 14:25:56 +0100 (Wed, 28 Feb 2007) | 2 lines

  * src/native/vm/java_lang_ClassLoader.c (vm/stringlocal.h): Added.
........
  r7418 | twisti | 2007-02-28 21:07:06 +0100 (Wed, 28 Feb 2007) | 13 lines

  * src/vm/access.c (access_check_caller): Renamed to
  access_check_member. Don't call access_is_accessible_class, this is
  wrong.

  * src/native/vm/gnu/java_lang_reflect_Constructor.c (constructNative):
  Use access_check_member.

  * src/native/vm/gnu/java_lang_reflect_Field.c (CHECKFIELDACCESS):
  Removed.
  (cacao_get_field_address): Use access_check_member.

  * src/native/vm/gnu/java_lang_reflect_Method.c (invokeNative): Likewise.
........
  r7419 | twisti | 2007-02-28 23:00:50 +0100 (Wed, 28 Feb 2007) | 3 lines

  * src/vm/access.h (access_check_caller): Renamed to
  access_check_member.
........
  r7420 | edwin | 2007-02-28 23:30:31 +0100 (Wed, 28 Feb 2007) | 3 lines

  * src/vm/jit/stack.c (stack_analyse): Fix: reset TYPE_VOID to
  TYPE_ADR at the end of stack_analyse.
........
  r7421 | twisti | 2007-02-28 23:31:50 +0100 (Wed, 28 Feb 2007) | 4 lines

  * src/vm/vm.c (vm_create): Changed initialization order. Call
  properties_postinit later, since it puts a pointer to
  _Jv_bootclasspath into the properties list.
........
  r7422 | edwin | 2007-02-28 23:50:28 +0100 (Wed, 28 Feb 2007) | 4 lines

  * tests/regression/jasmin/test_verify_ok_local_as_retaddr_and_reference.j:
  New test.
  * tests/regression/jasmin/Makefile.am: Added new test.
........
  r7423 | edwin | 2007-03-01 00:20:58 +0100 (Thu, 01 Mar 2007) | 2 lines

  * src/vm/jit/stack.c (stack_analyse): Minor STACK_VERBOSE improvements.
........
  r7424 | edwin | 2007-03-01 00:27:15 +0100 (Thu, 01 Mar 2007) | 3 lines

  * src/vm/jit/verify/typecheck.c (handle_basic_block): Move the printing
  of the block to a point where jd->var is already valid.
........
  r7425 | twisti | 2007-03-01 00:39:48 +0100 (Thu, 01 Mar 2007) | 2 lines

  * src/cacaoh/dummy.c (typeinfo_print): Added.
........
  r7426 | twisti | 2007-03-01 00:57:39 +0100 (Thu, 01 Mar 2007) | 5 lines

  * src/vmcore/classcache.c (toolbox/logging.h): Added.
  (classcache_merge_class_entries): Replace log_text with log_println.
  (classcache_store): Likewise.
  (classcache_store_defined): Likewise.
........
  r7427 | edwin | 2007-03-01 13:32:10 +0100 (Thu, 01 Mar 2007) | 3 lines

  * src/vmcore/resolve.c (resolve_classref_or_classinfo): Always use
  refmethod->class as the referring class, if it is available.
........
  r7428 | twisti | 2007-03-01 13:39:45 +0100 (Thu, 01 Mar 2007) | 6 lines

  * src/native/vm/Makefile.am [ENABLE_JAVASE] (CLASSLOADER_SOURCES):
  Added.
  (libnativevm_la_SOURCES): Use CLASSLOADER_SOURCES.

  * src/native/vm/java_lang_ClassLoader.c (native/jni.h): Added.
........
  r7431 | edwin | 2007-03-01 14:49:14 +0100 (Thu, 01 Mar 2007) | 14 lines

  * src/vmcore/resolve.h, src/vmcore/resolve.c
  (resolve_class_eager_no_access_check): New function.

  * src/vm/jit/powerpc/patcher.c: Use resolve_class_eager_no_access_check.
  * src/vm/jit/arm/patcher.c: Likewise.
  * src/vm/jit/sparc64/patcher.c: Likewise.
  * src/vm/jit/alpha/patcher.c: Likewise.
  * src/vm/jit/s390/patcher.c: Likewise.
  * src/vm/jit/mips/patcher.c: Likewise.
  * src/vm/jit/powerpc64/patcher.c: Likewise.
  * src/vm/jit/i386/patcher.c: Likewise.
  * src/vm/jit/x86_64/patcher.c: Likewise.
........
  r7433 | edwin | 2007-03-02 20:42:13 +0100 (Fri, 02 Mar 2007) | 3 lines

  * tests/regression/resolving: Added resolving test suite. These tests
  check lazy loading, classloader handling, loading & subtype constraints.
........
  r7434 | edwin | 2007-03-02 20:44:53 +0100 (Fri, 02 Mar 2007) | 2 lines

  * configure.ac: Added Makefiles of resolving test suite.
........
  r7435 | edwin | 2007-03-02 20:45:42 +0100 (Fri, 02 Mar 2007) | 2 lines

  * src/vmcore/classcache.c: Print debug messages to stdout.
........

--HG--
branch : exact-gc

58 files changed:
configure.ac
src/cacaoh/dummy.c
src/native/jni.c
src/native/vm/Makefile.am
src/native/vm/gnu/java_lang_VMClassLoader.c
src/native/vm/gnu/java_lang_reflect_Constructor.c
src/native/vm/gnu/java_lang_reflect_Field.c
src/native/vm/gnu/java_lang_reflect_Method.c
src/native/vm/java_lang_ClassLoader.c [new file with mode: 0644]
src/native/vm/java_lang_ClassLoader.h [new file with mode: 0644]
src/vm/access.c
src/vm/access.h
src/vm/jit/alpha/patcher.c
src/vm/jit/arm/patcher.c
src/vm/jit/i386/patcher.c
src/vm/jit/mips/patcher.c
src/vm/jit/powerpc/patcher.c
src/vm/jit/powerpc64/patcher.c
src/vm/jit/s390/asmpart.S
src/vm/jit/s390/codegen.c
src/vm/jit/s390/patcher.c
src/vm/jit/sparc64/emit.c
src/vm/jit/sparc64/patcher.c
src/vm/jit/sparc64/solaris/md-os.c
src/vm/jit/stack.c
src/vm/jit/stacktrace.h
src/vm/jit/verify/typecheck.c
src/vm/jit/x86_64/patcher.c
src/vm/vm.c
src/vmcore/classcache.c
src/vmcore/resolve.c
src/vmcore/resolve.h
tests/regression/Makefile.am
tests/regression/jasmin/Makefile.am
tests/regression/jasmin/test_verify_ok_local_as_retaddr_and_reference.j [new file with mode: 0644]
tests/regression/resolving/Makefile.am [new file with mode: 0644]
tests/regression/resolving/TestController.java [new file with mode: 0644]
tests/regression/resolving/TestLoader.java [new file with mode: 0644]
tests/regression/resolving/classes1/BarPassFoo.java [new file with mode: 0644]
tests/regression/resolving/classes1/BarUseFoo.java [new file with mode: 0644]
tests/regression/resolving/classes1/Foo.java [new file with mode: 0644]
tests/regression/resolving/classes1/Makefile.am [new file with mode: 0644]
tests/regression/resolving/classes2/BarPassFoo.java [new file with mode: 0644]
tests/regression/resolving/classes2/BarUseFoo.java [new file with mode: 0644]
tests/regression/resolving/classes2/DerivedFoo.java [new file with mode: 0644]
tests/regression/resolving/classes2/Foo.java [new file with mode: 0644]
tests/regression/resolving/classes2/Makefile.am [new file with mode: 0644]
tests/regression/resolving/classes3/BarPassFoo.java [new file with mode: 0644]
tests/regression/resolving/classes3/BarUseFoo.java [new file with mode: 0644]
tests/regression/resolving/classes3/DerivedFoo.java [new file with mode: 0644]
tests/regression/resolving/classes3/Foo.java [new file with mode: 0644]
tests/regression/resolving/classes3/Makefile.am [new file with mode: 0644]
tests/regression/resolving/test_instance_subtype_violated.java [new file with mode: 0644]
tests/regression/resolving/test_param_loading_constraint_violated.java [new file with mode: 0644]
tests/regression/resolving/test_param_loading_constraint_violated_derived.java [new file with mode: 0644]
tests/regression/resolving/test_param_subtype_violated.java [new file with mode: 0644]
tests/regression/resolving/test_retval_loading_constraint_violated.java [new file with mode: 0644]
tests/regression/resolving/test_simple_lazy_load.java [new file with mode: 0644]

index 0df7525efcdd65c7c2856bd1c274fd43312bfe9f..05284e9099bc4a68726a95941f2c8a17c058d101 100644 (file)
@@ -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 7375 2007-02-20 00:38:06Z twisti $
+dnl $Id: configure.ac 7441 2007-03-02 23:13:10Z michi $
 
 dnl Process this file with autoconf to produce a configure script.
 
@@ -169,8 +169,10 @@ dnl must be before *linux*
 
 *solaris* )
     OS_DIR="solaris"
-    INTRP_CFLAGS="$ARCH_CFLAGS -D__SOLARIS__ -Wall -Wno-long-long -D_POSIX_C_SOURCE=199506L -D_XOPEN_SOURCE=500 -D__EXTENSIONS__ -D_BSD_SOURCE"
-    ARCH_CFLAGS="$ARCH_CFLAGS -D__SOLARIS__ -ansi -pedantic -Wall -Wno-long-long -D_POSIX_C_SOURCE=199506L -D_XOPEN_SOURCE=500 -D__EXTENSIONS__ -D_BSD_SOURCE"
+       dnl on solaris the architecture defines 'sparc','sun','unix' are not set when cpp is called with -ansi
+       dnl therefore we add them here
+    INTRP_CFLAGS="$ARCH_CFLAGS -D__SOLARIS__ -Wall -Wno-long-long -D_POSIX_C_SOURCE=199506L -D_XOPEN_SOURCE=500 -D__EXTENSIONS__ -D_BSD_SOURCE -Dsparc -Dsun -Dunix"
+    ARCH_CFLAGS="$ARCH_CFLAGS -D__SOLARIS__ -ansi -pedantic -Wall -Wno-long-long -D_POSIX_C_SOURCE=199506L -D_XOPEN_SOURCE=500 -D__EXTENSIONS__ -D_BSD_SOURCE -Dsparc -Dsun -Dunix"
     ;;
 
 * )
@@ -442,7 +444,7 @@ if test x"${ENABLE_DISASSEMBLER}" = "xyes"; then
             AC_CHECK_HEADER([dis-asm.h],, [AC_MSG_ERROR(cannot find dis-asm.h)])
 
             case "${OS_DIR}" in
-                cygwin | darwin | netbsd )
+                cygwin | darwin | netbsd | solaris)
                      AC_CHECK_LIB(intl, dcgettext,, [AC_MSG_ERROR(cannot find libintl (from binutils))])
                      ;;
             esac
@@ -1038,6 +1040,7 @@ AC_CONFIG_FILES([Makefile]
                [src/vm/jit/schedule/Makefile]
                [src/vm/jit/sparc64/Makefile]
                [src/vm/jit/sparc64/linux/Makefile]
+               [src/vm/jit/sparc64/solaris/Makefile]
                [src/vm/jit/tools/Makefile]
                [src/vm/jit/verify/Makefile]
                [src/vm/jit/x86_64/Makefile]
@@ -1048,7 +1051,12 @@ AC_CONFIG_FILES([Makefile]
                [tests/regression/Makefile]
                [tests/regression/codepatching/Makefile]
                [tests/regression/jasmin/Makefile]
-               [tests/regression/native/Makefile])
+               [tests/regression/native/Makefile]
+               [tests/regression/resolving/Makefile]
+               [tests/regression/resolving/classes1/Makefile]
+               [tests/regression/resolving/classes2/Makefile]
+               [tests/regression/resolving/classes3/Makefile]
+               )
 
 
 dnl now configure subpackages with OPT_CFLAGS and ARCH_CFLAGS
index 774e4dbf44a5c3e09acd9ec22ff28cb2f4839cee..947a6682b4ccb71b1e445c6bad3142c59e35f245 100644 (file)
@@ -493,6 +493,10 @@ typecheck_result typeinfo_is_assignable_to_class(typeinfo *value, classref_or_cl
        return typecheck_TRUE;
 }
 
+void typeinfo_print(FILE *file, typeinfo *info, int indent)
+{
+}
+
 
 /* vm *************************************************************************/
 
index 704b679c3de2a2393fe6176482fb52c204c589ff..2744d34a14db44a552dbb77d341c8449774034ef 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: jni.c 7439 2007-03-02 22:43:27Z michi $
+   $Id: jni.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
 
 #include "native/vm/java_lang_Class.h"
 
+#if defined(ENABLE_JAVASE)
+# include "native/vm/java_lang_ClassLoader.h"
+#endif
+
 #if defined(ENABLE_THREADS)
 # include "threads/native/lock.h"
 # include "threads/native/threads.h"
@@ -1124,8 +1128,8 @@ jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
        s  = javastring_new_from_utf_string(name);
        ba = (java_bytearray *) buf;
 
-       c = (jclass) _Jv_java_lang_ClassLoader_defineClass(env, NULL, cl, s, ba,
-                                                                                                          0, bufLen, NULL);
+       c = (jclass) _Jv_java_lang_ClassLoader_defineClass(cl, s, ba, 0, bufLen,
+                                                                                                          NULL);
 
        return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
 #else
index a00b0e564b9c78de7e69c7c1984d41123ff3a8de..71f95d8f59b05ecf48772bc97d65d8ac378d4e53 100644 (file)
@@ -50,12 +50,19 @@ NATIVEVM_LIB = \
        gnu/libnativevmcore.la
 endif
 
+if ENABLE_JAVASE
+CLASSLOADER_SOURCES = \
+       java_lang_ClassLoader.c \
+       java_lang_ClassLoader.h
+endif
+
 noinst_LTLIBRARIES = \
        libnativevm.la
 
 libnativevm_la_SOURCES = \
        java_lang_Class.c \
        java_lang_Class.h \
+       $(CLASSLOADER_SOURCES) \
        java_lang_Object.c \
        java_lang_Object.h \
        java_lang_Runtime.c \
index 2a33089c8db8a60875436444437cd639a4636b99..aed9dde716b015d8e635aa9e039d97031f3a45c1 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: java_lang_VMClassLoader.c 7399 2007-02-23 23:29:13Z michi $
+   $Id: java_lang_VMClassLoader.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -44,6 +44,8 @@
 #include "native/include/java_lang_ClassLoader.h"
 #include "native/include/java_util_Vector.h"
 
+#include "native/vm/java_lang_ClassLoader.h"
+
 #include "toolbox/logging.h"
 
 #include "vm/builtin.h"
  * Method:    defineClass
  * Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;
  */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIEnv *env, jclass clazz, java_lang_ClassLoader *clo, java_lang_String *name, java_bytearray *data, s4 offset, s4 len, java_security_ProtectionDomain *pd)
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIEnv *env, jclass clazz, java_lang_ClassLoader *cl, java_lang_String *name, java_bytearray *data, s4 offset, s4 len, java_security_ProtectionDomain *pd)
 {
-       classinfo       *c;
-       classinfo       *r;
-       classbuffer     *cb;
-       classloader     *cl;
-       utf             *utfname;
-       java_lang_Class *co;
-#if defined(ENABLE_JVMTI)
-       jint new_class_data_len = 0;
-       unsigned char* new_class_data = NULL;
-#endif
-
-       /* check if data was passed */
-
-       if (data == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       /* check the indexes passed */
-
-       if ((offset < 0) || (len < 0) || ((offset + len) > data->header.size)) {
-               exceptions_throw_arrayindexoutofboundsexception();
-               return NULL;
-       }
-
-       /* add classloader to classloader hashtable */
-
-       assert(clo);
-       cl = loader_hashtable_classloader_add((java_objectheader *) clo);
-
-
-       if (name != NULL) {
-               /* convert '.' to '/' in java string */
-
-               utfname = javastring_toutf(name, true);
-               
-               /* check if this class has already been defined */
-
-               c = classcache_lookup_defined_or_initiated(cl, utfname);
-               if (c != NULL) {
-                       exceptions_throw_linkageerror("duplicate class definition: ", c);
-                       return NULL;
-               }
-       } 
-       else {
-               utfname = NULL;
-       }
-
-
-#if defined(ENABLE_JVMTI)
-       /* XXX again this will not work because of the indirection cell for classloaders */
-       assert(0);
-       /* fire Class File Load Hook JVMTI event */
-       if (jvmti) jvmti_ClassFileLoadHook(utfname, len, (unsigned char*)data->data, 
-                                                       (java_objectheader *)cl, (java_objectheader *)pd, 
-                                                       &new_class_data_len, &new_class_data);
-#endif
-
-
-       /* create a new classinfo struct */
-
-       c = class_create_classinfo(utfname);
-
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
-
-       if (opt_getloadingtime)
-               loadingtime_start();
-#endif
-
-       /* build a classbuffer with the given data */
-
-       cb = NEW(classbuffer);
-       cb->class = c;
-#if defined(ENABLE_JVMTI)
-       /* check if the JVMTI wants to modify the class */
-       if (new_class_data == NULL) {
-#endif
-       cb->size  = len;
-       cb->data  = (u1 *) &data->data[offset];
-#if defined(ENABLE_JVMTI)
-       } else {
-               cb->size  = new_class_data_len;
-               cb->data  = (u1 *) new_class_data;
-       }
-#endif
-       cb->pos   = cb->data;
-
-       /* preset the defining classloader */
-
-       c->classloader = cl;
-
-       /* load the class from this buffer */
-
-       r = load_class_from_classbuffer(cb);
-
-       /* free memory */
-
-       FREE(cb, classbuffer);
-
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
-
-       if (opt_getloadingtime)
-               loadingtime_stop();
-#endif
-
-       if (r == NULL) {
-               /* If return value is NULL, we had a problem and the class is
-                  not loaded.  Now free the allocated memory, otherwise we
-                  could run into a DOS. */
-
-               class_free(c);
-
-               return NULL;
-       }
-
-       /* set ProtectionDomain */
-
-       co = (java_lang_Class *) c;
-
-       co->pd = pd;
-
-       /* Store the newly defined class in the class cache. This call also       */
-       /* checks whether a class of the same name has already been defined by    */
-       /* the same defining loader, and if so, replaces the newly created class  */
-       /* by the one defined earlier.                                            */
-       /* Important: The classinfo given to classcache_store must be             */
-       /*            fully prepared because another thread may return this       */
-       /*            pointer after the lookup at to top of this function         */
-       /*            directly after the class cache lock has been released.      */
-
-       c = classcache_store(cl, c, true);
-
-       return (java_lang_Class *) c;
+       return _Jv_java_lang_ClassLoader_defineClass(cl, name, data, offset, len, pd);
 }
 
 
index cbeeb4cda28a6ad27026467f534c158dd5144532..d2fa2eaac92e5c04b13b446267782d8cc8cff0a0 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: java_lang_reflect_Constructor.c 7246 2007-01-29 18:49:05Z twisti $
+   $Id: java_lang_reflect_Constructor.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -115,46 +115,14 @@ JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_Constructor_construct
        java_objectheader *o;
 
        c = (classinfo *) declaringClass;
-
-#if 0
-       /* find initializer */
-
-       if (!args) {
-               if (this->parameterTypes->header.size != 0) {
-                       *exceptionptr =
-                               new_exception_message(string_java_lang_IllegalArgumentException,
-                                                                         "wrong number of arguments");
-                       return NULL;
-               }
-
-       } else {
-               if (this->parameterTypes->header.size != args->header.size) {
-                       *exceptionptr =
-                               new_exception_message(string_java_lang_IllegalArgumentException,
-                                                                         "wrong number of arguments");
-                       return NULL;
-               }
-       }
-#endif
-
-       if (this->slot >= c->methodscount) {
-               log_text("illegal index in methods table");
-               return NULL;
-       }
-
        m = &(c->methods[this->slot]);
 
-       if (m->name != utf_init) {
-               /* XXX throw an exception here, although this should never happen */
-
-               assert(0);
-       }
-
        /* check method access */
+
        /* check if we should bypass security checks (AccessibleObject) */
 
        if (this->flag == false) {
-               if (!access_check_caller(c, m->flags, 1))
+               if (!access_check_member(c, m->flags, 1))
                        return NULL;
        }
 
@@ -162,7 +130,7 @@ JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_Constructor_construct
 
        o = builtin_new(c);
 
-       if (!o)
+       if (o == NULL)
                return NULL;
         
        /* call initializer */
index 796e3607a9c3ca2ac6a9b04f499fd213ff50c95c..6290ddbaa11a2924458f571fafc30d43c35e6a5d 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: java_lang_reflect_Field.c 7246 2007-01-29 18:49:05Z twisti $
+   $Id: java_lang_reflect_Field.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -62,9 +62,6 @@
 #include "vmcore/utf8.h"
 
 
-#define CHECKFIELDACCESS(this,fi,c,doret)
-
-
 /* cacao_get_field_address *****************************************************
 
    Return the address of a field of an object.
@@ -97,7 +94,7 @@ static void *cacao_get_field_address(java_lang_reflect_Field *this,
                           java.lang.reflect.Field.xxx (Native Method)
                   [0] <caller>
                */
-               if (!access_check_caller(c, f->flags, 0))
+               if (!access_check_member(c, f->flags, 0))
                        return NULL;
        }
 
index dde38297ff1b5b77a37875a33967cc769f3fb7d4..2d5ac85e07a31d786f13a57c8dc5c820b23633b1 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: java_lang_reflect_Method.c 7328 2007-02-11 21:22:07Z twisti $
+   $Id: java_lang_reflect_Method.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -136,10 +136,11 @@ JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_Method_invokeNative(J
        m = &(c->methods[slot]);
 
        /* check method access */
+
        /* check if we should bypass security checks (AccessibleObject) */
 
        if (this->flag == false) {
-               if (!access_check_caller(c, m->flags, 1))
+               if (!access_check_member(c, m->flags, 1))
                        return NULL;
        }
 
diff --git a/src/native/vm/java_lang_ClassLoader.c b/src/native/vm/java_lang_ClassLoader.c
new file mode 100644 (file)
index 0000000..351991a
--- /dev/null
@@ -0,0 +1,217 @@
+/* src/native/vm/java_lang_ClassLoader.c - java/lang/ClassLoader
+
+   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: java_lang_VMClass.c 6131 2006-12-06 22:15:57Z twisti $
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "vm/global.h"                          /* required by native headers */
+
+#include "native/jni.h"
+
+#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_Class.h"
+# include "native/include/java_lang_ClassLoader.h"
+# include "native/include/java_security_ProtectionDomain.h"
+#endif
+
+#include "vm/exceptions.h"
+#include "vm/stringlocal.h"
+
+#include "vmcore/class.h"
+#include "vmcore/classcache.h"
+#include "vmcore/options.h"
+
+
+/*
+ * Class:     java/lang/ClassLoader
+ * Method:    defineClass
+ * Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;
+ */
+java_lang_Class *_Jv_java_lang_ClassLoader_defineClass(java_lang_ClassLoader *cl, java_lang_String *name, java_bytearray *data, s4 offset, s4 len, java_security_ProtectionDomain *pd)
+{
+       utf               *utfname;
+       classinfo         *c;
+       classinfo         *r;
+       classbuffer       *cb;
+       classloader       *loader;
+       java_lang_Class   *co;
+#if defined(ENABLE_JVMTI)
+       jint new_class_data_len = 0;
+       unsigned char* new_class_data = NULL;
+#endif
+
+       /* check if data was passed */
+
+       if (data == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       /* check the indexes passed */
+
+       if ((offset < 0) || (len < 0) || ((offset + len) > data->header.size)) {
+               exceptions_throw_arrayindexoutofboundsexception();
+               return NULL;
+       }
+
+       /* add classloader to classloader hashtable */
+
+       assert(cl);
+       loader = loader_hashtable_classloader_add((java_objectheader *) cl);
+
+       if (name != NULL) {
+               /* convert '.' to '/' in java string */
+
+               utfname = javastring_toutf(name, true);
+               
+               /* check if this class has already been defined */
+
+               c = classcache_lookup_defined_or_initiated(cl, utfname);
+
+               if (c != NULL) {
+                       exceptions_throw_linkageerror("duplicate class definition: ", c);
+                       return NULL;
+               }
+       } 
+       else {
+               utfname = NULL;
+       }
+
+#if defined(ENABLE_JVMTI)
+       /* XXX again this will not work because of the indirection cell for classloaders */
+       assert(0);
+       /* fire Class File Load Hook JVMTI event */
+
+       if (jvmti)
+               jvmti_ClassFileLoadHook(utfname, len, (unsigned char *) data->data, 
+                                                               loader, (java_objectheader *) pd, 
+                                                               &new_class_data_len, &new_class_data);
+#endif
+
+       /* create a new classinfo struct */
+
+       c = class_create_classinfo(utfname);
+
+#if defined(ENABLE_STATISTICS)
+       /* measure time */
+
+       if (opt_getloadingtime)
+               loadingtime_start();
+#endif
+
+       /* build a classbuffer with the given data */
+
+       cb = NEW(classbuffer);
+       cb->class = c;
+#if defined(ENABLE_JVMTI)
+       /* check if the JVMTI wants to modify the class */
+       if (new_class_data == NULL) {
+#endif
+       cb->size  = len;
+       cb->data  = (u1 *) &data->data[offset];
+#if defined(ENABLE_JVMTI)
+       } else {
+               cb->size  = new_class_data_len;
+               cb->data  = (u1 *) new_class_data;
+       }
+#endif
+       cb->pos   = cb->data;
+
+       /* preset the defining classloader */
+
+       c->classloader = loader;
+
+       /* load the class from this buffer */
+
+       r = load_class_from_classbuffer(cb);
+
+       /* free memory */
+
+       FREE(cb, classbuffer);
+
+#if defined(ENABLE_STATISTICS)
+       /* measure time */
+
+       if (opt_getloadingtime)
+               loadingtime_stop();
+#endif
+
+       if (r == NULL) {
+               /* If return value is NULL, we had a problem and the class is
+                  not loaded.  Now free the allocated memory, otherwise we
+                  could run into a DOS. */
+
+               class_free(c);
+
+               return NULL;
+       }
+
+       /* set ProtectionDomain */
+
+       co = (java_lang_Class *) c;
+
+       co->pd = pd;
+
+       /* Store the newly defined class in the class cache. This call also       */
+       /* checks whether a class of the same name has already been defined by    */
+       /* the same defining loader, and if so, replaces the newly created class  */
+       /* by the one defined earlier.                                            */
+       /* Important: The classinfo given to classcache_store must be             */
+       /*            fully prepared because another thread may return this       */
+       /*            pointer after the lookup at to top of this function         */
+       /*            directly after the class cache lock has been released.      */
+
+       c = classcache_store(loader, c, true);
+
+       return (java_lang_Class *) c;
+}
+
+
+/*
+ * 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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/native/vm/java_lang_ClassLoader.h b/src/native/vm/java_lang_ClassLoader.h
new file mode 100644 (file)
index 0000000..0127dd3
--- /dev/null
@@ -0,0 +1,71 @@
+/* src/native/vm/java_lang_ClassLoader.h - java/lang/ClassLoader functions
+
+   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: java_lang_VMClass.c 6131 2006-12-06 22:15:57Z twisti $
+
+*/
+
+
+#ifndef _JV_JAVA_LANG_CLASSLOADER_H
+#define _JV_JAVA_LANG_CLASSLOADER_H
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "native/jni.h"
+
+#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_Class.h"
+# include "native/include/java_lang_ClassLoader.h"
+# include "native/include/java_security_ProtectionDomain.h"
+#endif
+
+#include "vm/global.h"
+
+
+/* function prototypes ********************************************************/
+
+#if defined(ENABLE_JAVASE)
+java_lang_Class *_Jv_java_lang_ClassLoader_defineClass(java_lang_ClassLoader *cl, java_lang_String *name, java_bytearray *data, s4 offset, s4 len, java_security_ProtectionDomain *pd);
+#endif
+
+#endif /* _JV_JAVA_LANG_CLASSLOADER_H */
+
+
+/*
+ * 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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
index 66c9db65afdb749831b9599a4714837829ee7169..45e8548bcd3d03721ea65e3c8c0a6f421f0a9439 100644 (file)
@@ -1,4 +1,4 @@
-/* src/vmcore/access.c - checking access rights
+/* src/vm/access.c - checking access rights
 
    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: access.c 7246 2007-01-29 18:49:05Z twisti $
+   $Id: access.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -71,20 +71,21 @@ bool access_is_accessible_class(classinfo *referer, classinfo *cls)
        assert(cls);
 
        /* public classes are always accessible */
+
        if (cls->flags & ACC_PUBLIC)
                return true;
 
        /* a class in the same package is always accessible */
+
        if (SAME_PACKAGE(referer, cls))
                return true;
 
        /* a non-public class in another package is not accessible */
+
        return false;
 }
 
 
-
-
 /* access_is_accessible_member *************************************************
  
    Check if a field or method is accessible from a given class
@@ -116,37 +117,45 @@ bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
        assert(declarer);
        
        /* public members are accessible */
+
        if (memberflags & ACC_PUBLIC)
                return true;
 
        /* {declarer is not an interface} */
 
        /* private members are only accessible by the class itself */
+
        if (memberflags & ACC_PRIVATE)
                return (referer == declarer);
 
        /* {the member is protected or package private} */
 
-       /* protected and package private members are accessible in the same package */
-       if (SAME_PACKAGE(referer,declarer))
+       /* protected and package private members are accessible in the
+          same package */
+
+       if (SAME_PACKAGE(referer, declarer))
                return true;
 
        /* package private members are not accessible outside the package */
+
        if (!(memberflags & ACC_PROTECTED))
                return false;
 
        /* {the member is protected and declarer is in another package} */
 
-       /* a necessary condition for access is that referer is a subclass of declarer */
+       /* a necessary condition for access is that referer is a subclass
+          of declarer */
+
        assert((referer->state & CLASS_LINKED) && (declarer->state & CLASS_LINKED));
-       if (builtin_isanysubclass(referer,declarer))
+
+       if (builtin_isanysubclass(referer, declarer))
                return true;
 
        return false;
 }
 
 
-/* access_check_caller *********************************************************
+/* access_check_member *********************************************************
  
    Check if the (indirect) caller has access rights to a member.
   
@@ -169,7 +178,7 @@ bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
    
 *******************************************************************************/
 
-bool access_check_caller(classinfo *declarer, s4 memberflags, s4 calldepth)
+bool access_check_member(classinfo *declarer, s4 memberflags, s4 calldepth)
 {
        java_objectarray *oa;
        classinfo        *callerclass;
@@ -192,9 +201,7 @@ bool access_check_caller(classinfo *declarer, s4 memberflags, s4 calldepth)
 
        /* check access rights */
 
-       if (!access_is_accessible_class(callerclass, declarer)
-               || !access_is_accessible_member(callerclass, declarer, memberflags))
-       {
+       if (!access_is_accessible_member(callerclass, declarer, memberflags)) {
                exceptions_throw_illegalaccessexception(callerclass);
                return false;
        }
index d46cd4f161a7cbc905862744edb0827795491f94..e2b867be1d64626641f4a536a88dab122da571e9 100644 (file)
@@ -1,4 +1,4 @@
-/* src/vmcore/access.h - checking access rights
+/* src/vm/access.h - checking access rights
 
    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: access.h 7246 2007-01-29 18:49:05Z twisti $
+   $Id: access.h 7441 2007-03-02 23:13:10Z michi $
 
 */
 
+
 #ifndef _ACCESS_H
 #define _ACCESS_H
 
@@ -51,10 +52,11 @@ bool access_is_accessible_class(classinfo *referer, classinfo *cls);
 bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
                                                                 s4 memberflags);
 
-bool access_check_caller(classinfo *declarer, s4 memberflags, s4 calldepth);
+bool access_check_member(classinfo *declarer, s4 memberflags, s4 calldepth);
 
 #endif /* _ACCESS_H */
 
+
 /*
  * 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
index 84e08cf7ab3457ad6e499072352bd52be8e7a074..053166a6671fddcf981fc8e3f64423c987aa1e70 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: patcher.c 7251 2007-01-29 20:24:53Z twisti $
+   $Id: patcher.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -177,15 +177,14 @@ bool patcher_initialize_class(u1 *sp)
 bool patcher_resolve_class(u1 *sp)
 {
        unresolved_class *uc;
-       classinfo        *c;
 
        /* get stuff from the stack */
 
        uc = (unresolved_class *)  *((ptrint *) (sp + 2 * 8));
 
-       /* resolve the class */
+       /* resolve the class and check subtype constraints */
 
-       if (!resolve_class(uc, resolveEager, false, &c))
+       if (!resolve_class_eager_no_access_check(uc))
                return false;
 
        return true;
index 6052996e6a856ff2cb1d6d0ac33cbeafeb5eca86..cd99711779eb23863a41490637d213b909e8a319 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: patcher.c 7297 2007-02-07 14:59:56Z twisti $
+   $Id: patcher.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -700,15 +700,14 @@ bool patcher_clinit(u1 *sp)
 bool patcher_athrow_areturn(u1 *sp)
 {
        unresolved_class *uc;
-       classinfo        *c;
 
        /* get stuff from the stack */
 
        uc = (unresolved_class *) *((ptrint *) (sp + 1 * 4));
 
-       /* check if the class is initialized */
+       /* resolve the class and check subtype constraints */
 
-       if (!resolve_class(uc, resolveEager, false, &c))
+       if (!resolve_class_eager_no_access_check(uc))
                return false;
 
        return true;
index d467e7b23eae375ac152460a0169115d41334884..92db1dd494cac79ace16a6d982d891a60de03ab3 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: patcher.c 7297 2007-02-07 14:59:56Z twisti $
+   $Id: patcher.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -889,7 +889,6 @@ bool patcher_athrow_areturn(u1 *sp)
        u1               *ra;
        u8                mcode;
        unresolved_class *uc;
-       classinfo        *c;
 
        /* get stuff from the stack */
 
@@ -897,9 +896,9 @@ bool patcher_athrow_areturn(u1 *sp)
        mcode =                      *((u8 *)     (sp + 2 * 4));
        uc    = (unresolved_class *) *((ptrint *) (sp + 1 * 4));
 
-       /* resolve the class */
+       /* resolve the class and check subtype constraints */
 
-       if (!resolve_class(uc, resolveEager, false, &c))
+       if (!resolve_class_eager_no_access_check(uc))
                return false;
 
        /* patch back original code */
index fb11caf336097f800342b609f139d52c4ed23b5a..8b8f454fec4638bc1febed371f52857079ef241e 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: patcher.c 7252 2007-01-29 21:09:01Z twisti $
+   $Id: patcher.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -799,15 +799,14 @@ bool patcher_clinit(u1 *sp)
 bool patcher_athrow_areturn(u1 *sp)
 {
        unresolved_class *uc;
-       classinfo        *c;
 
        /* get stuff from the stack */
 
        uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
 
-       /* resolve the class */
+       /* resolve the class and check subtype constraints */
 
-       if (!resolve_class(uc, resolveEager, false, &c))
+       if (!resolve_class_eager_no_access_check(uc))
                return false;
 
        return true;
index e7a1360621269e795d549febaed87d5fa41ea503..abfb8aa186debd07854ac33c3ff8654ae1d5e24c 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: patcher.c 7246 2007-01-29 18:49:05Z twisti $
+   $Id: patcher.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -175,15 +175,14 @@ bool patcher_initialize_class(u1 *sp)
 bool patcher_resolve_class(u1 *sp)
 {
        unresolved_class *uc;
-       classinfo        *c;
 
        /* get stuff from the stack */
 
        uc = (unresolved_class *) *((ptrint *) (sp + 2 * 4));
 
-       /* resolve the class */
+       /* resolve the class and check subtype constraints */
 
-       if (!resolve_class(uc, resolveEager, false, &c))
+       if (!resolve_class_eager_no_access_check(uc))
                return false;
 
        return true;
index 3cb769d2db88b23b9da15c8e8d477af209684e10..3b53da79d03c4cdf0453e207c045b55d64a7e79e 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: patcher.c 7311 2007-02-09 13:20:27Z twisti $
+   $Id: patcher.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -832,7 +832,6 @@ bool patcher_athrow_areturn(u1 *sp)
        u1               *ra;
        u4                mcode;
        unresolved_class *uc;
-       classinfo        *c;
 
        /* get stuff from the stack */
 
@@ -840,9 +839,9 @@ bool patcher_athrow_areturn(u1 *sp)
        mcode =                      *((u4 *)     (sp + 3 * 8));
        uc    = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
 
-       /* resolve the class */
+       /* resolve the class and check subtype constraints */
 
-       if (!resolve_class(uc, resolveEager, false, &c))
+       if (!resolve_class_eager_no_access_check(uc))
                return false;
 
        /* patch back original code */
index 5fb0292ea54b79dad319c521aea94440d9c5e93b..a4ee6a0701c29ee3c7ea2865f60950a1b990956d 100644 (file)
@@ -30,7 +30,7 @@
 
    Changes: Edwin Steiner
 
-   $Id: asmpart.S 7407 2007-02-26 19:12:03Z michi $
+   $Id: asmpart.S 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -95,8 +95,6 @@ L_##magic##_lp_end:                                         ; \
        .globl asm_getclassvalues_atomic
 
 
-asm_handle_nat_exception:
-       .long 0
 asm_abstractmethoderror:
        .long 0
 asm_replacement_out:
@@ -519,24 +517,27 @@ L_bras_jac:
        lm      %r2,%r5,96(sp)             /* restore volatile int arg regs */
        ld      %f0,96+16(sp)              /* restore volatile float arg regs */
        ld      %f2,96+24(sp)              /* restore volatile float arg regs */
-       l       %r14,96+32(sp)             /* restore return address */
-       ahi     sp, ACJC_STACKFRAME        /* remove stack frame */
 
        ltr     pv,pv
        je      L_asm_call_jit_compiler_exception
 
+       l       %r14,96+32(sp)             /* restore return address */
+       ahi     sp, ACJC_STACKFRAME        /* remove stack frame */
+
 jit_code_entry:                        /* label to set breakpoint on */
        br      pv                         /* call the method, it will return to the caller */
 
 
 L_asm_call_jit_compiler_exception:
-#if 0
-       call    exceptions_get_and_clear_exception@PLT
-       pop     xpc                         /* delete return address              */
-       sub     $3,xpc                      /* faulting address is ra - 3         */
-       jmp     L_asm_handle_exception
-#endif
-       .long 0
+       bras    itmp2, L_bras_acjce
+       .long exceptions_get_and_clear_exception
+L_bras_acjce:
+       l       itmp2, 0(itmp2)
+       basr    %r14, itmp2
+       lr      xptr, %r2
+       l       xpc,96+32(sp)              /* restore return address */
+       ahi     sp, ACJC_STACKFRAME        /* remove stack frame */
+       j       L_asm_handle_nat_exception
 
 
 #if 0
@@ -550,10 +551,11 @@ L_asm_call_jit_compiler_exception:
 *                                                                              *
 *******************************************************************************/
 
-asm_handle_nat_exception:
-       add     $8,sp                       /* clear return address of native stub*/
 #endif
-       
+
+asm_handle_nat_exception:
+L_asm_handle_nat_exception:
+       /* TODO really nothing here ? */
 asm_handle_exception:
 L_asm_handle_exception:                 /* required for PIC code              */
 
@@ -784,12 +786,10 @@ L_apw_bras:
        br      itmp3                       /* return */
 
 L_asm_patcher_wrapper_exception:
-       .long 0
-#if 0
-       mov     itmp3,xptr                  /* get exception                      */
-       pop     xpc                         /* get and remove return address      */
-       jmp     L_asm_handle_exception
-#endif
+       lr      xptr,itmp3                  /* get exception                      */
+       l       xpc, apw_sfs + (5 * 4)(sp)  /* load return address to JIT from stack */
+       ahi     sp, apw_sfs + (6 * 4)       /* remove stack frame, and stack frame by patcher stub */
+       j       L_asm_handle_exception
 
 #if 0
 
index 87c88ade2df5957611677eba6da18855c77ef81b..055ed6c4bd1bdef41a14f31c4ca3e6d0cce1a6ca 100644 (file)
@@ -29,7 +29,7 @@
             Christian Ullrich
             Edwin Steiner
 
-   $Id: codegen.c 7407 2007-02-26 19:12:03Z michi $
+   $Id: codegen.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -2006,20 +2006,25 @@ bool codegen(jitdata *jd)
                        break;
 
                case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
-                       OOPS();
-#if 0
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+
+                       s1 = emit_load_s1(jd, iptr, REG_A0);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
-                       s3 = emit_load_s3(jd, iptr, REG_ITMP3);
+                       emit_array_checks(cd, iptr, s1, s2);
+                       s3 = emit_load_s3(jd, iptr, REG_A1);
+
+                       M_INTMOVE(s1, REG_A0);
+                       M_INTMOVE(s3, REG_A1);
+
+                       disp = dseg_add_functionptr(cd, BUILTIN_canstore);
+                       ICONST(REG_ITMP3, disp);
+                       N_L(REG_PV, 0, REG_ITMP3, REG_PV);
+                       M_ISUB_IMM(96, REG_SP);
+                       M_JSR(REG_RA, REG_PV);
+                       M_IADD_IMM(96, REG_SP);
+                       N_BASR(REG_ITMP1, RN);
+                       disp = (s4) (cd->mcodeptr - cd->mcodebase);
+                       M_LDA(REG_PV, REG_ITMP1, -disp);
 
-                       M_MOV(s1, REG_A0);
-                       M_MOV(s3, REG_A1);
-                       M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
-                       M_CALL(REG_ITMP1);
                        M_TEST(REG_RESULT);
                        M_BEQ(0);
                        codegen_add_arraystoreexception_ref(cd);
@@ -2027,8 +2032,15 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
-                       emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 3);
-#endif
+
+                       M_INTMOVE(s2, REG_ITMP2);
+                       N_SLL(REG_ITMP2, 2, RN);
+                       N_ST(s3, OFFSET(java_objectarray, data[0]), REG_ITMP2, s1);
+
+                       /*
+                       M_SAADDQ(s2, s1, REG_ITMP1); itmp1 := 4 * s2 + s1
+                       M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
+                       */
                        break;
 
 
index e577db2fd6209ce5309d4ac8b5fb54a145b82339..93b410554d6605ddb49296606ca2ae363a774844 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: patcher.c 7383 2007-02-21 20:26:52Z twisti $
+   $Id: patcher.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -974,7 +974,6 @@ __PORTED__ bool patcher_athrow_areturn(u1 *sp)
        u1               *ra;
        u4                mcode;
        unresolved_class *uc;
-       classinfo        *c;
 
        /* get stuff from the stack */
 
@@ -982,9 +981,9 @@ __PORTED__ bool patcher_athrow_areturn(u1 *sp)
        mcode =                      *((u4 *)     (sp + 3 * 4));
        uc    = (unresolved_class *) *((ptrint *) (sp + 2 * 4));
 
-       /* resolve the class */
+       /* resolve the class and check subtype constraints */
 
-       if (!resolve_class(uc, resolveEager, false, &c))
+       if (!resolve_class_eager_no_access_check(uc))
                return false;
 
        /* patch back original code */
index 31b6c3c6ee5dfeed96511a404ad1bb5c781f3328..b4b58ad65b150502f78fcf772b2801750cb9691b 100644 (file)
@@ -361,7 +361,7 @@ void emit_patcher_stubs(jitdata *jd)
 
                /* move patcher function pointer onto stack */
 
-               disp = dseg_add_address(cd, pref->patcher);
+               disp = dseg_add_functionptr(cd, pref->patcher);
                M_ALD(REG_ITMP3, REG_PV, disp);
                M_AST(REG_ITMP3, REG_SP, JITSTACK + 0 * 8);
 
@@ -534,11 +534,12 @@ void emit_verbosecall_exit(jitdata *jd)
 
        M_DST(REG_FRESULT, REG_SP, JITSTACK);
 
-       disp = dseg_add_address(cd, m);
-       M_ALD(rd->argintregs[0], REG_PV_CALLEE, disp);
+       M_MOV(REG_RESULT_CALLEE, rd->argintregs[0]);
+       M_DMOV(REG_FRESULT, 1); /* logical dreg 1 => f2 */
+       M_FMOV(REG_FRESULT, 2); /* logical freg 2 => f5 */
 
-       M_MOV(REG_RESULT_CALLEE, rd->argintregs[1]);
-       M_DMOV(REG_FRESULT, 2); /* applies for flt and dbl values */
+       disp = dseg_add_functionptr(cd, m);
+       M_ALD(rd->argintregs[3], REG_PV_CALLEE, disp);
 
        disp = dseg_add_functionptr(cd, builtin_verbosecall_exit);
        M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
index 1f99e92dcfb4c7e056787249bad4e211b33cec32..393f196724e2b36db19101be088b7e8b7f9a092f 100644 (file)
@@ -771,15 +771,14 @@ bool patcher_clinit(u1 *sp)
 bool patcher_athrow_areturn(u1 *sp)
 {
        unresolved_class *uc;
-       classinfo        *c;
 
        /* get stuff from the stack */
 
        uc       = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
 
-       /* resolve the class */
+       /* resolve the class and check subtype constraints */
 
-       if (!resolve_class(uc, resolveEager, false, &c))
+       if (!resolve_class_eager_no_access_check(uc))
                return false;
 
        return true;
index a2eed3eb726d11596db814508b31de200bef1b05..5addbee442536233eca2141574f41226e4860fe8 100644 (file)
@@ -37,6 +37,8 @@
 #include <assert.h>
 #include <ucontext.h>
 
+#undef REG_SP
+
 #include "vm/types.h"
 
 #include "vm/jit/sparc64/md-abi.h"
@@ -69,12 +71,14 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
        _uc = (ucontext_t *) _p;
        _mc = &_uc->uc_mcontext;
 
-       instr = *((s4 *) (_mc->mc_gregs[MC_PC]));
+       instr = *((s4 *) (_mc->gregs[REG_PC]));
        /*addr = _mc->sc_regs[(instr >> 16) & 0x1f];*/
        addr = 0;
 
        if (addr == 0) {
-               pv  = (u1 *) _mc->mc_gregs[MC_G2];
+
+#if 0
+               pv  = (u1 *) _mc->gregs[REG_G3];
                sp  = (u1 *) _mc->mc_fp;
                ra  = (u1 *) _mc->mc_i7;       /* this is correct for leafs */
                xpc = (u1 *) _mc->mc_gregs[MC_PC];
@@ -84,6 +88,8 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 
                _mc->mc_gregs[MC_G5] = (ptrint) xpc;
                _mc->mc_gregs[MC_PC] = (ptrint) asm_handle_exception;
+#endif
+               assert(0);
 
        } else {
                addr += (long) ((instr << 16) >> 16);
index 14b18ac4f3f7233556db613f9b501abda4b327cf..004bf38725be7a11e51e6b2d94f59c8fbacda1bc 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: stack.c 7246 2007-01-29 18:49:05Z twisti $
+   $Id: stack.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -714,6 +714,9 @@ static void stack_merge_locals(stackdata_t *sd, basicblock *b)
                        if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
                                        && (sv->SBRSTART != dv->SBRSTART))
                        {
+#if defined(STACK_VERBOSE)
+                               printf("JSR MISMATCH: setting variable %d to VOID\n", i);
+#endif
                                dv->type = TYPE_VOID;
                                if (b->flags >= BBFINISHED)
                                        b->flags = BBTYPECHECK_REACHED;
@@ -4680,10 +4683,22 @@ icmd_BUILTIN:
 
        } while (sd.repeat && !deadcode);
 
-       /* reset locals of TYPE_RET to TYPE_ADR */
+    /* reset locals of TYPE_RET|VOID to TYPE_ADR */
+
+    /* A local variable may be used as both a returnAddress and a reference */
+    /* type variable, as we do not split variables between these types when */
+    /* renaming locals. While returnAddresses have been eliminated now, we  */
+    /* must assume that the variable is still used as TYPE_ADR.             */
+    /* The only way that a local can be TYPE_VOID at this point, is that it */
+    /* was a TYPE_RET variable for which incompatible returnAddresses were  */
+    /* merged. Thus we must treat TYPE_VOID in the same way as TYPE_RET     */
+    /* here.                                                                */
+    /* XXX: It would be nice to remove otherwise unused returnAddress       */
+    /*      variables from the local variable array, so they are not        */
+    /*      allocated by simplereg. (For LSRA this is not needed).          */
 
        for (i=0; i<sd.localcount; ++i) {
-               if (sd.var[i].type == TYPE_RET)
+               if (sd.var[i].type == TYPE_RET || sd.var[i].type == TYPE_VOID)
                        sd.var[i].type = TYPE_ADR;
        }
 
@@ -4851,8 +4866,12 @@ void stack_javalocals_store(instruction *iptr, s4 *javalocals)
 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
 {
        printf("%c", show_jit_type_letters[v->type]);
-       if (v->type == TYPE_RET)
+       if (v->type == TYPE_RET) {
                printf("{L%03d}", v->vv.retaddr->nr);
+#if defined(ENABLE_VERIFIER)
+               printf("{start=L%03d}", ((basicblock *)v->SBRSTART)->nr);
+#endif
+       }
 }
 
 
index f82f2ac3702221634686860262d98e53c35e2b6c..e71c032f3133d2c154551e0658d2133b0b195335 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: stacktrace.h 7396 2007-02-23 23:06:11Z michi $
+   $Id: stacktrace.h 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -191,6 +191,10 @@ void stacktrace_print_trace(java_objectheader *xptr);
 
 #if defined(ENABLE_JIT)
 u1 *md_stacktrace_get_returnaddress(u1 *sp, u4 framesize);
+# if defined(__SPARC_64__)
+u1 *md_get_framepointer(u1 *sp);
+u1 *md_get_pv_from_stackframe(u1 *sp);
+# endif
 #endif
 
 #if defined(ENABLE_INTRP)
index 4720feba3dba09f0c80ef97bebee15760b18e1c9..f73efc2ee011ee99034f4a5ee6f32060f695b05d 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: typecheck.c 7246 2007-01-29 18:49:05Z twisti $
+   $Id: typecheck.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -533,7 +533,6 @@ handle_basic_block(verifier_state *state)
 
        LOGSTR1("\n---- BLOCK %04d ------------------------------------------------\n",state->bptr->nr);
        LOGFLUSH;
-       DOLOG(show_basicblock(jd, state->bptr, SHOW_STACK));
 
        superblockend = false;
        state->bptr->flags = BBFINISHED;
@@ -556,6 +555,7 @@ handle_basic_block(verifier_state *state)
        /* init variable types at the start of this block */
        typevector_copy_inplace(state->bptr->inlocals, jd->var, state->numlocals);
 
+       DOLOG(show_basicblock(jd, state->bptr, SHOW_STACK));
        DOLOG(typecheck_print_vararray(stdout, jd, state->bptr->invars, 
                                state->bptr->indepth));
        DOLOG(typevector_print(stdout, jd->var, state->numlocals));
index 1c4caf0c94c17d6ed9c709e55f8269cb571a0f7c..58c11855a9a685dce63706918c68128196f31b6b 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: patcher.c 7297 2007-02-07 14:59:56Z twisti $
+   $Id: patcher.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -837,7 +837,6 @@ bool patcher_athrow_areturn(u1 *sp)
        u1               *ra;
        u8                mcode;
        unresolved_class *uc;
-       classinfo        *c;
 
        /* get stuff from the stack */
 
@@ -845,9 +844,9 @@ bool patcher_athrow_areturn(u1 *sp)
        mcode =                      *((u8 *)     (sp + 3 * 8));
        uc    = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
 
-       /* resolve the class */
+       /* resolve the class and check subtype constraints */
 
-       if (!resolve_class(uc, resolveEager, false, &c))
+       if (!resolve_class_eager_no_access_check(uc))
                return false;
 
        /* patch back original code */
index 10489e6a32cad8bce0297bff89e746b09962e41b..ca5ba1a57fce87fbd6a9ba6f7fe5b4b0d4426b9e 100644 (file)
@@ -1447,19 +1447,6 @@ bool vm_create(JavaVMInitArgs *vm_args)
        }
 #endif
 
-       /* Now re-set some of the properties that may have changed. This
-          must be done after _all_ environment variables have been
-          processes (e.g. -jar handling). */
-
-       if (!properties_postinit())
-               vm_abort("properties_postinit failed");
-
-       /* Now we have all options handled and we can print the version
-          information. */
-
-       if (opt_version)
-               version(opt_exit);
-
        /* initialize this JVM ****************************************************/
 
        vm_initializing = true;
@@ -1484,33 +1471,51 @@ bool vm_create(JavaVMInitArgs *vm_args)
        }
 #endif
 
-       /* initialize the string hashtable stuff: lock (must be done
-          _after_ threads_preinit) */
+       /* AFTER: threads_preinit */
 
        if (!string_init())
                throw_main_exception_exit();
 
-       /* initialize the utf8 hashtable stuff: lock, often used utf8
-          strings (must be done _after_ threads_preinit) */
+       /* AFTER: threads_preinit */
 
        if (!utf8_init())
                throw_main_exception_exit();
 
-       /* initialize the classcache hashtable stuff: lock, hashtable
-          (must be done _after_ threads_preinit) */
-
-       if (!classcache_init())
-               throw_main_exception_exit();
-
-       /* initialize the loader with bootclasspath (must be done _after_
-          thread_preinit) */
+       /* AFTER: thread_preinit */
 
        if (!suck_init())
                throw_main_exception_exit();
 
        suck_add_from_property("java.endorsed.dirs");
+
+       /* Now we have all options handled and we can print the version
+          information.
+
+          AFTER: suck_add_from_property("java.endorsed.dirs"); */
+
+       if (opt_version)
+               version(opt_exit);
+
+       /* AFTER: utf8_init */
+
        suck_add(_Jv_bootclasspath);
 
+       /* Now re-set some of the properties that may have changed. This
+          must be done after _all_ environment variables have been
+          processes (e.g. -jar handling).
+
+          AFTER: suck_add_from_property, since it may change the
+          _Jv_bootclasspath pointer. */
+
+       if (!properties_postinit())
+               vm_abort("properties_postinit failed");
+
+       /* initialize the classcache hashtable stuff: lock, hashtable
+          (must be done _after_ threads_preinit) */
+
+       if (!classcache_init())
+               throw_main_exception_exit();
+
        /* initialize the memory subsystem (must be done _after_
           threads_preinit) */
 
index c2d53ed455bfa0c3e9884667a7b5ed235edf3cb0..11a6669078b793583b96bea78ce96426e4fb214e 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: classcache.c 7246 2007-01-29 18:49:05Z twisti $
+   $Id: classcache.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -40,6 +40,7 @@
 #endif
 
 #include "toolbox/hashtable.h"
+#include "toolbox/logging.h"
 
 #include "vm/exceptions.h"
 
 /* DEBUG HELPERS                                                              */
 /*============================================================================*/
 
-/*#define CLASSCACHE_VERBOSE*/
+/* #define CLASSCACHE_VERBOSE */
 
 /*============================================================================*/
 /* STATISTICS                                                                 */
@@ -397,7 +398,7 @@ static void classcache_merge_class_entries(classcache_name_entry *en,
                utf_cat_classname(logbuffer, clsenA->classobj->name);
        if (clsenB->classobj)
                utf_cat_classname(logbuffer, clsenB->classobj->name);
-       log_text(logbuffer);
+       log_println(logbuffer);
 #endif
 
        CLASSCACHE_COUNT(stat_merge_class_entries);
@@ -760,7 +761,7 @@ classinfo *classcache_store(classloader *initloader, classinfo *cls,
        sprintf(logbuffer,"classcache_store (%p,%d,%p=", (void*)initloader,mayfree,(void*)cls);
        utf_cat_classname(logbuffer, cls->name);
        strcat(logbuffer,")");
-       log_text(logbuffer);
+       log_println(logbuffer);
 #endif
 
        en = classcache_new_name(cls->name);
@@ -777,7 +778,7 @@ classinfo *classcache_store(classloader *initloader, classinfo *cls,
                                        /* A class with the same (initloader,name) pair has been stored already. */
                                        /* We free the given class and return the earlier one.                   */
 #ifdef CLASSCACHE_VERBOSE
-                                       dolog("replacing %p with earlier loaded class %p",cls,clsen->classobj);
+                                       log_println("replacing %p with earlier loaded class %p",cls,clsen->classobj);
 #endif
                                        assert(clsen->classobj);
                                        if (mayfree)
@@ -863,7 +864,7 @@ classinfo *classcache_store(classloader *initloader, classinfo *cls,
 
   return_success:
 #ifdef CLASSCACHE_VERBOSE
-       classcache_debug_dump(stderr,cls->name);
+       classcache_debug_dump(stdout,cls->name);
 #endif
        CLASSCACHE_UNLOCK();
        return cls;
@@ -944,7 +945,7 @@ classinfo *classcache_store_defined(classinfo *cls)
        sprintf(logbuffer,"classcache_store_defined (%p,", (void*)cls->classloader);
        utf_cat_classname(logbuffer, cls->name);
        strcat(logbuffer,")");
-       log_text(logbuffer);
+       log_println(logbuffer);
 #endif
 
        en = classcache_new_name(cls->name);
@@ -960,7 +961,7 @@ classinfo *classcache_store_defined(classinfo *cls)
                        /* (if it is a different classinfo)                     */
                        if (clsen->classobj != cls) {
 #ifdef CLASSCACHE_VERBOSE
-                               dolog("replacing %p with earlier defined class %p",cls,clsen->classobj);
+                               log_println("replacing %p with earlier defined class %p",cls,clsen->classobj);
 #endif
                                class_free(cls);
                                cls = clsen->classobj;
@@ -983,7 +984,7 @@ classinfo *classcache_store_defined(classinfo *cls)
 
 return_success:
 #ifdef CLASSCACHE_VERBOSE
-       classcache_debug_dump(stderr,cls->name);
+       classcache_debug_dump(stdout,cls->name);
 #endif
        CLASSCACHE_UNLOCK();
        return cls;
@@ -1176,9 +1177,9 @@ bool classcache_add_constraint(classloader * a,
        assert(classname);
 
 #ifdef CLASSCACHE_VERBOSE
-       fprintf(stderr, "classcache_add_constraint(%p,%p,", (void *) a, (void *) b);
-       utf_fprint_printable_ascii_classname(stderr, classname);
-       fprintf(stderr, ")\n");
+       fprintf(stdout, "classcache_add_constraint(%p,%p,", (void *) a, (void *) b);
+       utf_fprint_printable_ascii_classname(stdout, classname);
+       fprintf(stdout, ")\n");
 #endif
 
        /* a constraint with a == b is trivially satisfied */
index e491a32fc905186afb949e8d013aa935cc684843..609d35cabc7d5f3eb667f091189daadc4f0d8a5d 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: resolve.c 7257 2007-01-29 23:07:40Z twisti $
+   $Id: resolve.c 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -265,7 +265,10 @@ bool resolve_classref(methodinfo *refmethod,
 /* resolve_classref_or_classinfo ***********************************************
  
    Resolve a symbolic class reference if necessary
-  
+
+   NOTE: If given, refmethod->class is used as the referring class.
+         Otherwise, cls.ref->referer is used.
+
    IN:
        refmethod........the method from which resolution was triggered
                         (may be NULL if not applicable)
@@ -299,6 +302,7 @@ bool resolve_classref_or_classinfo(methodinfo *refmethod,
                                                                   classinfo **result)
 {
        classinfo         *c;
+       classinfo         *referer;
        
        assert(cls.any);
        assert(mode == resolveEager || mode == resolveLazy);
@@ -315,7 +319,18 @@ bool resolve_classref_or_classinfo(methodinfo *refmethod,
        if (IS_CLASSREF(cls)) {
                /* we must resolve this reference */
 
-               if (!resolve_class_from_name(cls.ref->referer, refmethod, cls.ref->name,
+               /* determine which class to use as the referer */
+
+               /* Common cases are refmethod == NULL or both referring classes */
+               /* being the same, so the referer usually is cls.ref->referer.    */
+               /* There is one important case where it is not: When we do a      */
+               /* deferred assignability check to a formal argument of a method, */
+               /* we must use refmethod->class (the caller's class) to resolve   */
+               /* the type of the formal argument.                               */
+
+               referer = (refmethod) ? refmethod->class : cls.ref->referer;
+
+               if (!resolve_class_from_name(referer, refmethod, cls.ref->name,
                                                                         mode, checkaccess, link, &c))
                        goto return_exception;
 
@@ -936,6 +951,32 @@ classinfo * resolve_class_eager(unresolved_class *ref)
 }
 #endif /* ENABLE_VERIFIER */
 
+/* resolve_class_eager_no_access_check *****************************************
+   Resolve an unresolved class reference eagerly. The class is also linked.
+   Access rights are _not_ checked.
+  
+   IN:
+       ref..............struct containing the reference
+   
+   RETURN VALUE:
+       classinfo * to the class, or
+          NULL if an exception has been thrown
+   
+*******************************************************************************/
+
+#ifdef ENABLE_VERIFIER
+classinfo * resolve_class_eager_no_access_check(unresolved_class *ref)
+{
+       classinfo *c;
+
+       if (!resolve_class(ref, resolveEager, false, &c))
+               return NULL;
+
+       return c;
+}
+#endif /* ENABLE_VERIFIER */
+
 /******************************************************************************/
 /* FIELD RESOLUTION                                                           */
 /******************************************************************************/
index 2f49a2efc443c3dcfc9f562463f1729d52ced16f..e7dee5a4aafb43e132b376daaedd1beb4e6bc7e5 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: resolve.h 7246 2007-01-29 18:49:05Z twisti $
+   $Id: resolve.h 7441 2007-03-02 23:13:10Z michi $
 
 */
 
@@ -148,6 +148,7 @@ bool resolve_class(unresolved_class *ref,
                          classinfo **result);
 
 classinfo * resolve_class_eager(unresolved_class *ref);
+classinfo * resolve_class_eager_no_access_check(unresolved_class *ref);
 #endif /* ENABLE_VERIFIER */
 
 bool resolve_field(unresolved_field *ref,
index 4efeff1f6407a1976c12493c8e75025bd0ecb306..6a32c19c729b5aecb32c238a3df6d7dff52d5ce3 100644 (file)
 ##
 ## Authors: Christian Thalinger
 ##
-## $Id: Makefile.am 6266 2007-01-02 20:49:34Z twisti $
+## $Id: Makefile.am 7441 2007-03-02 23:13:10Z michi $
 
 ## Process this file with automake to produce Makefile.in
 
 SUBDIRS = \
        codepatching \
        jasmin \
-       native
+       native \
+       resolving
 
 JAVA      = $(top_builddir)/src/cacao/cacao
 
index 25e7be3ed72284998edaa4b1aa9c3a29772e538c..9582aafcd7c6a68b0cc43039c9ee13145ee9b292 100644 (file)
@@ -124,6 +124,7 @@ JASMIN_TESTS = \
        $(srcdir)/test_verify_ok_jsr_subroutine_loops_to_start.j \
        $(srcdir)/test_verify_ok_jsr_swap.j \
        $(srcdir)/test_verify_ok_jsr_through_variable.j \
+       $(srcdir)/test_verify_ok_local_as_retaddr_and_reference.j \
        $(srcdir)/test_verify_ok_overwrite_local_type.j \
        $(srcdir)/test_verify_ok_untyped_local.j \
        $(srcdir)/test_verify_unspecced_ok_backward_with_new_in_local.j \
diff --git a/tests/regression/jasmin/test_verify_ok_local_as_retaddr_and_reference.j b/tests/regression/jasmin/test_verify_ok_local_as_retaddr_and_reference.j
new file mode 100644 (file)
index 0000000..5e42c67
--- /dev/null
@@ -0,0 +1,91 @@
+.class public test_verify_ok_local_as_retaddr_and_reference
+.super java/lang/Object
+
+; ======================================================================
+
+.method public <init>()V
+   aload_0
+   invokenonvirtual java/lang/Object/<init>()V
+   return
+.end method
+
+; ======================================================================
+
+.method public static check(I)V
+       .limit locals 1
+       .limit stack 10
+       getstatic java/lang/System/out Ljava/io/PrintStream;
+       iload_0
+       invokevirtual java/io/PrintStream/println(I)V
+       return
+.end method
+
+; ======================================================================
+
+.method public static main([Ljava/lang/String;)V
+       .limit stack 2
+       .limit locals 3
+
+       ldc 35
+       istore 1
+
+       ; --------------------------------------------------
+
+       ; load local 2 with a reference to a string
+    ldc "foo"
+       astore 2
+
+       ; perform some bogus instructions
+       aload 0
+       ifnull branch_a
+
+       nop
+branch_a:
+
+    ; use the string in local 2
+       getstatic java/lang/System/out Ljava/io/PrintStream;
+       aload_2
+       invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
+       ; OUTPUT: foo
+
+       ; --------------------------------------------------
+
+       aload 0
+       ifnull branch_b
+
+       jsr sbr_1
+       goto merge_point
+       ; OUTPUT: 35
+
+branch_b:
+       jsr sbr_2
+       goto merge_point
+
+merge_point:
+    ; here local 2 becomes VOID, as two incompatible returnAddresses
+       ; are merged
+
+       ; --------------------------------------------------
+
+force_basic_block_boundary:
+
+       iload 1
+       invokestatic test_verify_ok_local_as_retaddr_and_reference/check(I)V
+       ; OUTPUT: 35
+
+       return
+
+sbr_1:
+       astore 2
+       iload 1
+       invokestatic test_verify_ok_local_as_retaddr_and_reference/check(I)V
+       ret 2
+
+sbr_2:
+       astore 2
+       ldc 42
+       invokestatic test_verify_ok_local_as_retaddr_and_reference/check(I)V
+       ret 2
+
+.end method
+
diff --git a/tests/regression/resolving/Makefile.am b/tests/regression/resolving/Makefile.am
new file mode 100644 (file)
index 0000000..6d6dbf0
--- /dev/null
@@ -0,0 +1,48 @@
+SUBDIRS = \
+    classes1 \
+       classes2 \
+       classes3
+
+HARNESS_SOURCE_FILES = \
+       TestController.java \
+       TestLoader.java
+
+HARNESS_CLASS_FILES = \
+       TestController.class \
+       TestLoader.class
+
+TEST_SOURCE_FILES = \
+       test_instance_subtype_violated.java \
+       test_param_loading_constraint_violated_derived.java \
+       test_param_loading_constraint_violated.java \
+       test_param_subtype_violated.java \
+       test_retval_loading_constraint_violated.java \
+       test_simple_lazy_load.java
+
+TEST_NAMES = \
+       test_instance_subtype_violated \
+       test_param_loading_constraint_violated_derived \
+       test_param_loading_constraint_violated \
+       test_param_subtype_violated \
+       test_retval_loading_constraint_violated \
+       test_simple_lazy_load
+
+EXTRA_DIST = $(HARNESS_SOURCE_FILES) $(TEST_SOURCE_FILES)
+
+CLEANFILES = \
+       *.class
+
+JAVA      = $(top_builddir)/src/cacao/cacao
+
+if WITH_CLASSPATH_GNU
+JAVAFLAGS = -Xbootclasspath:$(top_builddir)/src/lib/classes/:$(CLASSPATH_CLASSES)
+else
+JAVAFLAGS = -Xbootclasspath:$(CLASSPATH_CLASSES)
+endif
+
+check: $(HARNESS_CLASS_FILES)
+       for t in $(TEST_NAMES) ; do echo "TEST $$t" ; { $(JAVAC) $$t.java && $(JAVA) $$t ; } || exit 1 ; done
+
+$(HARNESS_CLASS_FILES): $(HARNESS_SOURCE_FILES)
+       $(JAVAC) $(HARNESS_SOURCE_FILES)
+
diff --git a/tests/regression/resolving/TestController.java b/tests/regression/resolving/TestController.java
new file mode 100644 (file)
index 0000000..478482c
--- /dev/null
@@ -0,0 +1,273 @@
+import java.util.Vector;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+public class TestController {
+
+    boolean report_class_ids_ = false;
+    Vector expectations_ = new Vector();
+    boolean failed_ = false;
+
+    class Expectation {
+        String tag_;
+        String loader1_;
+        String loader2_;
+        String class_;
+
+        public Expectation(String tag, String ld1, String ld2, String cls) {
+            tag_ = tag;
+            loader1_ = ld1;
+            loader2_ = ld2;
+            class_ = cls;
+        }
+
+        public Expectation(String tag, String ld1, String cls) {
+            this(tag, ld1, null, cls);
+        }
+
+        public boolean matches(String tag, String ld1, String ld2, String cls) {
+            return tag_.equals(tag)
+                && loader1_.equals(ld1)
+                && ((loader2_ == ld2) || ((loader2_ != null) && (ld2 != null) && loader2_.equals(ld2)))
+                && class_.equals(cls);
+        }
+    }
+
+    public void setReportClassIDs(boolean rep) {
+        report_class_ids_ = rep;
+    }
+
+    void expect(Expectation exp) {
+        expectations_.add(exp);
+    }
+
+    void expect(String tag, String loader, String classname) {
+        expect(new Expectation(tag, loader, classname));
+    }
+
+    void expect(String tag, String loader1, String loader2, String classname) {
+        expect(new Expectation(tag, loader1, loader2, classname));
+    }
+
+    public void expect(String tag, ClassLoader loader, String classname) {
+        expect(tag, loaderName(loader), classname);
+    }
+
+    public void expect(String tag, ClassLoader loader1, ClassLoader loader2, String classname) {
+        expect(tag, loaderName(loader1), loaderName(loader2), classname);
+    }
+
+    public void expectLoadFromSystem(ClassLoader loader, String classname) {
+        expect("requested", loader, classname);
+        expect("delegated", loader, ClassLoader.getSystemClassLoader(), classname);
+        expect("loaded", loader, "<" + classname + ">");
+    }
+
+    public void expectDelegationAndDefinition(ClassLoader loader1, ClassLoader loader2, String classname) {
+        expect("requested", loader1, classname);
+        expect("delegated", loader1, loader2, classname);
+        expect("requested", loader2, classname);
+        expect("defined", loader2, "<" + classname + ">");
+        expect("loaded", loader1, "<" + classname + ">");
+    }
+
+    public void expectDelegationAndFound(ClassLoader loader1, ClassLoader loader2, String classname) {
+        expect("requested", loader1, classname);
+        expect("delegated", loader1, loader2, classname);
+        expect("requested", loader2, classname);
+        expect("found", loader2, "<" + classname + ">");
+        expect("loaded", loader1, "<" + classname + ">");
+    }
+
+    void fail(String message) {
+        log("FAIL: " + message);
+        failed_ = true;
+    }
+
+    void ok(String message) {
+        log("ok: " + message);
+    }
+
+    void fail(String message, String tag, String ld1, String ld2, String cls) {
+        fail(message + ": " + tag + " " + ld1 + " " + ld2 + " class=" + cls);
+    }
+
+    void ok(String tag, String ld1, String ld2, String cls) {
+        ok(tag + " " + ld1 + " " + ld2 + " class=" + cls);
+    }
+
+    public void expectEnd() {
+        if (expectations_.size() != 0)
+            fail("missing reports");
+        else
+            ok("got all expected reports");
+    }
+
+    public void checkStringGetter(Class cls, String methodname, String expected) {
+        String id = invokeStringGetter(cls, methodname);
+        if (id == null)
+            fail("could not get return value of " + methodname + "()");
+        else if (id.equals(expected))
+            ok("returned string matches: " + id);
+        else
+            fail("wrong string returned: " + id + ", expected: " + expected);
+    }
+
+    public void checkStringGetterMustFail(Class cls, String methodname) {
+        String id = invokeStringGetter(cls, methodname);
+        if (id == null)
+            ok("method invocation failed as expected: " + methodname + "()");
+        else 
+            fail("method invocation did not fail as expected: " + methodname + "()");
+    }
+
+    public void checkClassId(Class cls, String expected) {
+        String id = getClassId(cls);
+        if (id == null)
+            fail("could not get class id");
+        else if (id.equals(expected))
+            ok("class id matches: " + id);
+        else
+            fail("wrong class id: " + id + ", expected: " + expected);
+    }
+
+    public synchronized void match(String tag, String ld1, String ld2, String cls) {
+        if (expectations_.size() == 0) {
+            fail("unexpected", tag, ld1, ld2, cls);
+        }
+        else {
+            Expectation exp = (Expectation) expectations_.firstElement();
+
+            if (exp.matches(tag, ld1, ld2, cls)) {
+                expectations_.remove(0);
+                ok(tag, ld1, ld2, cls);
+            }
+            else {
+                fail("unexpected", tag, ld1, ld2, cls);
+            }
+        }
+    }
+
+    void report(String tag, String loader, String classname) {
+        match(tag, loader, null, classname);
+    }
+
+    void report(String tag, String loader1, String loader2, String classname) {
+        match(tag, loader1, loader2, classname);
+    }
+
+    void report(String tag, ClassLoader loader, String classname) {
+        report(tag, loaderName(loader), classname);
+    }
+
+    void report(String tag, ClassLoader loader, Class cls) {
+        report(tag, loaderName(loader), className(cls));
+    }
+
+    void report(String tag, ClassLoader loader1, ClassLoader loader2, String classname) {
+        report(tag, loaderName(loader1), loaderName(loader2), classname);
+    }
+
+    public void reportRequest(ClassLoader loader, String classname) {
+        report("requested", loader, classname);
+    }
+
+    public void reportUnexpectedClassRequested(ClassLoader loader, String classname) {
+        report("unexpected class requested", loader, classname);
+    }
+
+    public void reportDelegation(ClassLoader loader, ClassLoader delegate, String classname) {
+        report("delegated", loaderName(loader), loaderName(delegate), classname);
+    }
+
+    public void reportDefinition(ClassLoader loader, Class cls) {
+        report("defined", loaderName(loader), className(cls));
+    }
+
+    public void reportFoundLoaded(ClassLoader loader, Class cls) {
+        report("found", loaderName(loader), className(cls));
+    }
+
+    public void reportLoaded(ClassLoader loader, Class cls) {
+        report("loaded", loaderName(loader), className(cls));
+    }
+
+    public void reportClassNotFound(ClassLoader loader, String classname, ClassNotFoundException e) {
+        report("class not found", loaderName(loader), classname);
+    }
+
+    public void reportException(Class cls, Throwable ex) {
+        report("exception", ex.getClass().getName(), className(cls));
+        log("exception was: " + ex);
+        // ex.printStackTrace(System.out);
+    }
+
+    public Class loadClass(ClassLoader loader, String classname) {
+        try {
+            Class cls = loader.loadClass(classname);
+
+            reportLoaded(loader, cls);
+
+            return cls;
+        }
+        catch (ClassNotFoundException e) {
+            reportClassNotFound(loader, classname, e);
+        }
+
+        return null;
+    }
+
+    public void log(String str) {
+        System.out.println(str);
+    }
+
+    public String loaderName(ClassLoader loader) {
+        if (loader == ClassLoader.getSystemClassLoader())
+            return "<SystemClassLoader>";
+
+        return (loader == null) ? "<null>" : loader.toString();
+    }
+
+    public String invokeStringGetter(Class cls, String methodname) {
+        try {
+            Method mid = cls.getMethod(methodname, null);
+
+            String id = (String) mid.invoke(null, null);
+
+            return id;
+        }
+        catch (NoSuchMethodException e) {
+            return null;
+        }
+        catch (InvocationTargetException e) {
+            reportException(cls, e.getCause());
+            return null;
+        }
+        catch (Exception e) {
+            reportException(cls, e);
+            return null;
+        }
+    }
+
+    public String getClassId(Class cls) {
+        return invokeStringGetter(cls, "id");
+    }
+
+    public String className(Class cls) {
+        if (report_class_ids_) {
+            String id = getClassId(cls);
+            if (id != null)
+                return "<" + cls.getName() + ":" + id + ">";
+        }
+
+        return "<" + cls.getName() + ">";
+    }
+
+    public void exit() {
+        expectEnd();
+        System.exit(failed_ ? 1 : 0);
+    }
+
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/TestLoader.java b/tests/regression/resolving/TestLoader.java
new file mode 100644 (file)
index 0000000..157eef8
--- /dev/null
@@ -0,0 +1,123 @@
+import java.util.Hashtable;
+import java.io.*;
+
+public class TestLoader extends ClassLoader {
+
+    Hashtable registry_;
+    String name_;
+    TestController controller_;
+
+    class Entry {
+    }
+
+    class ClassfileEntry extends Entry {
+        public String filename_;
+        public ClassfileEntry(String filename) { filename_ = filename; }
+    }
+
+    class DelegationEntry extends Entry {
+        public ClassLoader loader_;
+        public DelegationEntry(ClassLoader loader) { loader_ = loader; }
+    }
+
+    class SuperDelegationEntry extends Entry {
+    }
+
+    public TestLoader(ClassLoader parent, String name, TestController controller) {
+        super(parent);
+        name_ = name;
+        controller_ = controller;
+        registry_ = new Hashtable();
+    }
+
+    public void addClassfile(String classname, String filename) {
+        registry_.put(classname, new ClassfileEntry(filename));
+    }
+
+    public void addDelegation(String classname, ClassLoader loader) {
+        registry_.put(classname, new DelegationEntry(loader));
+    }
+
+    public void addParentDelegation(String classname) {
+        registry_.put(classname, new DelegationEntry(getParent()));
+    }
+
+    public void addSuperDelegation(String classname) {
+        registry_.put(classname, new SuperDelegationEntry());
+    }
+
+    public String toString() {
+        return "TestLoader<" + name_ + ">";
+    }
+
+    public Class loadClass(String classname) throws ClassNotFoundException {
+        controller_.reportRequest(this, classname);
+
+        Entry entry = (Entry) registry_.get(classname);
+
+        if (entry == null) {
+            controller_.reportUnexpectedClassRequested(this, classname);
+            throw new ClassNotFoundException(this + " does not know how to load class " + classname);
+        }
+
+        if (entry instanceof ClassfileEntry) {
+            Class cls = findLoadedClass(classname);
+
+            if (cls != null) {
+                controller_.reportFoundLoaded(this, cls);
+                return cls;
+            }
+
+            String filename = ((ClassfileEntry)entry).filename_;
+
+            try {
+                byte[] bytes = slurpFile(filename);
+
+                cls = defineClass(classname, bytes, 0, bytes.length);
+
+                controller_.reportDefinition(this, cls);
+
+                return cls;
+            }
+            catch (Exception e) {
+                throw new ClassNotFoundException(e.toString());
+            }
+        }
+        else if (entry instanceof DelegationEntry) {
+            ClassLoader delegate = ((DelegationEntry)entry).loader_;
+
+            controller_.reportDelegation(this, delegate, classname);
+
+            Class cls = delegate.loadClass(classname);
+
+            controller_.reportLoaded(this, cls);
+
+            return cls;
+        }
+
+        throw new ClassNotFoundException("unknown TestLoader entry: " + entry);
+    }
+
+    byte[] slurpFile(String filename) throws IOException {
+        File file = new File(filename);
+        InputStream is = new FileInputStream(file);
+        long len = file.length();
+        if (len > Integer.MAX_VALUE)
+            throw new IOException("file " + file.getName() + " is too large");
+        byte[] bytes = new byte[(int) len];
+
+        int ofs = 0;
+        int read = 0;
+        while ((ofs < len) && (read = is.read(bytes, ofs, bytes.length - ofs)) >= 0)
+            ofs += read;
+
+        if (ofs < len)
+            throw new IOException("error reading file " + file.getName());
+
+        is.close();
+        return bytes;
+    }
+}
+
+// vim: et sw=4
+
diff --git a/tests/regression/resolving/classes1/BarPassFoo.java b/tests/regression/resolving/classes1/BarPassFoo.java
new file mode 100644 (file)
index 0000000..b5aba27
--- /dev/null
@@ -0,0 +1,11 @@
+public class BarPassFoo {
+    public static String id() {
+        return "classes1/BarPassFoo";
+    }
+
+    public Foo createFoo() {
+        return null;
+    }
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/classes1/BarUseFoo.java b/tests/regression/resolving/classes1/BarUseFoo.java
new file mode 100644 (file)
index 0000000..df1923b
--- /dev/null
@@ -0,0 +1,22 @@
+public class BarUseFoo {
+    public static String id() {
+        return "classes1/BarUseFoo";
+    }
+
+    public static String idOfFoo() {
+        return Foo.id();
+    }
+
+    public String useFoo(Foo foo) {
+        return foo.virtualId();
+    }
+
+    public static String useReturnedFoo() {
+        BarPassFoo bpf = new BarPassFoo();
+        Foo foo = bpf.createFoo();
+        return foo.virtualId();
+    }
+}
+
+// vim: et sw=4
+
diff --git a/tests/regression/resolving/classes1/Foo.java b/tests/regression/resolving/classes1/Foo.java
new file mode 100644 (file)
index 0000000..3510eb5
--- /dev/null
@@ -0,0 +1,11 @@
+public class Foo {
+    public static String id() {
+        return "classes1/Foo";
+    }
+
+    public String virtualId() {
+        return id();
+    }
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/classes1/Makefile.am b/tests/regression/resolving/classes1/Makefile.am
new file mode 100644 (file)
index 0000000..320cd8b
--- /dev/null
@@ -0,0 +1,20 @@
+SOURCE_FILES = \
+       BarPassFoo.java \
+       BarUseFoo.java \
+       Foo.java
+
+CLASS_FILES = \
+       BarPassFoo.class \
+       BarUseFoo.class \
+       Foo.class
+
+EXTRA_DIST = $(SOURCE_FILES)
+
+CLEANFILES = \
+       *.class
+
+check: $(CLASS_FILES)
+
+$(CLASS_FILES): $(SOURCE_FILES)
+       $(JAVAC) $(SOURCE_FILES)
+
diff --git a/tests/regression/resolving/classes2/BarPassFoo.java b/tests/regression/resolving/classes2/BarPassFoo.java
new file mode 100644 (file)
index 0000000..23c02c1
--- /dev/null
@@ -0,0 +1,31 @@
+public class BarPassFoo {
+    public static String id() {
+        return "classes2/BarPassFoo";
+    }
+
+    public static String passit() {
+        Foo foo = new Foo();
+        BarUseFoo bar = new BarUseFoo();
+
+        return bar.useFoo(foo);
+    }
+
+    public static String passDerivedFoo() {
+        DerivedFoo dfoo = new DerivedFoo();
+        BarUseFoo bar = new BarUseFoo();
+
+        return bar.useFoo(dfoo);
+    }
+
+    public static String passDerivedFooInstance() {
+        Foo foo = new DerivedFoo();
+
+        return foo.virtualId();
+    }
+
+    public Foo createFoo() {
+        return new Foo();
+    }
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/classes2/BarUseFoo.java b/tests/regression/resolving/classes2/BarUseFoo.java
new file mode 100644 (file)
index 0000000..4b49c25
--- /dev/null
@@ -0,0 +1,16 @@
+public class BarUseFoo {
+    public static String id() {
+        return "classes2/BarUseFoo";
+    }
+
+    public static String idOfFoo() {
+        return Foo.id();
+    }
+
+    public String useFoo(Foo foo) {
+        return "not implemented";
+    }
+}
+
+// vim: et sw=4
+
diff --git a/tests/regression/resolving/classes2/DerivedFoo.java b/tests/regression/resolving/classes2/DerivedFoo.java
new file mode 100644 (file)
index 0000000..8eb6c96
--- /dev/null
@@ -0,0 +1,7 @@
+public class DerivedFoo extends Foo {
+    public static String id() {
+        return "classes2/DerivedFoo";
+    }
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/classes2/Foo.java b/tests/regression/resolving/classes2/Foo.java
new file mode 100644 (file)
index 0000000..c091ec4
--- /dev/null
@@ -0,0 +1,11 @@
+public class Foo {
+    public static String id() {
+        return "classes2/Foo";
+    }
+
+    public String virtualId() {
+        return id();
+    }
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/classes2/Makefile.am b/tests/regression/resolving/classes2/Makefile.am
new file mode 100644 (file)
index 0000000..dc89ae4
--- /dev/null
@@ -0,0 +1,23 @@
+SOURCE_FILES = \
+       BarPassFoo.java \
+       BarUseFoo.java \
+       DerivedFoo.java \
+       Foo.java
+
+CLASS_FILES = \
+       BarPassFoo.class \
+       BarUseFoo.class \
+       DerivedFoo.class \
+       Foo.class
+
+EXTRA_DIST = $(SOURCE_FILES)
+
+CLEANFILES = \
+       *.class
+
+check: $(CLASS_FILES)
+
+$(CLASS_FILES): $(SOURCE_FILES)
+       $(JAVAC) $(SOURCE_FILES)
+
+
diff --git a/tests/regression/resolving/classes3/BarPassFoo.java b/tests/regression/resolving/classes3/BarPassFoo.java
new file mode 100644 (file)
index 0000000..0457cee
--- /dev/null
@@ -0,0 +1,21 @@
+public class BarPassFoo {
+    public static String id() {
+        return "classes3/BarPassFoo";
+    }
+
+    public static String passit() {
+        Foo foo = new Foo();
+        BarUseFoo bar = new BarUseFoo();
+
+        return bar.useFoo(foo);
+    }
+
+    public static String passDerivedFoo() {
+        DerivedFoo dfoo = new DerivedFoo();
+        BarUseFoo bar = new BarUseFoo();
+
+        return bar.useFoo(dfoo);
+    }
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/classes3/BarUseFoo.java b/tests/regression/resolving/classes3/BarUseFoo.java
new file mode 100644 (file)
index 0000000..144c1aa
--- /dev/null
@@ -0,0 +1,16 @@
+public class BarUseFoo {
+    public static String id() {
+        return "classes3/BarUseFoo";
+    }
+
+    public static String idOfFoo() {
+        return Foo.id();
+    }
+
+    public String useFoo(Foo foo) {
+        return "not implemented";
+    }
+}
+
+// vim: et sw=4
+
diff --git a/tests/regression/resolving/classes3/DerivedFoo.java b/tests/regression/resolving/classes3/DerivedFoo.java
new file mode 100644 (file)
index 0000000..01ed83f
--- /dev/null
@@ -0,0 +1,7 @@
+public class DerivedFoo extends Foo {
+    public static String id() {
+        return "classes3/DerivedFoo";
+    }
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/classes3/Foo.java b/tests/regression/resolving/classes3/Foo.java
new file mode 100644 (file)
index 0000000..5702b2d
--- /dev/null
@@ -0,0 +1,11 @@
+public class Foo {
+    public static String id() {
+        return "classes3/Foo";
+    }
+
+    public String virtualId() {
+        return "not implemented";
+    }
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/classes3/Makefile.am b/tests/regression/resolving/classes3/Makefile.am
new file mode 100644 (file)
index 0000000..dc89ae4
--- /dev/null
@@ -0,0 +1,23 @@
+SOURCE_FILES = \
+       BarPassFoo.java \
+       BarUseFoo.java \
+       DerivedFoo.java \
+       Foo.java
+
+CLASS_FILES = \
+       BarPassFoo.class \
+       BarUseFoo.class \
+       DerivedFoo.class \
+       Foo.class
+
+EXTRA_DIST = $(SOURCE_FILES)
+
+CLEANFILES = \
+       *.class
+
+check: $(CLASS_FILES)
+
+$(CLASS_FILES): $(SOURCE_FILES)
+       $(JAVAC) $(SOURCE_FILES)
+
+
diff --git a/tests/regression/resolving/test_instance_subtype_violated.java b/tests/regression/resolving/test_instance_subtype_violated.java
new file mode 100644 (file)
index 0000000..875dd9d
--- /dev/null
@@ -0,0 +1,62 @@
+public class test_instance_subtype_violated {
+
+    public static void main(String[] args) {
+        TestController ct = new TestController();
+
+        TestLoader ld1 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld1", ct);
+        TestLoader ld2 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld2", ct);
+        TestLoader ld3 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld3", ct);
+
+        ld1.addClassfile("BarUseFoo", "classes1/BarUseFoo.class");
+        ld1.addClassfile("Foo", "classes1/Foo.class");
+        ld1.addParentDelegation("java.lang.Object");
+        ld1.addParentDelegation("java.lang.String");
+
+        ld2.addClassfile("BarPassFoo", "classes2/BarPassFoo.class");
+        ld2.addDelegation("BarUseFoo", ld1);
+        ld2.addDelegation("Foo", ld1);
+        ld2.addDelegation("DerivedFoo", ld3);
+        ld2.addParentDelegation("java.lang.Object");
+        ld2.addParentDelegation("java.lang.String");
+
+        ld3.addClassfile("Foo", "classes3/Foo.class");
+        ld3.addClassfile("DerivedFoo", "classes3/DerivedFoo.class");
+        ld3.addParentDelegation("java.lang.Object");
+        ld3.addParentDelegation("java.lang.String");
+
+
+        // loading BarPassFoo
+        ct.expect("requested", ld2, "BarPassFoo");
+        ct.expect("defined", ld2, "<BarPassFoo>");
+        ct.expect("loaded", ld2, "<BarPassFoo>");
+
+        Class cls = ct.loadClass(ld2, "BarPassFoo");
+
+        // linking BarPassFoo
+        ct.expectLoadFromSystem(ld2, "java.lang.Object");
+
+        // executing BarPassFoo.passDerivedFooInstance: new DerivedFoo
+        ct.expectDelegationAndDefinition(ld2, ld3, "DerivedFoo");
+
+        // linking (ld3, DerivedFoo)
+        ct.expect("requested", ld3, "Foo");
+        ct.expect("defined", ld3, "<Foo>");
+        ct.expectLoadFromSystem(ld3, "java.lang.Object");
+
+        // resolving Foo.virtualId
+        // the deferred subtype check ((ld2, DerivedFoo) subtypeof (ld2, Foo)) is done
+        ct.expectDelegationAndDefinition(ld2, ld1, "Foo");
+        // ...linking (ld2, Foo) == (ld1, Foo)
+        ct.expectLoadFromSystem(ld1, "java.lang.Object");
+
+        // the subtype constraint ((ld2, DerivedFoo) subtypeof (ld2, Foo)) is violated
+        ct.expect("exception", "java.lang.LinkageError", "<BarPassFoo>");
+
+        ct.checkStringGetterMustFail(cls, "passDerivedFooInstance");
+
+        ct.exit();
+    }
+
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/test_param_loading_constraint_violated.java b/tests/regression/resolving/test_param_loading_constraint_violated.java
new file mode 100644 (file)
index 0000000..e4c734b
--- /dev/null
@@ -0,0 +1,53 @@
+public class test_param_loading_constraint_violated {
+
+    public static void main(String[] args) {
+        TestController ct = new TestController();
+
+        TestLoader ld1 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld1", ct);
+        TestLoader ld2 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld2", ct);
+
+        ld1.addClassfile("BarUseFoo", "classes1/BarUseFoo.class");
+        ld1.addClassfile("Foo", "classes1/Foo.class");
+        ld1.addParentDelegation("java.lang.Object");
+        ld1.addParentDelegation("java.lang.String");
+
+        ld2.addClassfile("BarPassFoo", "classes2/BarPassFoo.class");
+        ld2.addClassfile("Foo", "classes2/Foo.class");
+        ld2.addDelegation("BarUseFoo", ld1);
+        ld2.addParentDelegation("java.lang.Object");
+        ld2.addParentDelegation("java.lang.String");
+
+
+        // loading BarPassFoo
+        ct.expect("requested", ld2, "BarPassFoo");
+        ct.expect("defined", ld2, "<BarPassFoo>");
+        ct.expect("loaded", ld2, "<BarPassFoo>");
+
+        Class cls = ct.loadClass(ld2, "BarPassFoo");
+
+        // linking BarPassFoo
+        ct.expectLoadFromSystem(ld2, "java.lang.Object");
+
+        // executing BarPassFoo.passit: new Foo
+        ct.expect("requested", ld2, "Foo");
+        ct.expect("defined", ld2, "<Foo>");
+
+        // executing BarPassFoo.passit: new BarUseFoo
+        ct.expectDelegationAndDefinition(ld2, ld1, "BarUseFoo");
+        // ...linking BarUseFoo
+        ct.expectLoadFromSystem(ld1, "java.lang.Object");
+
+        // resolving Foo.virtualId() from BarUseFoo
+        ct.expect("requested", ld1, "Foo");
+
+        // the loading constraing (ld1,ld2,Foo) is violated
+        ct.expect("exception", "java.lang.LinkageError", "<BarPassFoo>");
+
+        ct.checkStringGetterMustFail(cls, "passit");
+
+        ct.exit();
+    }
+
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/test_param_loading_constraint_violated_derived.java b/tests/regression/resolving/test_param_loading_constraint_violated_derived.java
new file mode 100644 (file)
index 0000000..8ed0ec8
--- /dev/null
@@ -0,0 +1,69 @@
+public class test_param_loading_constraint_violated_derived {
+
+    public static void main(String[] args) {
+        TestController ct = new TestController();
+
+        TestLoader ld1 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld1", ct);
+        TestLoader ld2 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld2", ct);
+        TestLoader ld3 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld3", ct);
+
+        ld1.addClassfile("BarUseFoo", "classes1/BarUseFoo.class");
+        ld1.addClassfile("Foo", "classes1/Foo.class");
+        ld1.addParentDelegation("java.lang.Object");
+        ld1.addParentDelegation("java.lang.String");
+
+        ld2.addClassfile("BarPassFoo", "classes2/BarPassFoo.class");
+        ld2.addDelegation("BarUseFoo", ld1);
+        ld2.addDelegation("Foo", ld3);
+        ld2.addDelegation("DerivedFoo", ld3);
+        ld2.addParentDelegation("java.lang.Object");
+        ld2.addParentDelegation("java.lang.String");
+
+        ld3.addClassfile("Foo", "classes3/Foo.class");
+        ld3.addClassfile("DerivedFoo", "classes3/DerivedFoo.class");
+        ld3.addParentDelegation("java.lang.Object");
+        ld3.addParentDelegation("java.lang.String");
+
+
+        // loading BarPassFoo
+        ct.expect("requested", ld2, "BarPassFoo");
+        ct.expect("defined", ld2, "<BarPassFoo>");
+        ct.expect("loaded", ld2, "<BarPassFoo>");
+
+        Class cls = ct.loadClass(ld2, "BarPassFoo");
+
+        // linking BarPassFoo
+        ct.expectLoadFromSystem(ld2, "java.lang.Object");
+
+        // executing BarPassFoo.passDerivedFoo: new DerivedFoo
+        ct.expectDelegationAndDefinition(ld2, ld3, "DerivedFoo");
+
+        // linking (ld3, DerivedFoo)
+        ct.expect("requested", ld3, "Foo");
+        ct.expect("defined", ld3, "<Foo>");
+        ct.expectLoadFromSystem(ld3, "java.lang.Object");
+
+        // executing BarPassFoo.passit: new BarUseFoo
+        ct.expectDelegationAndDefinition(ld2, ld1, "BarUseFoo");
+
+        // linking BarUseFoo
+        ct.expectLoadFromSystem(ld1, "java.lang.Object");
+
+        // resolving BarUseFoo.useFoo
+        // the deferred subtype check ((ld2, DerivedFoo) subtypeof (ld2, Foo)) is done
+        ct.expectDelegationAndFound(ld2, ld3, "Foo");
+
+        // resolving Foo.virtualId() from BarUseFoo
+        ct.expect("requested", ld1, "Foo");
+
+        // the loading constraint (ld1,ld2,Foo) is violated
+        ct.expect("exception", "java.lang.LinkageError", "<BarPassFoo>");
+
+        ct.checkStringGetterMustFail(cls, "passDerivedFoo");
+
+        ct.exit();
+    }
+
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/test_param_subtype_violated.java b/tests/regression/resolving/test_param_subtype_violated.java
new file mode 100644 (file)
index 0000000..254feda
--- /dev/null
@@ -0,0 +1,64 @@
+public class test_param_subtype_violated {
+
+    public static void main(String[] args) {
+        TestController ct = new TestController();
+
+        TestLoader ld1 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld1", ct);
+        TestLoader ld2 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld2", ct);
+        TestLoader ld3 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld3", ct);
+
+        ld1.addClassfile("BarUseFoo", "classes1/BarUseFoo.class");
+        ld1.addClassfile("Foo", "classes1/Foo.class");
+        ld1.addParentDelegation("java.lang.Object");
+        ld1.addParentDelegation("java.lang.String");
+
+        ld2.addClassfile("BarPassFoo", "classes2/BarPassFoo.class");
+        ld2.addDelegation("BarUseFoo", ld1);
+        ld2.addDelegation("Foo", ld1);
+        ld2.addDelegation("DerivedFoo", ld3);
+        ld2.addParentDelegation("java.lang.Object");
+        ld2.addParentDelegation("java.lang.String");
+
+        ld3.addClassfile("Foo", "classes3/Foo.class");
+        ld3.addClassfile("DerivedFoo", "classes3/DerivedFoo.class");
+        ld3.addParentDelegation("java.lang.Object");
+        ld3.addParentDelegation("java.lang.String");
+
+
+        // loading BarPassFoo
+        ct.expect("requested", ld2, "BarPassFoo");
+        ct.expect("defined", ld2, "<BarPassFoo>");
+        ct.expect("loaded", ld2, "<BarPassFoo>");
+
+        Class cls = ct.loadClass(ld2, "BarPassFoo");
+
+        // linking BarPassFoo
+        ct.expectLoadFromSystem(ld2, "java.lang.Object");
+
+        // executing BarPassFoo.passDerivedFoo: new DerivedFoo
+        ct.expectDelegationAndDefinition(ld2, ld3, "DerivedFoo");
+        // ...linking (ld3, DerivedFoo)
+        ct.expect("requested", ld3, "Foo");
+        ct.expect("defined", ld3, "<Foo>");
+        ct.expectLoadFromSystem(ld3, "java.lang.Object");
+
+        // executing BarPassFoo.passDerivedFoo: new BarUseFoo
+        ct.expectDelegationAndDefinition(ld2, ld1, "BarUseFoo");
+        // ...linking BarUseFoo
+        ct.expectLoadFromSystem(ld1, "java.lang.Object");
+
+        // resolving BarUseFoo.useFoo
+        // the deferred subtype check ((ld2, DerivedFoo) subtypeof (ld2, Foo)) is done
+        ct.expectDelegationAndDefinition(ld2, ld1, "Foo");
+
+        // the subtype constraint ((ld2, DerivedFoo) subtypeof (ld2, Foo)) is violated
+        ct.expect("exception", "java.lang.LinkageError", "<BarPassFoo>");
+
+        ct.checkStringGetterMustFail(cls, "passDerivedFoo");
+
+        ct.exit();
+    }
+
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/test_retval_loading_constraint_violated.java b/tests/regression/resolving/test_retval_loading_constraint_violated.java
new file mode 100644 (file)
index 0000000..8893a7f
--- /dev/null
@@ -0,0 +1,50 @@
+public class test_retval_loading_constraint_violated {
+
+    public static void main(String[] args) {
+        TestController ct = new TestController();
+
+        TestLoader ld1 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld1", ct);
+        TestLoader ld2 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld2", ct);
+
+        ld1.addClassfile("BarUseFoo", "classes1/BarUseFoo.class");
+        ld1.addClassfile("Foo", "classes1/Foo.class");
+        ld1.addDelegation("BarPassFoo", ld2);
+        ld1.addParentDelegation("java.lang.Object");
+        ld1.addParentDelegation("java.lang.String");
+
+        ld2.addClassfile("BarPassFoo", "classes2/BarPassFoo.class");
+        ld2.addClassfile("Foo", "classes2/Foo.class");
+        ld2.addParentDelegation("java.lang.Object");
+        ld2.addParentDelegation("java.lang.String");
+
+
+        // loading BarUseFoo
+        ct.expect("requested", ld1, "BarUseFoo");
+        ct.expect("defined", ld1, "<BarUseFoo>");
+        ct.expect("loaded", ld1, "<BarUseFoo>");
+
+        Class cls = ct.loadClass(ld1, "BarUseFoo");
+
+        // linking BarUseFoo
+        ct.expectLoadFromSystem(ld1, "java.lang.Object");
+
+        // executing BarUseFoo.useReturnedFoo: new BarPassFoo
+        ct.expectDelegationAndDefinition(ld1, ld2, "BarPassFoo");
+        // ...linking BarPassFoo
+        ct.expectLoadFromSystem(ld2, "java.lang.Object");
+
+        // resolving BarPassFoo.createFoo
+        ct.expect("requested", ld2, "Foo");
+        ct.expect("defined", ld2, "<Foo>");
+        ct.expect("requested", ld1, "Foo");
+        // ...the loading constraing (ld1,ld2,Foo) is violated
+        ct.expect("exception", "java.lang.LinkageError", "<BarUseFoo>");
+
+        ct.checkStringGetterMustFail(cls, "useReturnedFoo");
+
+        ct.exit();
+    }
+
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/test_simple_lazy_load.java b/tests/regression/resolving/test_simple_lazy_load.java
new file mode 100644 (file)
index 0000000..30ca610
--- /dev/null
@@ -0,0 +1,32 @@
+public class test_simple_lazy_load {
+
+    public static void main(String[] args) {
+        TestController ct = new TestController();
+
+        TestLoader ld1 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld1", ct);
+
+        ld1.addClassfile("BarUseFoo", "classes1/BarUseFoo.class");
+        ct.expect("requested", ld1, "BarUseFoo");
+        ct.expect("defined", ld1, "<BarUseFoo>");
+        ct.expect("loaded", ld1, "<BarUseFoo>");
+        Class cls = ct.loadClass(ld1, "BarUseFoo");
+        ct.expectEnd();
+
+        ld1.addParentDelegation("java.lang.Object");
+        ct.expectLoadFromSystem(ld1, "java.lang.Object");
+        ct.checkClassId(cls, "classes1/BarUseFoo");
+        ct.expectEnd();
+
+        ld1.addClassfile("Foo", "classes1/Foo.class");
+        ct.setReportClassIDs(true);
+        ct.expect("requested", ld1, "Foo");
+        ct.expect("defined", ld1, "<Foo:classes1/Foo>");
+        ct.checkStringGetter(cls, "idOfFoo", "classes1/Foo");
+        ct.expectEnd();
+
+        ct.exit();
+    }
+
+}
+
+// vim: et sw=4