*/
void Array::set_boxed_element(int32_t index, java_handle_t *o)
{
+ vftbl_t *v;
+ int type;
imm_union value;
- value = Primitive::unbox(o);
+ if (is_null()) {
+ exceptions_throw_nullpointerexception();
+ return;
+ }
+
+ v = LLNI_vftbl_direct(_handle);
+
+ type = v->arraydesc->arraytype;
+
+ // Special handling for object arrays.
+ if (type == ARRAYTYPE_OBJECT) {
+ ObjectArray array(_handle);
+ array.set_element(index, o);
+ return;
+ }
+
+ // Check if primitive type can be stored.
+ if (!Primitive::unbox_typed(o, type, &value)) {
+/* exceptions_throw_illegalargumentexception("argument type mismatch"); */
+ exceptions_throw_illegalargumentexception();
+ return;
+ }
set_primitive_element(index, 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.
*/