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