1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * java.lang.reflect.Array 19 */ 20 #include "Dalvik.h" 21 #include "native/InternalNativePriv.h" 22 23 24 /* 25 * private static Object createObjectArray(Class<?> componentType, 26 * int length) throws NegativeArraySizeException; 27 * 28 * Create a one-dimensional array of Objects. 29 */ 30 static void Dalvik_java_lang_reflect_Array_createObjectArray(const u4* args, 31 JValue* pResult) 32 { 33 ClassObject* elementClass = (ClassObject*) args[0]; 34 int length = args[1]; 35 36 assert(elementClass != NULL); // tested by caller 37 if (length < 0) { 38 dvmThrowNegativeArraySizeException(length); 39 RETURN_VOID(); 40 } 41 42 ClassObject* arrayClass = 43 dvmFindArrayClassForElement(elementClass); 44 ArrayObject* newArray = 45 dvmAllocArrayByClass(arrayClass, length, ALLOC_DEFAULT); 46 if (newArray == NULL) { 47 assert(dvmCheckException(dvmThreadSelf())); 48 RETURN_VOID(); 49 } 50 dvmReleaseTrackedAlloc((Object*) newArray, NULL); 51 52 RETURN_PTR(newArray); 53 } 54 55 /* 56 * private static Object createMultiArray(Class<?> componentType, 57 * int[] dimensions) throws NegativeArraySizeException; 58 * 59 * Create a multi-dimensional array of Objects or primitive types. 60 * 61 * We have to generate the names for X[], X[][], X[][][], and so on. The 62 * easiest way to deal with that is to create the full name once and then 63 * subtract pieces off. Besides, we want to start with the outermost 64 * piece and work our way in. 65 */ 66 static void Dalvik_java_lang_reflect_Array_createMultiArray(const u4* args, 67 JValue* pResult) 68 { 69 ClassObject* elementClass = (ClassObject*) args[0]; 70 ArrayObject* dimArray = (ArrayObject*) args[1]; 71 ClassObject* arrayClass; 72 ArrayObject* newArray; 73 char* acDescriptor; 74 int numDim, i; 75 int* dimensions; 76 77 ALOGV("createMultiArray: '%s' [%d]", 78 elementClass->descriptor, dimArray->length); 79 80 assert(elementClass != NULL); // verified by caller 81 82 /* 83 * Verify dimensions. 84 * 85 * The caller is responsible for verifying that "dimArray" is non-null 86 * and has a length > 0 and <= 255. 87 */ 88 assert(dimArray != NULL); // verified by caller 89 numDim = dimArray->length; 90 assert(numDim > 0 && numDim <= 255); 91 92 dimensions = (int*)(void*)dimArray->contents; 93 for (i = 0; i < numDim; i++) { 94 if (dimensions[i] < 0) { 95 dvmThrowNegativeArraySizeException(dimensions[i]); 96 RETURN_VOID(); 97 } 98 LOGVV("DIM %d: %d", i, dimensions[i]); 99 } 100 101 /* 102 * Generate the full name of the array class. 103 */ 104 acDescriptor = 105 (char*) malloc(strlen(elementClass->descriptor) + numDim + 1); 106 memset(acDescriptor, '[', numDim); 107 108 LOGVV("#### element name = '%s'", elementClass->descriptor); 109 if (dvmIsPrimitiveClass(elementClass)) { 110 assert(elementClass->primitiveType != PRIM_NOT); 111 acDescriptor[numDim] = dexGetPrimitiveTypeDescriptorChar(elementClass->primitiveType); 112 acDescriptor[numDim+1] = '\0'; 113 } else { 114 strcpy(acDescriptor+numDim, elementClass->descriptor); 115 } 116 LOGVV("#### array name = '%s'", acDescriptor); 117 118 /* 119 * Find/generate the array class. 120 */ 121 arrayClass = dvmFindArrayClass(acDescriptor, elementClass->classLoader); 122 if (arrayClass == NULL) { 123 ALOGW("Unable to find or generate array class '%s'", acDescriptor); 124 assert(dvmCheckException(dvmThreadSelf())); 125 free(acDescriptor); 126 RETURN_VOID(); 127 } 128 free(acDescriptor); 129 130 /* create the array */ 131 newArray = dvmAllocMultiArray(arrayClass, numDim-1, dimensions); 132 if (newArray == NULL) { 133 assert(dvmCheckException(dvmThreadSelf())); 134 RETURN_VOID(); 135 } 136 137 dvmReleaseTrackedAlloc((Object*) newArray, NULL); 138 RETURN_PTR(newArray); 139 } 140 141 const DalvikNativeMethod dvm_java_lang_reflect_Array[] = { 142 { "createObjectArray", "(Ljava/lang/Class;I)Ljava/lang/Object;", 143 Dalvik_java_lang_reflect_Array_createObjectArray }, 144 { "createMultiArray", "(Ljava/lang/Class;[I)Ljava/lang/Object;", 145 Dalvik_java_lang_reflect_Array_createMultiArray }, 146 { NULL, NULL, NULL }, 147 }; 148