示例#1
0
/*
 * Find the return type in the signature, and convert it to a class
 * object.  For primitive types we use a boxed class, for reference types
 * we do a name lookup.
 *
 * On failure, we return NULL with an exception raised.
 */
ClassObject* dvmGetBoxedReturnType(const Method* meth)
{
    const char* sig = dexProtoGetReturnType(&meth->prototype);

    switch (*sig) {
    case 'Z':
    case 'C':
    case 'F':
    case 'D':
    case 'B':
    case 'S':
    case 'I':
    case 'J':
    case 'V':
        return dvmFindPrimitiveClass(*sig);
    case '[':
    case 'L':
        return dvmFindClass(sig, meth->clazz->classLoader);
    default: {
        /* should not have passed verification */
        char* desc = dexProtoCopyMethodDescriptor(&meth->prototype);
        ALOGE("Bad return type in signature '%s'", desc);
        free(desc);
        dvmThrowInternalError(NULL);
        return NULL;
    }
    }
}
示例#2
0
GOTO_TARGET(filledNewArray, bool methodCallRange, bool)
    {
        ClassObject* arrayClass;
        ArrayObject* newArray;
        u4* contents;
        char typeCh;
        int i;
        u4 arg5;

        EXPORT_PC();

        ref = FETCH(1);             /* class ref */
        vdst = FETCH(2);            /* first 4 regs -or- range base */

        if (methodCallRange) {
            vsrc1 = INST_AA(inst);  /* #of elements */
            arg5 = -1;              /* silence compiler warning */
            ILOGV("|filled-new-array-range args=%d @0x%04x {regs=v%d-v%d}",
                vsrc1, ref, vdst, vdst+vsrc1-1);
        } else {
            arg5 = INST_A(inst);
            vsrc1 = INST_B(inst);   /* #of elements */
            ILOGV("|filled-new-array args=%d @0x%04x {regs=0x%04x %x}",
               vsrc1, ref, vdst, arg5);
        }

        /*
         * Resolve the array class.
         */
        arrayClass = dvmDexGetResolvedClass(methodClassDex, ref);
        if (arrayClass == NULL) {
            arrayClass = dvmResolveClass(curMethod->clazz, ref, false);
            if (arrayClass == NULL)
                GOTO_exceptionThrown();
        }
        /*
        if (!dvmIsArrayClass(arrayClass)) {
            dvmThrowRuntimeException(
                "filled-new-array needs array class");
            GOTO_exceptionThrown();
        }
        */
        /* verifier guarantees this is an array class */
        assert(dvmIsArrayClass(arrayClass));
        assert(dvmIsClassInitialized(arrayClass));

        /*
         * Create an array of the specified type.
         */
        LOGVV("+++ filled-new-array type is '%s'", arrayClass->descriptor);
        typeCh = arrayClass->descriptor[1];
        if (typeCh == 'D' || typeCh == 'J') {
            /* category 2 primitives not allowed */
            dvmThrowRuntimeException("bad filled array req");
            GOTO_exceptionThrown();
        } else if (typeCh != 'L' && typeCh != '[' && typeCh != 'I') {
            /* TODO: requires multiple "fill in" loops with different widths */
            ALOGE("non-int primitives not implemented");
            dvmThrowInternalError(
                "filled-new-array not implemented for anything but 'int'");
            GOTO_exceptionThrown();
        }

        newArray = dvmAllocArrayByClass(arrayClass, vsrc1, ALLOC_DONT_TRACK);
        if (newArray == NULL)
            GOTO_exceptionThrown();

        /*
         * Fill in the elements.  It's legal for vsrc1 to be zero.
         */
        contents = (u4*)(void*)newArray->contents;
        if (methodCallRange) {
            for (i = 0; i < vsrc1; i++)
                contents[i] = GET_REGISTER(vdst+i);
        } else {
            assert(vsrc1 <= 5);
            if (vsrc1 == 5) {
                contents[4] = GET_REGISTER(arg5);
                vsrc1--;
            }
            for (i = 0; i < vsrc1; i++) {
                contents[i] = GET_REGISTER(vdst & 0x0f);
                vdst >>= 4;
            }
        }
        if (typeCh == 'L' || typeCh == '[') {
            dvmWriteBarrierArray(newArray, 0, newArray->length);
        }

        retval.l = (Object*)newArray;
    }