Signed-off-by: Vegard Nossum <vegard.nos...@gmail.com> --- include/vm/object.h | 2 + test/vm/preload-stub.c | 1 + vm/class.c | 5 ++- vm/jato.c | 9 ++++- vm/object.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 4 deletions(-)
diff --git a/include/vm/object.h b/include/vm/object.h index 7f49c52..9bb4b93 100644 --- a/include/vm/object.h +++ b/include/vm/object.h @@ -30,6 +30,8 @@ struct vm_object *vm_object_alloc_multi_array(struct vm_class *class, int nr_dimensions, int *count); struct vm_object *vm_object_alloc_array(struct vm_class *class, int count); +struct vm_object *vm_object_clone(struct vm_object *obj); + struct vm_object * vm_object_alloc_string_from_utf8(const uint8_t bytes[], unsigned int length); struct vm_object *vm_object_alloc_string_from_c(const char *bytes); diff --git a/test/vm/preload-stub.c b/test/vm/preload-stub.c index a4befac..ea53d09 100644 --- a/test/vm/preload-stub.c +++ b/test/vm/preload-stub.c @@ -4,6 +4,7 @@ struct vm_class *vm_java_lang_Object; struct vm_class *vm_java_lang_Class; struct vm_field *vm_java_lang_Class_vmdata; +struct vm_class *vm_java_lang_Cloneable; struct vm_class *vm_java_lang_String; struct vm_field *vm_java_lang_String_offset; diff --git a/vm/class.c b/vm/class.c index 72cf18b..c153fe4 100644 --- a/vm/class.c +++ b/vm/class.c @@ -350,8 +350,9 @@ int vm_class_link_array_class(struct vm_class *vmc, const char *class_name) vmc->state = VM_CLASS_LINKED; vmc->super = vm_java_lang_Object; - vmc->nr_interfaces = 0; - vmc->interfaces = NULL; + /* XXX: Actually, arrays should implement Serializable as well. */ + vmc->nr_interfaces = 1; + vmc->interfaces = &vm_java_lang_Cloneable; vmc->fields = NULL; vmc->methods = NULL; diff --git a/vm/jato.c b/vm/jato.c index e28e808..9889079 100644 --- a/vm/jato.c +++ b/vm/jato.c @@ -265,8 +265,13 @@ static int32_t __vm_native native_vmsystem_identityhashcode(struct vm_object *ob static struct vm_object * __vm_native native_vmobject_clone(struct vm_object *object) { - NOT_IMPLEMENTED; - return vm_object_alloc(object->class); + if (!object) { + signal_new_exception(vm_java_lang_NullPointerException, NULL); + throw_from_native(sizeof object); + return NULL; + } + + return vm_object_clone(object); } static struct vm_object * __vm_native diff --git a/vm/object.c b/vm/object.c index 555983d..54c022a 100644 --- a/vm/object.c +++ b/vm/object.c @@ -184,6 +184,84 @@ struct vm_object *vm_object_alloc_array(struct vm_class *class, int count) return res; } +struct vm_object *clone_regular(struct vm_object *obj) +{ + struct vm_class *vmc = obj->class; + struct vm_object *new = vm_object_alloc(vmc); + + /* XXX: What do we do about exceptions? */ + if (new) + memcpy(new + 1, obj + 1, vmc->object_size); + + return new; +} + +struct vm_object *clone_array(struct vm_object *obj) +{ + struct vm_class *vmc = obj->class; + struct vm_class *e_vmc = vmc->array_element_class; + int count = obj->array_length; + + if (e_vmc->kind == VM_CLASS_KIND_PRIMITIVE) { + enum vm_type vmtype; + int type; + struct vm_object *new; + + vmtype = e_vmc->primitive_vm_type; + type = vmtype_to_bytecode_type(vmtype); + + /* XXX: This could be optimized by not doing the memset() in + * object_alloc_native_array. */ + new = vm_object_alloc_native_array(type, count); + if (new) { + memcpy(new + 1, obj + 1, + get_vmtype_size(vmtype) * count); + } + + return new; + } else { + struct vm_object *new; + + new = vm_object_alloc_array(vmc, count); + if (new) { + memcpy(new + 1, obj + 1, + sizeof(struct vm_object *) * count); + } + + return new; + } +} + +struct vm_object *clone_primitive(struct vm_object *obj) +{ + /* XXX: Is it even possible to create instances of primitive classes? + * I suspect it will be just the same as a normal object clone, + * though. Let's do that for now... */ + NOT_IMPLEMENTED; + return clone_regular(obj); +} + +struct vm_object *vm_object_clone(struct vm_object *obj) +{ + struct vm_class *vmc; + + assert(obj); + + /* (In order of likelyhood:) */ + switch (obj->class->kind) { + case VM_CLASS_KIND_REGULAR: + return clone_regular(obj); + case VM_CLASS_KIND_ARRAY: + return clone_array(obj); + case VM_CLASS_KIND_PRIMITIVE: + return clone_primitive(obj); + } + + /* Shouldn't happen. */ + assert(0); + return NULL; +} + void vm_object_lock(struct vm_object *obj) { if (pthread_mutex_lock(&obj->mutex)) -- 1.6.0.4 ------------------------------------------------------------------------------ _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel