#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"
#include "vm/options.h"
+#include "vm/os.hpp"
#include "vm/primitive.hpp"
#include "vm/utf8.h"
-#include "vm/vm.hpp"
/* primitivetype_table *********************************************************
}
+/**
+ * Returns the primitive type of the given primitive-class.
+ *
+ * @param c Class structure.
+ *
+ * @return Integer type of the class.
+ */
+int Primitive::get_type_by_primitiveclass(classinfo *c)
+{
+ /* Search primitive table. */
+
+ for (int i = 0; i < PRIMITIVETYPE_COUNT; i++)
+ if (primitivetype_table[i].class_primitive == c)
+ return i;
+
+ /* Invalid primitive class. */
+
+ return -1;
+}
+
+
/**
* Box a primitive of the given type. If the type is an object,
* simply return it.
break;
default:
o = NULL;
- VM::get_current()->abort("primitive_box: invalid primitive type %d", type);
+ os::abort("Primitive::box: Invalid primitive type %d", type);
}
return o;
value.a = h;
break;
default:
- VM::get_current()->abort("Primitive::unbox: invalid primitive type %d", type);
+ os::abort("Primitive::unbox: Invalid primitive type %d", type);
}
return value;
}
+/**
+ * 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.
*/
}
-
-// 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_name(utf *name) { return Primitive::get_arrayclass_by_name(name); }
-classinfo* Primitive_get_arrayclass_by_type(int type) { return Primitive::get_arrayclass_by_type(type); }
-int Primitive_get_type_by_wrapperclass(classinfo *c) { return Primitive::get_type_by_wrapperclass(c); }
-java_handle_t* Primitive_box(int type, imm_union value) { return Primitive::box(type, value); }
-imm_union Primitive_unbox(java_handle_t *h) { return Primitive::unbox(h); }
-}
-
-
/*
* 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