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.
*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"
;;
* )
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
[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]
[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
return typecheck_TRUE;
}
+void typeinfo_print(FILE *file, typeinfo *info, int indent)
+{
+}
+
/* vm *************************************************************************/
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"
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
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 \
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 $
*/
#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);
}
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 $
*/
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;
}
o = builtin_new(c);
- if (!o)
+ if (o == NULL)
return NULL;
/* call initializer */
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 $
*/
#include "vmcore/utf8.h"
-#define CHECKFIELDACCESS(this,fi,c,doret)
-
-
/* cacao_get_field_address *****************************************************
Return the address of a field of an object.
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;
}
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 $
*/
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;
}
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */
-/* 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,
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 $
*/
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
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.
*******************************************************************************/
-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;
/* 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;
}
-/* 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
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
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 $
*/
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;
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 $
*/
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;
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 $
*/
u1 *ra;
u8 mcode;
unresolved_class *uc;
- classinfo *c;
/* get stuff from the stack */
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 */
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 $
*/
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;
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 $
*/
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;
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 $
*/
u1 *ra;
u4 mcode;
unresolved_class *uc;
- classinfo *c;
/* get stuff from the stack */
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 */
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 $
*/
.globl asm_getclassvalues_atomic
-asm_handle_nat_exception:
- .long 0
asm_abstractmethoderror:
.long 0
asm_replacement_out:
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
* *
*******************************************************************************/
-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 */
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
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 $
*/
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);
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;
Changes:
- $Id: patcher.c 7383 2007-02-21 20:26:52Z twisti $
+ $Id: patcher.c 7441 2007-03-02 23:13:10Z michi $
*/
u1 *ra;
u4 mcode;
unresolved_class *uc;
- classinfo *c;
/* get stuff from the stack */
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 */
/* 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);
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);
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;
#include <assert.h>
#include <ucontext.h>
+#undef REG_SP
+
#include "vm/types.h"
#include "vm/jit/sparc64/md-abi.h"
_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];
_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);
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 $
*/
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;
} 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;
}
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
+ }
}
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 $
*/
#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)
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 $
*/
LOGSTR1("\n---- BLOCK %04d ------------------------------------------------\n",state->bptr->nr);
LOGFLUSH;
- DOLOG(show_basicblock(jd, state->bptr, SHOW_STACK));
superblockend = false;
state->bptr->flags = BBFINISHED;
/* 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));
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 $
*/
u1 *ra;
u8 mcode;
unresolved_class *uc;
- classinfo *c;
/* get stuff from the stack */
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 */
}
#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;
}
#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) */
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 $
*/
#endif
#include "toolbox/hashtable.h"
+#include "toolbox/logging.h"
#include "vm/exceptions.h"
/* DEBUG HELPERS */
/*============================================================================*/
-/*#define CLASSCACHE_VERBOSE*/
+/* #define CLASSCACHE_VERBOSE */
/*============================================================================*/
/* STATISTICS */
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);
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);
/* 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)
return_success:
#ifdef CLASSCACHE_VERBOSE
- classcache_debug_dump(stderr,cls->name);
+ classcache_debug_dump(stdout,cls->name);
#endif
CLASSCACHE_UNLOCK();
return 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);
/* (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;
return_success:
#ifdef CLASSCACHE_VERBOSE
- classcache_debug_dump(stderr,cls->name);
+ classcache_debug_dump(stdout,cls->name);
#endif
CLASSCACHE_UNLOCK();
return cls;
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 */
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 $
*/
/* 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)
classinfo **result)
{
classinfo *c;
+ classinfo *referer;
assert(cls.any);
assert(mode == resolveEager || mode == resolveLazy);
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;
}
#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 */
/******************************************************************************/
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 $
*/
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,
##
## 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
$(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 \
--- /dev/null
+.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
+
--- /dev/null
+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)
+
--- /dev/null
+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
--- /dev/null
+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
+
--- /dev/null
+public class BarPassFoo {
+ public static String id() {
+ return "classes1/BarPassFoo";
+ }
+
+ public Foo createFoo() {
+ return null;
+ }
+}
+
+// vim: et sw=4
--- /dev/null
+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
+
--- /dev/null
+public class Foo {
+ public static String id() {
+ return "classes1/Foo";
+ }
+
+ public String virtualId() {
+ return id();
+ }
+}
+
+// vim: et sw=4
--- /dev/null
+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)
+
--- /dev/null
+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
--- /dev/null
+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
+
--- /dev/null
+public class DerivedFoo extends Foo {
+ public static String id() {
+ return "classes2/DerivedFoo";
+ }
+}
+
+// vim: et sw=4
--- /dev/null
+public class Foo {
+ public static String id() {
+ return "classes2/Foo";
+ }
+
+ public String virtualId() {
+ return id();
+ }
+}
+
+// vim: et sw=4
--- /dev/null
+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)
+
+
--- /dev/null
+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
--- /dev/null
+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
+
--- /dev/null
+public class DerivedFoo extends Foo {
+ public static String id() {
+ return "classes3/DerivedFoo";
+ }
+}
+
+// vim: et sw=4
--- /dev/null
+public class Foo {
+ public static String id() {
+ return "classes3/Foo";
+ }
+
+ public String virtualId() {
+ return "not implemented";
+ }
+}
+
+// vim: et sw=4
--- /dev/null
+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)
+
+
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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