2009/7/1 Tomek Grabiec <tgrab...@gmail.com>:
> 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;
> +       };
>  };

And now that I think about it, I have a feeling that this should go
somewhere around the "class" member instead. It's just about intuitive
ordering, maybe my intuition is completely off ;-)

(I can even send a patch to fix the order myself, if you agree with it.)

>
>  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;

I think we could also use strndup for this.

result = strndup(class_name + 2, len - 3);

?

> +
> +               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;
>  }

Hm, this was hard to review. I'll just look at the end result when
Pekka merges it ;-)

Acked-by: Vegard Nossum <vegard.nos...@gmail.com>


Vegard

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

Reply via email to