While at it, make it more robust by using valueOf() functions. Signed-off-by: Tomek Grabiec <tgrab...@gmail.com> --- include/vm/preload.h | 8 +++ vm/preload.c | 56 ++++++++++++++++++ vm/reflection.c | 153 ++++++++++++++++++++------------------------------ 3 files changed, 124 insertions(+), 93 deletions(-)
diff --git a/include/vm/preload.h b/include/vm/preload.h index a99fa89..d09f6b7 100644 --- a/include/vm/preload.h +++ b/include/vm/preload.h @@ -101,13 +101,21 @@ extern struct vm_method *vm_java_lang_VMThread_init; extern struct vm_method *vm_java_lang_VMThread_run; extern struct vm_method *vm_java_lang_System_exit; extern struct vm_method *vm_java_lang_Boolean_init; +extern struct vm_method *vm_java_lang_Boolean_valueOf; extern struct vm_method *vm_java_lang_Byte_init; +extern struct vm_method *vm_java_lang_Byte_valueOf; extern struct vm_method *vm_java_lang_Character_init; +extern struct vm_method *vm_java_lang_Character_valueOf; extern struct vm_method *vm_java_lang_Double_init; +extern struct vm_method *vm_java_lang_Double_valueOf; extern struct vm_method *vm_java_lang_Float_init; +extern struct vm_method *vm_java_lang_Float_valueOf; extern struct vm_method *vm_java_lang_Integer_init; +extern struct vm_method *vm_java_lang_Integer_valueOf; extern struct vm_method *vm_java_lang_Long_init; +extern struct vm_method *vm_java_lang_Long_valueOf; extern struct vm_method *vm_java_lang_Short_init; +extern struct vm_method *vm_java_lang_Short_valueOf; extern struct vm_method *vm_java_lang_ClassLoader_loadClass; extern struct vm_method *vm_java_lang_ClassLoader_getSystemClassLoader; extern struct vm_method *vm_java_lang_Number_intValue; diff --git a/vm/preload.c b/vm/preload.c index 23516af..ba2d50f 100644 --- a/vm/preload.c +++ b/vm/preload.c @@ -247,13 +247,21 @@ struct vm_method *vm_java_lang_VMThread_init; struct vm_method *vm_java_lang_VMThread_run; struct vm_method *vm_java_lang_System_exit; struct vm_method *vm_java_lang_Boolean_init; +struct vm_method *vm_java_lang_Boolean_valueOf; struct vm_method *vm_java_lang_Byte_init; +struct vm_method *vm_java_lang_Byte_valueOf; struct vm_method *vm_java_lang_Character_init; +struct vm_method *vm_java_lang_Character_valueOf; struct vm_method *vm_java_lang_Double_init; +struct vm_method *vm_java_lang_Double_valueOf; struct vm_method *vm_java_lang_Float_init; +struct vm_method *vm_java_lang_Float_valueOf; struct vm_method *vm_java_lang_Integer_init; +struct vm_method *vm_java_lang_Integer_valueOf; struct vm_method *vm_java_lang_Long_init; +struct vm_method *vm_java_lang_Long_valueOf; struct vm_method *vm_java_lang_Short_init; +struct vm_method *vm_java_lang_Short_valueOf; struct vm_method *vm_java_lang_ClassLoader_loadClass; struct vm_method *vm_java_lang_ClassLoader_getSystemClassLoader; struct vm_method *vm_java_lang_VMString_intern; @@ -360,48 +368,96 @@ static const struct method_preload_entry method_preload_entries[] = { &vm_java_lang_Boolean_init, }, { + &vm_java_lang_Boolean, + "valueOf", + "(Z)Ljava/lang/Boolean;", + &vm_java_lang_Boolean_valueOf, + }, + { &vm_java_lang_Byte, "<init>", "(B)V", &vm_java_lang_Byte_init, }, { + &vm_java_lang_Byte, + "valueOf", + "(B)Ljava/lang/Byte;", + &vm_java_lang_Byte_valueOf, + }, + { &vm_java_lang_Character, "<init>", "(C)V", &vm_java_lang_Character_init, }, { + &vm_java_lang_Character, + "valueOf", + "(C)Ljava/lang/Character;", + &vm_java_lang_Character_valueOf, + }, + { &vm_java_lang_Double, "<init>", "(D)V", &vm_java_lang_Double_init, }, { + &vm_java_lang_Double, + "valueOf", + "(D)Ljava/lang/Double;", + &vm_java_lang_Double_valueOf, + }, + { &vm_java_lang_Long, "<init>", "(J)V", &vm_java_lang_Long_init, }, { + &vm_java_lang_Long, + "valueOf", + "(J)Ljava/lang/Long;", + &vm_java_lang_Long_valueOf, + }, + { &vm_java_lang_Short, "<init>", "(S)V", &vm_java_lang_Short_init, }, { + &vm_java_lang_Short, + "valueOf", + "(S)Ljava/lang/Short;", + &vm_java_lang_Short_valueOf, + }, + { &vm_java_lang_Float, "<init>", "(F)V", &vm_java_lang_Float_init, }, { + &vm_java_lang_Float, + "valueOf", + "(F)Ljava/lang/Float;", + &vm_java_lang_Float_valueOf, + }, + { &vm_java_lang_Integer, "<init>", "(I)V", &vm_java_lang_Integer_init, }, { + &vm_java_lang_Integer, + "valueOf", + "(I)Ljava/lang/Integer;", + &vm_java_lang_Integer_valueOf, + }, + { &vm_java_lang_ClassLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", diff --git a/vm/reflection.c b/vm/reflection.c index e5dea46..027bfb4 100644 --- a/vm/reflection.c +++ b/vm/reflection.c @@ -505,67 +505,77 @@ struct vm_object *native_vmclass_get_superclass(struct vm_object *clazz) return vmc->super->object; } -static struct vm_object *encapsulate_value(void *value_p, enum vm_type type) +static int unwrap(void *field_ptr, enum vm_type type, + struct vm_object *value) { - struct vm_object *obj; + unsigned long args[] = { (unsigned long) value }; + union jvalue result; switch (type) { case J_REFERENCE: - return *(struct vm_object **) value_p; + *(jobject *) field_ptr = value; + return 0; + case J_BYTE: case J_BOOLEAN: - obj = vm_object_alloc(vm_java_lang_Boolean); - if (!obj) - goto failed_obj; - vm_call_method(vm_java_lang_Boolean_init, obj, *(jboolean *) value_p); - return obj; + case J_SHORT: + case J_CHAR: + case J_INT: + /* + * We can handle those as int because these values are + * returned by ireturn anyway. + */ + vm_call_method_this_a(vm_java_lang_Number_intValue, value, args, &result); + *(long *) field_ptr = result.i; + return 0; + case J_FLOAT: + vm_call_method_this_a(vm_java_lang_Number_floatValue, value, args, &result); + *(jfloat *) field_ptr = result.f; + return 0; + case J_LONG: + vm_call_method_this_a(vm_java_lang_Number_longValue, value, args, &result); + *(jlong *) field_ptr = result.j; + return 0; + case J_DOUBLE: + vm_call_method_this_a(vm_java_lang_Number_doubleValue, value, args, &result); + *(jdouble *) field_ptr = result.d; + return 0; + case J_VOID: + case J_RETURN_ADDRESS: + case VM_TYPE_MAX: + error("unexpected type"); + } + + return 0; +} + +static struct vm_object *wrap(union jvalue *value, enum vm_type vm_type) +{ + switch (vm_type) { + case J_VOID: + return NULL; + case J_REFERENCE: + return value->l; + case J_BOOLEAN: + return vm_call_method_object(vm_java_lang_Boolean_valueOf, value->z); case J_BYTE: - obj = vm_object_alloc(vm_java_lang_Byte); - if (!obj) - goto failed_obj; - vm_call_method(vm_java_lang_Byte_init, obj, *(jbyte *) value_p); - return obj; + return vm_call_method_object(vm_java_lang_Byte_valueOf, value->b); case J_CHAR: - obj = vm_object_alloc(vm_java_lang_Character); - if (!obj) - goto failed_obj; - vm_call_method(vm_java_lang_Character_init, obj, *(jchar *) value_p); - return obj; + return vm_call_method_object(vm_java_lang_Character_valueOf, value->c); case J_SHORT: - obj = vm_object_alloc(vm_java_lang_Short); - if (!obj) - goto failed_obj; - vm_call_method(vm_java_lang_Short_init, obj, *(jshort *) value_p); - return obj; - case J_FLOAT: - obj = vm_object_alloc(vm_java_lang_Float); - if (!obj) - goto failed_obj; - vm_call_method(vm_java_lang_Float_init, obj, *(jfloat *) value_p); - return obj; + return vm_call_method_object(vm_java_lang_Short_valueOf, value->s); + case J_LONG: + return vm_call_method_object(vm_java_lang_Long_valueOf, value->j); case J_INT: - obj = vm_object_alloc(vm_java_lang_Integer); - if (!obj) - goto failed_obj; - vm_call_method(vm_java_lang_Integer_init, obj, *(jint *) value_p); - return obj; + return vm_call_method_object(vm_java_lang_Integer_valueOf, value->i); + case J_FLOAT: + return vm_call_method_object(vm_java_lang_Float_valueOf, value->f); case J_DOUBLE: - obj = vm_object_alloc(vm_java_lang_Double); - if (!obj) - goto failed_obj; - vm_call_method(vm_java_lang_Double_init, obj, *(jdouble *) value_p); - return obj; - case J_LONG: - obj = vm_object_alloc(vm_java_lang_Long); - if (!obj) - goto failed_obj; - vm_call_method(vm_java_lang_Long_init, obj, *(jlong *) value_p); - return obj; - default: - error("invalid type"); + return vm_call_method_object(vm_java_lang_Double_valueOf, value->d); + case J_RETURN_ADDRESS: + case VM_TYPE_MAX: + die("unexpected type"); } - failed_obj: - NOT_IMPLEMENTED; return NULL; } @@ -614,7 +624,7 @@ struct vm_object *native_field_get(struct vm_object *this, struct vm_object *o) value_p = &o->fields[vmf->offset]; } - return encapsulate_value(value_p, type); + return wrap((union jvalue *) &value_p, type); } jint native_field_get_modifiers_internal(struct vm_object *this) @@ -628,49 +638,6 @@ jint native_field_get_modifiers_internal(struct vm_object *this) return vmf->field->access_flags; } -static int unwrap(void *field_ptr, enum vm_type type, - struct vm_object *value) -{ - unsigned long args[] = { (unsigned long) value }; - union jvalue result; - - switch (type) { - case J_REFERENCE: - *(jobject *) field_ptr = value; - return 0; - case J_BYTE: - case J_BOOLEAN: - case J_SHORT: - case J_CHAR: - case J_INT: - /* - * We can handle those as int because these values are - * returned by ireturn anyway. - */ - vm_call_method_this_a(vm_java_lang_Number_intValue, value, args, &result); - *(long *) field_ptr = result.i; - return 0; - case J_FLOAT: - vm_call_method_this_a(vm_java_lang_Number_floatValue, value, args, &result); - *(jfloat *) field_ptr = result.f; - return 0; - case J_LONG: - vm_call_method_this_a(vm_java_lang_Number_longValue, value, args, &result); - *(jlong *) field_ptr = result.j; - return 0; - case J_DOUBLE: - vm_call_method_this_a(vm_java_lang_Number_doubleValue, value, args, &result); - *(jdouble *) field_ptr = result.d; - return 0; - case J_VOID: - case J_RETURN_ADDRESS: - case VM_TYPE_MAX: - error("unexpected type"); - } - - return 0; -} - void native_field_set(struct vm_object *this, struct vm_object *o, struct vm_object *value_obj) { -- 1.6.0.4 ------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel