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