This also introduces vm_class.array_element_class field which points
to the class of array element for array classes. This field is set
during array class loading. Array element class is initialized on
demand, when vm_class_get_array_element_class() is called.

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 include/vm/class.h |   13 ++++-
 vm/class.c         |   36 +++++++++++++++
 vm/classloader.c   |  124 +++++++++++++--------------------------------------
 3 files changed, 78 insertions(+), 95 deletions(-)

diff --git a/include/vm/class.h b/include/vm/class.h
index 69dc484..eba73b1 100644
--- a/include/vm/class.h
+++ b/include/vm/class.h
@@ -51,9 +51,14 @@ struct vm_class {
 
        struct list_head static_fixup_site_list;
 
-       /* For primitve type classes this holds a vm type
-          represented by this class. */
-       enum vm_type primitive_vm_type;
+       union {
+               /* For primitve type classes this holds a vm type
+                  represented by this class. */
+               enum vm_type primitive_vm_type;
+
+               /* For array classes this points to array element's class */
+               struct vm_class *array_element_class;
+       };
 };
 
 int vm_class_link(struct vm_class *vmc, const struct cafebabe_class *class);
@@ -106,5 +111,7 @@ struct vm_method *vm_class_resolve_method_recursive(const 
struct vm_class *vmc,
 
 bool vm_class_is_assignable_from(const struct vm_class *vmc, const struct 
vm_class *from);
 bool vm_class_is_primitive_type_name(const char *class_name);
+char *vm_class_get_array_element_class_name(const char *class_name);
+struct vm_class *vm_class_get_array_element_class(const struct vm_class 
*array_class);
 
 #endif /* __CLASS_H */
diff --git a/vm/class.c b/vm/class.c
index 91ba8da..18eb189 100644
--- a/vm/class.c
+++ b/vm/class.c
@@ -547,3 +547,39 @@ bool vm_class_is_assignable_from(const struct vm_class 
*vmc, const struct vm_cla
        NOT_IMPLEMENTED;
        return false;
 }
+
+char *vm_class_get_array_element_class_name(const char *class_name)
+{
+       if (class_name[0] != '[')
+               return NULL;
+
+       if (class_name[1] == 'L') {
+               char *result;
+               int len;
+
+               /* Skip '[L' prefix and ';' suffix */
+               len = strlen(class_name);
+               assert(class_name[len - 1] == ';');
+
+               result = malloc(len - 2);
+               memcpy(result, class_name + 2, len - 3);
+               result[len - 3] = 0;
+
+               return result;
+       }
+
+       return strdup(class_name + 1);
+}
+
+struct vm_class *
+vm_class_get_array_element_class(const struct vm_class *array_class)
+{
+       struct vm_class *result;
+
+       result = array_class->array_element_class;
+       assert(result);
+
+       vm_class_ensure_init(result);
+
+       return result;
+}
diff --git a/vm/classloader.c b/vm/classloader.c
index eff2815..70f0835 100644
--- a/vm/classloader.c
+++ b/vm/classloader.c
@@ -310,56 +310,6 @@ static enum vm_type class_name_to_vm_type(const char 
*class_name)
        return J_VOID;
 }
 
-
-struct vm_class *load_primitive_array_class(const char *class_name,
-       unsigned int dimensions, char type)
-{
-       struct vm_class *array_class;
-
-       array_class = malloc(sizeof *array_class);
-       if (!array_class) {
-               NOT_IMPLEMENTED;
-               return NULL;
-       }
-
-       array_class->class = NULL;
-       array_class->state = VM_CLASS_LINKED;
-       array_class->name = strdup(class_name);
-       array_class->super = vm_java_lang_Object;
-       array_class->fields = NULL;
-       array_class->methods = NULL;
-       array_class->object_size = 0;
-       array_class->vtable_size = 0;
-       array_class->primitive_vm_type = class_name_to_vm_type(class_name);
-       array_class->kind = VM_CLASS_KIND_ARRAY;
-
-       return array_class;
-}
-
-struct vm_class *load_class_array_class(const char *array_class_name,
-       unsigned int dimensions, const char *class_name)
-{
-       struct vm_class *array_class;
-
-       array_class = malloc(sizeof *array_class);
-       if (!array_class) {
-               NOT_IMPLEMENTED;
-               return NULL;
-       }
-
-       array_class->class = NULL;
-       array_class->state = VM_CLASS_LINKED;
-       array_class->name = strdup(array_class_name);
-       array_class->super = vm_java_lang_Object;
-       array_class->fields = NULL;
-       array_class->methods = NULL;
-       array_class->object_size = 0;
-       array_class->vtable_size = 0;
-       array_class->kind = VM_CLASS_KIND_ARRAY;
-
-       return array_class;
-}
-
 struct vm_class *classloader_load_primitive(const char *class_name)
 {
        struct vm_class *class;
@@ -378,6 +328,7 @@ struct vm_class *classloader_load_primitive(const char 
*class_name)
        class->methods = NULL;
        class->object_size = 0;
        class->vtable_size = 0;
+       class->primitive_vm_type = class_name_to_vm_type(class_name);
        class->kind = VM_CLASS_KIND_PRIMITIVE;
 
        return class;
@@ -385,56 +336,45 @@ struct vm_class *classloader_load_primitive(const char 
*class_name)
 
 struct vm_class *load_array_class(const char *class_name)
 {
-       const char *ptr;
-       unsigned int dimensions;
-
-       ptr = class_name;
-       for (dimensions = 0; *ptr == '['; ++ptr)
-               ++dimensions;
-
-       assert(dimensions >= 1);
-
-       if (*ptr == 'L') {
-               const char *end;
-               unsigned int n;
-               char *copy;
-               struct vm_class *ret;
-
-               ++ptr;
-               end = strchr(ptr, ';');
-               if (!end) {
-                       NOT_IMPLEMENTED;
-                       return NULL;
-               }
+       struct vm_class *array_class;
+       char *elem_class_name;
 
-               n = strlen(ptr);
+       assert(class_name[0] == '[');
 
-               /*
-                * There must be exactly one semicolon, and it must be at the
-                * end of the string.
-                */
-               if (end + 1 != ptr + n) {
-                       NOT_IMPLEMENTED;
-                       return NULL;
-               }
+       array_class = malloc(sizeof *array_class);
+       if (!array_class) {
+               NOT_IMPLEMENTED;
+               return NULL;
+       }
 
-               copy = strndup(ptr, n - 1);
-               ret = load_class_array_class(class_name, dimensions, copy);
-               free(copy);
-               return ret;
+       elem_class_name =
+               vm_class_get_array_element_class_name(class_name);
+       if (!elem_class_name) {
+               NOT_IMPLEMENTED;
+               return NULL;
        }
 
-       if (class_name_to_vm_type(ptr)) {
-               if (strlen(ptr) != 1) {
-                       NOT_IMPLEMENTED;
-                       return NULL;
-               }
+       array_class->class = NULL;
+       array_class->state = VM_CLASS_LINKED;
+       array_class->name = strdup(class_name);
+       array_class->super = vm_java_lang_Object;
+       array_class->fields = NULL;
+       array_class->methods = NULL;
+       array_class->object_size = 0;
+       array_class->vtable_size = 0;
+       array_class->kind = VM_CLASS_KIND_ARRAY;
 
-               return load_primitive_array_class(class_name, dimensions, *ptr);
+       if (class_name_to_vm_type(class_name + 1) != J_VOID) {
+               array_class->array_element_class =
+                       classloader_load_primitive(elem_class_name);
+       } else {
+               array_class->array_element_class =
+                       classloader_load(elem_class_name);
        }
 
-       NOT_IMPLEMENTED;
-       return NULL;
+       free(elem_class_name);
+
+       return array_class;
 }
 
 struct vm_class *load_class(const char *class_name)
-- 
1.6.0.6


------------------------------------------------------------------------------
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to