summaryrefslogtreecommitdiff
path: root/vm/native/java_lang_reflect_Array.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'vm/native/java_lang_reflect_Array.cpp')
-rw-r--r--vm/native/java_lang_reflect_Array.cpp147
1 files changed, 147 insertions, 0 deletions
diff --git a/vm/native/java_lang_reflect_Array.cpp b/vm/native/java_lang_reflect_Array.cpp
new file mode 100644
index 0000000..c2fbb3d
--- /dev/null
+++ b/vm/native/java_lang_reflect_Array.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * java.lang.reflect.Array
+ */
+#include "Dalvik.h"
+#include "native/InternalNativePriv.h"
+
+
+/*
+ * private static Object createObjectArray(Class<?> componentType,
+ * int length) throws NegativeArraySizeException;
+ *
+ * Create a one-dimensional array of Objects.
+ */
+static void Dalvik_java_lang_reflect_Array_createObjectArray(const u4* args,
+ JValue* pResult)
+{
+ ClassObject* elementClass = (ClassObject*) args[0];
+ int length = args[1];
+
+ assert(elementClass != NULL); // tested by caller
+ if (length < 0) {
+ dvmThrowNegativeArraySizeException(length);
+ RETURN_VOID();
+ }
+
+ ClassObject* arrayClass =
+ dvmFindArrayClassForElement(elementClass);
+ ArrayObject* newArray =
+ dvmAllocArrayByClass(arrayClass, length, ALLOC_DEFAULT);
+ if (newArray == NULL) {
+ assert(dvmCheckException(dvmThreadSelf()));
+ RETURN_VOID();
+ }
+ dvmReleaseTrackedAlloc((Object*) newArray, NULL);
+
+ RETURN_PTR(newArray);
+}
+
+/*
+ * private static Object createMultiArray(Class<?> componentType,
+ * int[] dimensions) throws NegativeArraySizeException;
+ *
+ * Create a multi-dimensional array of Objects or primitive types.
+ *
+ * We have to generate the names for X[], X[][], X[][][], and so on. The
+ * easiest way to deal with that is to create the full name once and then
+ * subtract pieces off. Besides, we want to start with the outermost
+ * piece and work our way in.
+ */
+static void Dalvik_java_lang_reflect_Array_createMultiArray(const u4* args,
+ JValue* pResult)
+{
+ ClassObject* elementClass = (ClassObject*) args[0];
+ ArrayObject* dimArray = (ArrayObject*) args[1];
+ ClassObject* arrayClass;
+ ArrayObject* newArray;
+ char* acDescriptor;
+ int numDim, i;
+ int* dimensions;
+
+ LOGV("createMultiArray: '%s' [%d]",
+ elementClass->descriptor, dimArray->length);
+
+ assert(elementClass != NULL); // verified by caller
+
+ /*
+ * Verify dimensions.
+ *
+ * The caller is responsible for verifying that "dimArray" is non-null
+ * and has a length > 0 and <= 255.
+ */
+ assert(dimArray != NULL); // verified by caller
+ numDim = dimArray->length;
+ assert(numDim > 0 && numDim <= 255);
+
+ dimensions = (int*)(void*)dimArray->contents;
+ for (i = 0; i < numDim; i++) {
+ if (dimensions[i] < 0) {
+ dvmThrowNegativeArraySizeException(dimensions[i]);
+ RETURN_VOID();
+ }
+ LOGVV("DIM %d: %d", i, dimensions[i]);
+ }
+
+ /*
+ * Generate the full name of the array class.
+ */
+ acDescriptor =
+ (char*) malloc(strlen(elementClass->descriptor) + numDim + 1);
+ memset(acDescriptor, '[', numDim);
+
+ LOGVV("#### element name = '%s'", elementClass->descriptor);
+ if (dvmIsPrimitiveClass(elementClass)) {
+ assert(elementClass->primitiveType != PRIM_NOT);
+ acDescriptor[numDim] = dexGetPrimitiveTypeDescriptorChar(elementClass->primitiveType);
+ acDescriptor[numDim+1] = '\0';
+ } else {
+ strcpy(acDescriptor+numDim, elementClass->descriptor);
+ }
+ LOGVV("#### array name = '%s'", acDescriptor);
+
+ /*
+ * Find/generate the array class.
+ */
+ arrayClass = dvmFindArrayClass(acDescriptor, elementClass->classLoader);
+ if (arrayClass == NULL) {
+ LOGW("Unable to find or generate array class '%s'", acDescriptor);
+ assert(dvmCheckException(dvmThreadSelf()));
+ free(acDescriptor);
+ RETURN_VOID();
+ }
+ free(acDescriptor);
+
+ /* create the array */
+ newArray = dvmAllocMultiArray(arrayClass, numDim-1, dimensions);
+ if (newArray == NULL) {
+ assert(dvmCheckException(dvmThreadSelf()));
+ RETURN_VOID();
+ }
+
+ dvmReleaseTrackedAlloc((Object*) newArray, NULL);
+ RETURN_PTR(newArray);
+}
+
+const DalvikNativeMethod dvm_java_lang_reflect_Array[] = {
+ { "createObjectArray", "(Ljava/lang/Class;I)Ljava/lang/Object;",
+ Dalvik_java_lang_reflect_Array_createObjectArray },
+ { "createMultiArray", "(Ljava/lang/Class;[I)Ljava/lang/Object;",
+ Dalvik_java_lang_reflect_Array_createMultiArray },
+ { NULL, NULL, NULL },
+};