diff options
Diffstat (limited to 'vm/native/java_lang_reflect_Array.cpp')
-rw-r--r-- | vm/native/java_lang_reflect_Array.cpp | 147 |
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 }, +}; |