We need to assign access flags for arrays and primitive classes which have no corresponding cafebabe_class. Therefore ->access_flags field is introduced for struct vm_class.
Signed-off-by: Tomek Grabiec <tgrab...@gmail.com> --- Makefile | 1 + include/vm/class.h | 17 +++++---- regression/jvm/ClassTest.java | 74 +++++++++++++++++++++++++++++++++++++++++ regression/run-suite.sh | 1 + vm/class.c | 18 +++++++--- vm/classloader.c | 21 +++++------- vm/jato.c | 2 +- 7 files changed, 107 insertions(+), 27 deletions(-) create mode 100644 regression/jvm/ClassTest.java diff --git a/Makefile b/Makefile index e371db6..ee1ea58 100644 --- a/Makefile +++ b/Makefile @@ -257,6 +257,7 @@ REGRESSION_TEST_SUITE_CLASSES = \ regression/jvm/CFGCrashTest.java \ regression/jvm/ClassExceptionsTest.java \ regression/jvm/ClassLoaderTest.java \ + regression/jvm/ClassTest.java \ regression/jvm/CloneTest.java \ regression/jvm/ControlTransferTest.java \ regression/jvm/ConversionTest.java \ diff --git a/include/vm/class.h b/include/vm/class.h index bf18b5e..46b34b2 100644 --- a/include/vm/class.h +++ b/include/vm/class.h @@ -36,6 +36,7 @@ struct vm_class { enum vm_class_kind kind; const struct cafebabe_class *class; enum vm_class_state state; + uint16_t access_flags; char *name; pthread_mutex_t mutex; @@ -88,7 +89,7 @@ struct vm_class { int vm_class_link(struct vm_class *vmc, const struct cafebabe_class *class); int vm_class_link_primitive_class(struct vm_class *vmc, const char *class_name); -int vm_class_link_array_class(struct vm_class *vmc, const char *class_name); +int vm_class_link_array_class(struct vm_class *vmc, struct vm_class *elem_class, const char *class_name); int vm_class_init(struct vm_class *vmc); int vm_class_ensure_object(struct vm_class *vmc); @@ -99,37 +100,37 @@ static inline int vm_class_ensure_init(struct vm_class *vmc) static inline bool vm_class_is_public(const struct vm_class *vmc) { - return vmc->class->access_flags & CAFEBABE_CLASS_ACC_PUBLIC; + return vmc->access_flags & CAFEBABE_CLASS_ACC_PUBLIC; } static inline bool vm_class_is_private(const struct vm_class *vmc) { - return vmc->class->access_flags & CAFEBABE_CLASS_ACC_PRIVATE; + return vmc->access_flags & CAFEBABE_CLASS_ACC_PRIVATE; } static inline bool vm_class_is_protected(const struct vm_class *vmc) { - return vmc->class->access_flags & CAFEBABE_CLASS_ACC_PROTECTED; + return vmc->access_flags & CAFEBABE_CLASS_ACC_PROTECTED; } static inline bool vm_class_is_static(const struct vm_class *vmc) { - return vmc->class->access_flags & CAFEBABE_CLASS_ACC_STATIC; + return vmc->access_flags & CAFEBABE_CLASS_ACC_STATIC; } static inline bool vm_class_is_abstract(const struct vm_class *vmc) { - return vmc->class->access_flags & CAFEBABE_CLASS_ACC_ABSTRACT; + return vmc->access_flags & CAFEBABE_CLASS_ACC_ABSTRACT; } static inline bool vm_class_is_final(const struct vm_class *vmc) { - return vmc->class->access_flags & CAFEBABE_CLASS_ACC_FINAL; + return vmc->access_flags & CAFEBABE_CLASS_ACC_FINAL; } static inline bool vm_class_is_interface(const struct vm_class *vmc) { - return vmc->class->access_flags & CAFEBABE_CLASS_ACC_INTERFACE; + return vmc->access_flags & CAFEBABE_CLASS_ACC_INTERFACE; } static inline bool vm_class_is_array_class(const struct vm_class *vmc) diff --git a/regression/jvm/ClassTest.java b/regression/jvm/ClassTest.java new file mode 100644 index 0000000..27d3b75 --- /dev/null +++ b/regression/jvm/ClassTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2009 Tomasz Grabiec + * + * This file is released under the GPL version 2 with the following + * clarification and special exception: + * + * Linking this library statically or dynamically with other modules is + * making a combined work based on this library. Thus, the terms and + * conditions of the GNU General Public License cover the whole + * combination. + * + * As a special exception, the copyright holders of this library give you + * permission to link this library with independent modules to produce an + * executable, regardless of the license terms of these independent + * modules, and to copy and distribute the resulting executable under terms + * of your choice, provided that you also meet, for each linked independent + * module, the terms and conditions of the license of that module. An + * independent module is a module which is not derived from or based on + * this library. If you modify this library, you may extend this exception + * to your version of the library, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + * Please refer to the file LICENSE for details. + */ +package jvm; + +import java.lang.reflect.Modifier; + +/** + * @author Tomasz Grabiec + */ +public class ClassTest extends TestCase { + public static void testPrimitiveClassModifiers() { + Class primitive = Integer.TYPE; + int modifiers = primitive.getModifiers(); + + assertEquals(Modifier.PUBLIC + | Modifier.FINAL + | Modifier.ABSTRACT, + modifiers); + } + + private static class X { + }; + + public static void testArrayClassModifiers() { + X[] array = new X[1]; + + int modifiers = array.getClass().getModifiers(); + + /* + * FIXME: hotspot sets ACC_PRIVATE and ACC_STATIC for X while + * jato does not. + */ + assertEquals(0 /* Modifier.PRIVATE | Modifier.STATIC */, + X.class.getModifiers()); + + assertEquals(0 /* Modifier.PRIVATE | Modifier.STATIC */ + | Modifier.FINAL + | Modifier.ABSTRACT, + modifiers); + } + + public static void testRegularClassModifiers() { + assertEquals(Modifier.PUBLIC, ClassTest.class.getModifiers()); + } + + public static void main(String []args) { + testPrimitiveClassModifiers(); + testArrayClassModifiers(); + testRegularClassModifiers(); + } +} \ No newline at end of file diff --git a/regression/run-suite.sh b/regression/run-suite.sh index f28f794..336ba6c 100755 --- a/regression/run-suite.sh +++ b/regression/run-suite.sh @@ -53,6 +53,7 @@ if [ -z "$CLASS_LIST" ]; then run_java jvm.CFGCrashTest 0 run_java jvm.ClassExceptionsTest 0 run_java jvm.ClassLoaderTest 0 + run_java jvm.ClassTest 0 run_java jvm.CloneTest 0 run_java jvm.ControlTransferTest 0 run_java jvm.ConversionTest 0 diff --git a/vm/class.c b/vm/class.c index e00d7a4..4c77dd3 100644 --- a/vm/class.c +++ b/vm/class.c @@ -188,14 +188,11 @@ static void buckets_order_fields(struct field_bucket buckets[VM_TYPE_MAX], int vm_class_link(struct vm_class *vmc, const struct cafebabe_class *class) { - int err; - vmc->class = class; vmc->kind = VM_CLASS_KIND_REGULAR; - err = vm_class_link_common(vmc); - if (err) - return -err; + if (vm_class_link_common(vmc)) + return -1; const struct cafebabe_constant_info_class *constant_class; if (cafebabe_class_constant_get_class(class, @@ -215,6 +212,8 @@ int vm_class_link(struct vm_class *vmc, const struct cafebabe_class *class) vmc->name = strndup((char *) name->bytes, name->length); + vmc->access_flags = class->access_flags; + vmc->source_file_name = cafebabe_class_get_source_file_name(class); if (class->super_class) { @@ -423,6 +422,8 @@ int vm_class_link_primitive_class(struct vm_class *vmc, const char *class_name) vmc->class = NULL; vmc->state = VM_CLASS_LINKED; + vmc->access_flags = CAFEBABE_CLASS_ACC_PUBLIC | CAFEBABE_CLASS_ACC_FINAL | CAFEBABE_CLASS_ACC_ABSTRACT; + vmc->super = vm_java_lang_Object; vmc->nr_interfaces = 0; vmc->interfaces = NULL; @@ -439,7 +440,8 @@ int vm_class_link_primitive_class(struct vm_class *vmc, const char *class_name) return 0; } -int vm_class_link_array_class(struct vm_class *vmc, const char *class_name) +int vm_class_link_array_class(struct vm_class *vmc, struct vm_class *elem_class, + const char *class_name) { int err; @@ -455,6 +457,10 @@ int vm_class_link_array_class(struct vm_class *vmc, const char *class_name) vmc->class = NULL; vmc->state = VM_CLASS_LINKED; + vmc->array_element_class = elem_class; + vmc->access_flags = (elem_class->access_flags & ~CAFEBABE_CLASS_ACC_INTERFACE) + | CAFEBABE_CLASS_ACC_FINAL | CAFEBABE_CLASS_ACC_ABSTRACT; + vmc->super = vm_java_lang_Object; /* XXX: Actually, arrays should implement Serializable as well. */ vmc->nr_interfaces = 1; diff --git a/vm/classloader.c b/vm/classloader.c index 28270c7..5bd67ba 100644 --- a/vm/classloader.c +++ b/vm/classloader.c @@ -416,6 +416,7 @@ static struct vm_class * load_array_class(struct vm_object *loader, const char *class_name) { struct vm_class *array_class; + struct vm_class *elem_class; char *elem_class_name; assert(class_name[0] == '['); @@ -429,25 +430,21 @@ load_array_class(struct vm_object *loader, const char *class_name) elem_class_name = vm_class_get_array_element_class_name(class_name); if (!elem_class_name) { - NOT_IMPLEMENTED; + signal_new_exception(vm_java_lang_OutOfMemoryError, NULL); return NULL; } - if (vm_class_link_array_class(array_class, class_name)) { - NOT_IMPLEMENTED; - return NULL; - } + if (str_to_type(class_name + 1) != J_REFERENCE) + elem_class = classloader_load_primitive(elem_class_name); + else + elem_class = classloader_load(loader, elem_class_name); - if (str_to_type(class_name + 1) != J_REFERENCE) { - array_class->array_element_class = - classloader_load_primitive(elem_class_name); - } else { - array_class->array_element_class = - classloader_load(loader, elem_class_name); + if (vm_class_link_array_class(array_class, elem_class, class_name)) { + signal_new_exception(vm_java_lang_OutOfMemoryError, NULL); + return NULL; } free(elem_class_name); - return array_class; } diff --git a/vm/jato.c b/vm/jato.c index b3ca8d0..2882ee9 100644 --- a/vm/jato.c +++ b/vm/jato.c @@ -628,7 +628,7 @@ static jint native_vmclass_getmodifiers(struct vm_object *clazz) if (!class) return 0; - return class->class->access_flags; + return class->access_flags; } static struct vm_object * -- 1.6.0.6 ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel