/*
* 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 },
};