Support primitive array elements in annotations.
Annotations that include primitive array elements are stored internally
as arrays of boxed primitives. The VM didn't know how to un-box them
when somebody requested the contents.
For bug 2370144.
diff --git a/vm/oo/Array.c b/vm/oo/Array.c
index 60da683..4af03a9 100644
--- a/vm/oo/Array.c
+++ b/vm/oo/Array.c
@@ -689,6 +689,82 @@
}
/*
+ * Copy the entire contents of an array of boxed primitives into an
+ * array of primitives. The boxed value must fit in the primitive (i.e.
+ * narrowing conversions are not allowed).
+ */
+bool dvmUnboxObjectArray(ArrayObject* dstArray, const ArrayObject* srcArray,
+ ClassObject* dstElemClass)
+{
+ Object** src = (Object**)srcArray->contents;
+ void* dst = (void*)dstArray->contents;
+ u4 count = dstArray->length;
+ PrimitiveType typeIndex = dstElemClass->primitiveType;
+
+ assert(typeIndex != PRIM_NOT);
+ assert(srcArray->length == dstArray->length);
+
+ while (count--) {
+ JValue result;
+
+ /*
+ * This will perform widening conversions as appropriate. It
+ * might make sense to be more restrictive and require that the
+ * primitive type exactly matches the box class, but it's not
+ * necessary for correctness.
+ */
+ if (!dvmUnwrapPrimitive(*src, dstElemClass, &result)) {
+ LOGW("dvmCopyObjectArray: can't store %s in %s\n",
+ (*src)->clazz->descriptor, dstElemClass->descriptor);
+ return false;
+ }
+
+ /* would be faster with 4 loops, but speed not crucial here */
+ switch (typeIndex) {
+ case PRIM_BOOLEAN:
+ case PRIM_BYTE:
+ {
+ u1* tmp = dst;
+ *tmp++ = result.b;
+ dst = tmp;
+ }
+ break;
+ case PRIM_CHAR:
+ case PRIM_SHORT:
+ {
+ u2* tmp = dst;
+ *tmp++ = result.s;
+ dst = tmp;
+ }
+ break;
+ case PRIM_FLOAT:
+ case PRIM_INT:
+ {
+ u4* tmp = dst;
+ *tmp++ = result.i;
+ dst = tmp;
+ }
+ break;
+ case PRIM_DOUBLE:
+ case PRIM_LONG:
+ {
+ u8* tmp = dst;
+ *tmp++ = result.j;
+ dst = tmp;
+ }
+ break;
+ default:
+ /* should not be possible to get here */
+ dvmAbort();
+ }
+
+ src++;
+ }
+
+ return true;
+}
+
+/*
* Add all primitive classes to the root set of objects.
TODO: do these belong to the root class loader?
*/