X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fprimitive.cpp;h=9d6b79200e7ea2bcb753cbc69a915dee1869a12f;hb=d86a339b13c60630b7b391f0e5b17f510660f4da;hp=0a2d42212365b0fa394904783ca18266edd835aa;hpb=3c1549ce97160050029b21403b105a911da3cd45;p=cacao.git diff --git a/src/vm/primitive.cpp b/src/vm/primitive.cpp index 0a2d42212..9d6b79200 100644 --- a/src/vm/primitive.cpp +++ b/src/vm/primitive.cpp @@ -31,7 +31,7 @@ #include "native/llni.h" #include "vm/jit/builtin.hpp" -#include "vm/class.h" +#include "vm/class.hpp" #include "vm/global.h" #include "vm/globals.hpp" #include "vm/javaobjects.hpp" @@ -480,6 +480,161 @@ imm_union Primitive::unbox(java_handle_t *h) } +/** + * Unbox a primitive of the given type. Also checks if the + * boxed primitive type can be widened into the destination + * type. This conversion is done according to + * "The Java Language Specification, Third Edition, + * $5.1.2 Widening Primitive Conversion". + * + * @param h Handle of the boxing Java object. + * @param type Destination type of the conversion. + * @param value Pointer to union where the resulting primitive + * value will be stored will. + * + * @return True of the conversion is allowed, false otherwise. + */ +bool Primitive::unbox_typed(java_handle_t *h, int type, imm_union* value) +{ + classinfo *c; + int src_type; + + if (h == NULL) + return false; + + LLNI_class_get(h, c); + + src_type = get_type_by_wrapperclass(c); + + switch (src_type) { + case PRIMITIVETYPE_BOOLEAN: + switch (type) { + case PRIMITIVETYPE_BOOLEAN: + value->i = unbox_boolean(h); + return true; + default: + return false; + } + + case PRIMITIVETYPE_BYTE: + switch (type) { + case PRIMITIVETYPE_BYTE: + case PRIMITIVETYPE_SHORT: + case PRIMITIVETYPE_INT: + value->i = unbox_byte(h); + return true; + case PRIMITIVETYPE_LONG: + value->l = unbox_byte(h); + return true; + case PRIMITIVETYPE_FLOAT: + value->f = unbox_byte(h); + return true; + case PRIMITIVETYPE_DOUBLE: + value->d = unbox_byte(h); + return true; + default: + return false; + } + + case PRIMITIVETYPE_CHAR: + switch (type) { + case PRIMITIVETYPE_CHAR: + case PRIMITIVETYPE_INT: + value->i = unbox_char(h); + return true; + case PRIMITIVETYPE_LONG: + value->l = unbox_char(h); + return true; + case PRIMITIVETYPE_FLOAT: + value->f = unbox_char(h); + return true; + case PRIMITIVETYPE_DOUBLE: + value->d = unbox_char(h); + return true; + default: + return false; + } + + case PRIMITIVETYPE_SHORT: + switch (type) { + case PRIMITIVETYPE_SHORT: + case PRIMITIVETYPE_INT: + value->i = unbox_short(h); + return true; + case PRIMITIVETYPE_LONG: + value->l = unbox_short(h); + return true; + case PRIMITIVETYPE_FLOAT: + value->f = unbox_short(h); + return true; + case PRIMITIVETYPE_DOUBLE: + value->d = unbox_short(h); + return true; + default: + return false; + } + + case PRIMITIVETYPE_INT: + switch (type) { + case PRIMITIVETYPE_INT: + value->i = unbox_int(h); + return true; + case PRIMITIVETYPE_LONG: + value->l = unbox_int(h); + return true; + case PRIMITIVETYPE_FLOAT: + value->f = unbox_int(h); + return true; + case PRIMITIVETYPE_DOUBLE: + value->d = unbox_int(h); + return true; + default: + return false; + } + + case PRIMITIVETYPE_LONG: + switch (type) { + case PRIMITIVETYPE_LONG: + value->l = unbox_long(h); + return true; + case PRIMITIVETYPE_FLOAT: + value->f = unbox_long(h); + return true; + case PRIMITIVETYPE_DOUBLE: + value->d = unbox_long(h); + return true; + default: + return false; + } + + case PRIMITIVETYPE_FLOAT: + switch (type) { + case PRIMITIVETYPE_FLOAT: + value->f = unbox_float(h); + return true; + case PRIMITIVETYPE_DOUBLE: + value->d = unbox_float(h); + return true; + default: + return false; + } + + case PRIMITIVETYPE_DOUBLE: + switch (type) { + case PRIMITIVETYPE_DOUBLE: + value->d = unbox_double(h); + return true; + default: + return false; + } + + default: + os::abort("Primitive::unbox_typed: Invalid primitive type %d", type); + return false; + } +} + + /** * Box a primitive type. */ @@ -647,17 +802,6 @@ inline double Primitive::unbox_double(java_handle_t *h) } - -// Legacy C interface. - -extern "C" { - -classinfo* Primitive_get_class_by_name(utf *name) { return Primitive::get_class_by_name(name); } -classinfo* Primitive_get_class_by_type(int type) { return Primitive::get_class_by_type(type); } -classinfo* Primitive_get_arrayclass_by_type(int type) { return Primitive::get_arrayclass_by_type(type); } -} - - /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where