Re: [PATCH 10/19] vm: rewrite array class loading
2009/7/1 Tomek Grabiec : > 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 > --- > 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); > -
[PATCH 10/19] vm: rewrite array class loading
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 --- 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); cla