Signed-off-by: Vegard Nossum <[email protected]>
---
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/jatovm-devel