2009/7/1 Tomek Grabiec <[email protected]>:
> 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 <[email protected]>
> ---
> 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 <[email protected]>
Vegard
------------------------------------------------------------------------------
_______________________________________________
Jatovm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jatovm-devel