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

Reply via email to