Beispiel #1
0
ObjectArray* Java_java_lang_Class_getDeclaredMethods0(Env* env, Class* clazz, jboolean publicOnly) {
    if (CLASS_IS_PRIMITIVE(clazz) || CLASS_IS_ARRAY(clazz)) return NULL;

    Method* methods = rvmGetMethods(env, clazz);
    if (rvmExceptionCheck(env)) return NULL;

    Method* method;
    jint length = 0;
    for (method = methods; method != NULL; method = method->next) {
        if (!METHOD_IS_CONSTRUCTOR(method) && !METHOD_IS_CLASS_INITIALIZER(method)) {
            if (!publicOnly || METHOD_IS_PUBLIC(method)) {
                length++;
            }
        }
    }

    ObjectArray* result = NULL;
    jint i = 0;
    for (method = methods; method != NULL; method = method->next) {
        if (!METHOD_IS_CONSTRUCTOR(method) && !METHOD_IS_CLASS_INITIALIZER(method)) {
            if (!publicOnly || METHOD_IS_PUBLIC(method)) {
                Object* c = createMethodObject(env, method);
                if (!c) return NULL;
                if (!result) {
                    result = rvmNewObjectArray(env, length, c->clazz, NULL, NULL);
                    if (!result) return NULL;
                }
                result->values[i++] = c;
            }
        }
    }

    return result;
}
Beispiel #2
0
Array* rvmAllocateMemoryForArray(Env* env, Class* arrayClass, jint length) {
    jint elementSize = rvmGetArrayElementSize(env, arrayClass);
    if (elementSize == 0) {
        return NULL;
    }
    jlong size = (jlong) sizeof(Array) + (jlong) length * (jlong) elementSize;
    if (size > (jlong) (size_t) -1) {
        rvmThrowOutOfMemoryError(env);
        return NULL;
    }
    Array* m = NULL;
    if (CLASS_IS_PRIMITIVE(arrayClass->componentType)) {
        // Primitive array objects contain no pointers except for the Class
        // pointer and possibly a fat monitor. Those are allocated uncollectably
        // and will be reachable even if we alocate this atomically.
        m = (Array*) gcAllocateKind((size_t) size, atomicObjectGCKind);
    } else if (length < 30) {
        // TODO: Use GC bitmap descriptor for small Object arrays.
        m = (Array*) gcAllocateKind((size_t) size, objectGCKind);
    } else {
        // Large Object array. Conservatively scanned. Only the lock (if thin) 
        // and the length fields could become a problem if they look like 
        // pointers into the heap.
        m = (Array*) gcAllocateKind((size_t) size, largeArrayGCKind);
    }
    if (!m) {
        rvmThrowOutOfMemoryError(env);
        return NULL;
    }
    return m;
}
Beispiel #3
0
ObjectArray* Java_java_lang_Class_getDeclaredFields0(Env* env, Class* clazz, jboolean publicOnly) {
    if (CLASS_IS_PRIMITIVE(clazz) || CLASS_IS_ARRAY(clazz)) return NULL;

    Field* fields = rvmGetFields(env, clazz);
    if (rvmExceptionCheck(env)) return NULL;

    Field* field;
    jint length = 0;
    for (field = fields; field != NULL; field = field->next) {
        if (!publicOnly || FIELD_IS_PUBLIC(field)) {
            length++;
        }
    }

    ObjectArray* result = NULL;
    jint i = 0;
    for (field = fields; field != NULL; field = field->next) {
        if (!publicOnly || FIELD_IS_PUBLIC(field)) {
            Object* c = createFieldObject(env, field);
            if (!c) return NULL;
            if (!result) {
                result = rvmNewObjectArray(env, length, c->clazz, NULL, NULL);
                if (!result) return NULL;
            }
            result->values[i++] = c;
        }
    }

    return result;
}
Beispiel #4
0
static Class* createArrayClass(Env* env, Class* componentType) {
    jint length = strlen(componentType->name);
    char* desc = NULL;

    if (CLASS_IS_ARRAY(componentType) || CLASS_IS_PRIMITIVE(componentType)) {
        desc = rvmAllocateMemoryAtomic(env, length + 2);
        if (!desc) return NULL;
        desc[0] = '[';
        strcat(desc, componentType->name);
    } else {
        desc = rvmAllocateMemoryAtomic(env, length + 4);
        if (!desc) return NULL;
        desc[0] = '[';
        desc[1] = 'L';
        strcat(desc, componentType->name);
        desc[length + 2] = ';';
    }

    // TODO: Add clone() method.
    Class* clazz = rvmAllocateClass(env, desc, java_lang_Object, componentType->classLoader, 
        CLASS_TYPE_ARRAY | CLASS_STATE_INITIALIZED | ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT, 
        sizeof(Class), sizeof(Object), sizeof(Object), 0, 0, NULL, NULL);
    if (!clazz) return NULL;
    clazz->componentType = componentType;
    // Initialize methods to NULL to prevent rvmGetMethods() from trying to load the methods if called with this array class
    clazz->_methods = NULL;
    if (!rvmAddInterface(env, clazz, java_lang_Cloneable)) return NULL;
    if (!rvmAddInterface(env, clazz, java_io_Serializable)) return NULL;
    if (!rvmRegisterClass(env, clazz)) return NULL;

    return clazz;
}
Beispiel #5
0
static jboolean parseElementValue(Env* env, void** attributes, Class* type, Object* classLoader, jvalue* result) {
    if (CLASS_IS_PRIMITIVE(type)) {
        switch (type->name[0]) {
        case 'Z':
            return parseBooleanElementValue(env, attributes, result);
        case 'B':
            return parseByteElementValue(env, attributes, result);
        case 'S':
            return parseShortElementValue(env, attributes, result);
        case 'C':
            return parseCharElementValue(env, attributes, result);
        case 'I':
            return parseIntElementValue(env, attributes, result);
        case 'J':
            return parseLongElementValue(env, attributes, result);
        case 'F':
            return parseFloatElementValue(env, attributes, result);
        case 'D':
            return parseDoubleElementValue(env, attributes, result);
        }
    } else if (CLASS_IS_ARRAY(type)) {
        return parseArrayElementValue(env, attributes, type, classLoader, result);
    } else if (type == java_lang_Class) {
        return parseClassElementValue(env, attributes, classLoader, result);
    } else if (type == java_lang_String) {
        return parseStringElementValue(env, attributes, result);
    } else if (CLASS_IS_ENUM(type) && type->superclass == java_lang_Enum) {
        return parseEnumElementValue(env, attributes, classLoader, result);
    } else if (CLASS_IS_ANNOTATION(type) && CLASS_IS_INTERFACE(type)) {
        return parseAnnotationElementValue(env, attributes, type, classLoader, result);
    }

    return FALSE;
}
Beispiel #6
0
ObjectArray* Java_java_lang_Class_getDeclaredClasses0(Env* env, Class* clazz, jboolean publicOnly) {
    if (CLASS_IS_PRIMITIVE(clazz) || CLASS_IS_ARRAY(clazz)) return NULL;
    ObjectArray* result = rvmAttributeGetDeclaredClasses(env, clazz);
    if (!result || result->length == 0 || !publicOnly) {
        return result;
    }

    jint length = 0;
    jint i;
    for (i = 0; i < result->length; i++) {
        Class* c = (Class*) result->values[i];
        if (CLASS_IS_PUBLIC(c)) {
            length++;
        }
    }

    if (length == 0) return NULL;

    ObjectArray* publicResult = rvmNewObjectArray(env, length, java_lang_Class, NULL, NULL);
    if (!publicResult) return NULL;
    jint index = 0;
    for (i = 0; i < result->length; i++) {
        Class* c = (Class*) result->values[i];
        if (CLASS_IS_PUBLIC(c)) {
            publicResult->values[index++] = (Object*) c;
        }
    }

    return publicResult;
}
Beispiel #7
0
static void heapDumpCallback(void* ptr, unsigned char kind, size_t sz, void* data) {
    if ((kind == GC_gcj_kind || kind == objectArrayGCKind) && ptr) {
        Object* obj = (Object*) ptr;
        if (obj->clazz) {
            if (obj->clazz == java_lang_Class) {
                Class* clazz = (Class*) obj;
                fprintf(stderr, "  n%p [label=\"Class %s]\n", clazz, clazz->name); //, clazz->classDataSize);
                if (clazz->_data) {
                    fprintf(stderr, "  n%p -> n%p\n", clazz, clazz->_data);
                }
                void** start = (void**) (((char*) clazz) + offsetof(Class, data));
                void** end = (void**) (((char*) start) + clazz->classRefCount * sizeof(Object*));
                dumpRefs(clazz, start, end);
            } else if (CLASS_IS_ARRAY(obj->clazz)) {
                if (obj->clazz->name[1] == 'C') {
                    // Array of chars. Include the 29 first characters in the dump.
                    char s[30];
                    memset(s, 0, sizeof(s));
                    jint length = ((Array*) obj)->length;
                    length = length > sizeof(s) - 1 ? sizeof(s) - 1 : length;
                    for (jint i = 0; i < length; i++) {
                        s[i] = (char) ((CharArray*) obj)->values[i];
                    }
                    fprintf(stderr, "  n%p [label=\"%s[%d] = %s\"]\n", obj, obj->clazz->name, ((Array*) obj)->length, s);
                } else {
                    fprintf(stderr, "  n%p [label=\"%s[%d]\"]\n", obj, obj->clazz->name, ((Array*) obj)->length);
                    if (!CLASS_IS_PRIMITIVE(obj->clazz->componentType)) {
                        ObjectArray* array = (ObjectArray*) obj;
                        void** start = (void**) (((char*) array) + offsetof(ObjectArray, values));
                        void** end = (void**) (((char*) start) + sizeof(Object*) * array->length);
                        dumpRefs(array, start, end);
                    }
                }
            } else {
                Class* clazz = obj->clazz;
                fprintf(stderr, "  n%p [label=\"Instance %s\"]\n", obj, obj->clazz->name);
                while (clazz != NULL) {
                    void** start = (void**) (((char*) obj) + clazz->instanceDataOffset);
                    void** end = (void**) (((char*) start) + clazz->instanceRefCount * sizeof(Object*));
                    if (clazz == java_lang_ref_Reference) {
                        void** referent_start = (void**) (((char*) obj) + java_lang_ref_Reference_referent->offset);
                        void** referent_end = (void**) (((char*) referent_start) + sizeof(Object*));
                        //if (*referent_start) {
                            //fprintf(stderr, "\t%p (weak)\n", *referent_start);
                        //}
                        dumpRefs(obj, start, referent_start);
                        dumpRefs(obj, referent_end, end);
                    } else {
                        dumpRefs(obj, start, end);
                    }
                    clazz = clazz->superclass;
                }
            }
        }
    }
}
Beispiel #8
0
static struct GC_ms_entry* markObject(GC_word* addr, struct GC_ms_entry* mark_stack_ptr, struct GC_ms_entry* mark_stack_limit, GC_word env) {
    Object* obj = (Object*) addr;

    if (obj == NULL || obj->clazz == NULL || obj->clazz->object.clazz != java_lang_Class) {
        // According to the comments in gc_mark.h the GC sometimes calls the mark_proc with unused objects.
        // Such objects have been cleared except for the first word which points to a free list link field.
        // A valid RovoVM Object must point to a Class and the Class of the Object's Class must be java.lang.Class.
        return mark_stack_ptr;
    }

    mark_stack_ptr = GC_MARK_AND_PUSH(obj->clazz, mark_stack_ptr, mark_stack_limit, NULL);

    if (obj->clazz == java_lang_Class) {
        // Class*
        Class* clazz = (Class*) obj;
        mark_stack_ptr = GC_MARK_AND_PUSH(clazz->_data, mark_stack_ptr, mark_stack_limit, NULL);
        mark_stack_ptr = GC_MARK_AND_PUSH((void*) clazz->name, mark_stack_ptr, mark_stack_limit, NULL);
        mark_stack_ptr = GC_MARK_AND_PUSH(clazz->classLoader, mark_stack_ptr, mark_stack_limit, NULL);
        mark_stack_ptr = GC_MARK_AND_PUSH(clazz->superclass, mark_stack_ptr, mark_stack_limit, NULL);
        mark_stack_ptr = GC_MARK_AND_PUSH(clazz->componentType, mark_stack_ptr, mark_stack_limit, NULL);
        mark_stack_ptr = GC_MARK_AND_PUSH(clazz->_interfaces, mark_stack_ptr, mark_stack_limit, NULL);
        mark_stack_ptr = GC_MARK_AND_PUSH(clazz->_fields, mark_stack_ptr, mark_stack_limit, NULL);
        mark_stack_ptr = GC_MARK_AND_PUSH(clazz->_methods, mark_stack_ptr, mark_stack_limit, NULL);
        void** start = (void**) (((char*) clazz) + offsetof(Class, data));
        void** end = (void**) (((char*) start) + clazz->classRefCount * sizeof(Object*));
        mark_stack_ptr = markRegion(start, end, mark_stack_ptr, mark_stack_limit);
    } else if (CLASS_IS_ARRAY(obj->clazz)) {
        if (!CLASS_IS_PRIMITIVE(obj->clazz->componentType)) {
            // Array of objects. Mark all values in the array.
            ObjectArray* array = (ObjectArray*) obj;
            void** start = (void**) (((char*) array) + offsetof(ObjectArray, values));
            void** end = (void**) (((char*) start) + sizeof(Object*) * array->length);
            mark_stack_ptr = markRegion(start, end, mark_stack_ptr, mark_stack_limit);
        }
    } else {
        // Object* - for each Class in the hierarchy of obj's Class we mark the first instanceRefCount*sizeof(Object*) bytes
        Class* clazz = obj->clazz;
        while (clazz != NULL) {
            void** start = (void**) (((char*) obj) + clazz->instanceDataOffset);
            void** end = (void**) (((char*) start) + clazz->instanceRefCount * sizeof(Object*));
            if (clazz == java_lang_ref_Reference) {
                // Don't mark the referent field
                void** referent_start = (void**) (((char*) obj) + java_lang_ref_Reference_referent->offset);
                void** referent_end = (void**) (((char*) referent_start) + sizeof(Object*));
                mark_stack_ptr = markRegion(start, referent_start, mark_stack_ptr, mark_stack_limit);
                mark_stack_ptr = markRegion(referent_end, end, mark_stack_ptr, mark_stack_limit);
            } else {
                mark_stack_ptr = markRegion(start, end, mark_stack_ptr, mark_stack_limit);
            }
            clazz = clazz->superclass;
        }
    }

    return mark_stack_ptr;
}
Beispiel #9
0
static ObjectArray* listClasses(Env* env, Class* instanceofClazz, ClassLoader* classLoader, void* hash) {
    if (instanceofClazz && (CLASS_IS_ARRAY(instanceofClazz) || CLASS_IS_PRIMITIVE(instanceofClazz))) {
        return NULL;
    }
    ClassInfoHeader** base = getClassInfosBase(hash);
    uint32_t count = getClassInfosCount(hash);
    uint32_t i = 0;
    jint matches = count;
    TypeInfo* instanceofTypeInfo = instanceofClazz ? instanceofClazz->typeInfo : NULL;
    if (instanceofTypeInfo) {
        matches = 0;
        for (i = 0; i < count; i++) {
            ClassInfoHeader* header = base[i];
            if ((header->flags & CI_ERROR) == 0) {
                if ((!CLASS_IS_INTERFACE(instanceofClazz) 
                    && rvmIsClassTypeInfoAssignable(env, header->typeInfo, instanceofTypeInfo))
                    || (CLASS_IS_INTERFACE(instanceofClazz) 
                    && rvmIsInterfaceTypeInfoAssignable(env, header->typeInfo, instanceofTypeInfo))) {

                    matches++;
                }
            }
        }
    }

    if (matches == 0) return NULL;
    ObjectArray* result = rvmNewObjectArray(env, matches, java_lang_Class, NULL, NULL);
    if (!result) return NULL;

    jint j = 0;
    for (i = 0; i < count; i++) {
        ClassInfoHeader* header = base[i];
        if ((header->flags & CI_ERROR) == 0) {
            if (!instanceofTypeInfo || ((!CLASS_IS_INTERFACE(instanceofClazz) 
                && rvmIsClassTypeInfoAssignable(env, header->typeInfo, instanceofTypeInfo))
                || (CLASS_IS_INTERFACE(instanceofClazz) 
                && rvmIsInterfaceTypeInfoAssignable(env, header->typeInfo, instanceofTypeInfo)))) {

                result->values[j++] = (Object*) (header->clazz ? header->clazz : createClass(env, header, classLoader));
                if (rvmExceptionOccurred(env)) return NULL;
            }
        }
    }
    return result;
}
Beispiel #10
0
jboolean rvmIsAssignableFrom(Env* env, Class* s, Class* t) {
    // TODO: What if s or t are NULL?
    if (s == t || t == java_lang_Object) {
        return TRUE;
    }

    if (CLASS_IS_ARRAY(s)) {
        if (t == java_io_Serializable) {
            return TRUE;
        }
        if (t == java_lang_Cloneable) {
            return TRUE;
        }
        if (!CLASS_IS_ARRAY(t)) {
            return FALSE;
        }
        Class* componentType = s->componentType;
        if (CLASS_IS_PRIMITIVE(componentType)) {
            // s is a primitive array and can only be assigned to 
            // class t if s == t or t == (Object|Serializable|Cloneable). But we 
            // already know that s != t and t != (Object|Serializable|Cloneable)
            return FALSE;
        }
        return rvmIsAssignableFrom(env, componentType, t->componentType);
    }

    if (CLASS_IS_INTERFACE(t)) {
        // s or any of its parents must implement the interface t
        for (; s; s = s->superclass) {
            Interface* interface = rvmGetInterfaces(env, s);
            if (rvmExceptionCheck(env)) return FALSE;
            for (; interface != NULL; interface = interface->next) {
                if (rvmIsAssignableFrom(env, interface->interface, t)) {
                    return TRUE;
                }
            }
        }
        return FALSE;
    }

    while (s && s != t) {
        s = s->superclass;
    }
    return s ? TRUE : FALSE;
}
Beispiel #11
0
jvalue* validateAndUnwrapArgs(Env* env, ObjectArray* parameterTypes, ObjectArray* args) {
    jint length = args->length;
    jvalue* jvalueArgs = length > 0 ? (jvalue*) rvmAllocateMemory(env, sizeof(jvalue) * length) : emptyJValueArgs;
    if (!jvalueArgs) return NULL;

    jint i;
    for (i = 0; i < length; i++) {
        Object* arg = args->values[i];
        Class* type = (Class*) parameterTypes->values[i];
        if (CLASS_IS_PRIMITIVE(type)) {
            if (arg == NULL) {
                const char* typeName = rvmGetHumanReadableClassName(env, type);
                if (typeName) {
                    rvmThrowNewf(env, java_lang_IllegalArgumentException, 
                        "argument %d should have type %s, got null", i + 1, typeName);
                }
                return NULL;
            }
            if (!rvmUnbox(env, arg, type, &jvalueArgs[i])) {
                if (rvmExceptionOccurred(env)->clazz == java_lang_ClassCastException) {
                    rvmExceptionClear(env);
                    const char* argTypeName = rvmGetHumanReadableClassName(env, arg->clazz);
                    const char* typeName = argTypeName ? rvmGetHumanReadableClassName(env, type) : NULL;
                    if (argTypeName && typeName) {
                        rvmThrowNewf(env, java_lang_IllegalArgumentException, 
                            "argument %d should have type %s, got %s", i + 1, typeName, argTypeName);
                    }
                }
                return NULL;
            }
        } else {
            if (arg && !rvmIsInstanceOf(env, arg, type)) {
                const char* argTypeName = rvmGetHumanReadableClassName(env, arg->clazz);
                const char* typeName = argTypeName ? rvmGetHumanReadableClassName(env, type) : NULL;
                if (argTypeName && typeName) {
                    rvmThrowNewf(env, java_lang_IllegalArgumentException, 
                        "argument %d should have type %s, got %s", i + 1, typeName, argTypeName);
                }
                return NULL;
            }
            jvalueArgs[i].l = (jobject) arg;
        }
    }
    return jvalueArgs;
}
Beispiel #12
0
static void heapDumpCallback(void* ptr, unsigned char kind, size_t sz, void* data) {
    if (kind == objectGCKind || kind == largeArrayGCKind || kind == atomicObjectGCKind) {
        Object* obj = (Object*) ptr;
        if (obj->clazz == java_lang_Class) {
            Class* clazz = (Class*) obj;
            fprintf(stderr, "%p (class %s of size %d bytes)\n", clazz, clazz->name, clazz->classDataSize);
            if (clazz->_data) {
                fprintf(stderr, "\t%p\n", clazz->_data);
            }
            void** start = (void**) (((char*) clazz) + offsetof(Class, data));
            void** end = (void**) (((char*) start) + clazz->classRefCount * sizeof(Object*));
            dumpRefs(start, end);
        } else if (CLASS_IS_ARRAY(obj->clazz)) {
            fprintf(stderr, "%p (array of type %s of length %d elements)\n", obj, obj->clazz->name, ((Array*) obj)->length);
            if (!CLASS_IS_PRIMITIVE(obj->clazz->componentType)) {
                ObjectArray* array = (ObjectArray*) obj;
                void** start = (void**) (((char*) array) + offsetof(ObjectArray, values));
                void** end = (void**) (((char*) start) + sizeof(Object*) * array->length);
                dumpRefs(start, end);
            }
        } else {
            Class* clazz = obj->clazz;
            fprintf(stderr, "%p (object of type %s of size %d bytes)\n", obj, clazz->name, clazz->instanceDataSize);
            while (clazz != NULL) {
                void** start = (void**) (((char*) obj) + clazz->instanceDataOffset);
                void** end = (void**) (((char*) start) + clazz->instanceRefCount * sizeof(Object*));
                if (clazz == java_lang_ref_Reference) {
                    void** referent_start = (void**) (((char*) obj) + java_lang_ref_Reference_referent->offset);
                    void** referent_end = (void**) (((char*) referent_start) + sizeof(Object*));
                    if (*referent_start) {
                        fprintf(stderr, "\t%p (weak)\n", *referent_start);
                    }
                    dumpRefs(start, referent_start);
                    dumpRefs(referent_end, end);
                } else {
                    dumpRefs(start, end);
                }
                clazz = clazz->superclass;
            }
        }
    }
}
Beispiel #13
0
Object* rvmBox(Env* env, Class* type, jvalue* value) {
    if (CLASS_IS_PRIMITIVE(type)) {
        switch (type->name[0]) {
        case 'Z':
            return (Object*) rvmBoxBoolean(env, value->z);
        case 'B':
            return (Object*) rvmBoxByte(env, value->b);
        case 'S':
            return (Object*) rvmBoxShort(env, value->s);
        case 'C':
            return (Object*) rvmBoxChar(env, value->c);
        case 'I':
            return (Object*) rvmBoxInt(env, value->i);
        case 'J':
            return (Object*) rvmBoxLong(env, value->j);
        case 'F':
            return (Object*) rvmBoxFloat(env, value->f);
        case 'D':
            return (Object*) rvmBoxDouble(env, value->d);
        }
    }
    return (Object*) value->l;
}
Beispiel #14
0
 * Destroy a class object.
 */
static void
/* ARGSUSED */
destroyClass(Collector *collector, void* c)
{
        int i;
	unsigned int idx;
	Hjava_lang_Class* clazz = c;
	constants* pool;

DBG(CLASSGC,
        dprintf("destroying class %s @ %p\n",
		clazz->name ? clazz->name->data : "newborn", c);
   );
	assert(!CLASS_IS_PRIMITIVE(clazz)); 

	/* NB: Make sure that we don't unload fully loaded classes without
	 * classloaders.  This is wrong and indicate of a bug.
	 *
	 * NB: Note that this function must destroy any partially
	 * initialized class.  Class processing may fail at any
	 * state, and the discarded class objects destroyed.
	 */
	assert(clazz->state != CSTATE_COMPLETE || clazz->loader != 0);

#if defined(ENABLE_JVMPI)
	if( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_CLASS_UNLOAD) && clazz->state >= CSTATE_PREPARED)
	{
		JVMPI_Event ev;
Beispiel #15
0
static jboolean parseArrayElementValue(Env* env, void** attributes, Class* arrayClass, Object* classLoader, jvalue* result) {
    jbyte tag = getByte(attributes);
    if (tag != '[') return throwFormatError(env, "Array");

    Class* componentType = arrayClass->componentType;

    jint length = getChar(attributes);
    Array* array = NULL;
    if (CLASS_IS_PRIMITIVE(componentType)) {
        switch (componentType->name[0]) {
        case 'Z':
            array = (Array*) rvmNewBooleanArray(env, length);
            break;
        case 'B':
            array = (Array*) rvmNewByteArray(env, length);
            break;
        case 'S':
            array = (Array*) rvmNewShortArray(env, length);
            break;
        case 'C':
            array = (Array*) rvmNewCharArray(env, length);
            break;
        case 'I':
            array = (Array*) rvmNewIntArray(env, length);
            break;
        case 'J':
            array = (Array*) rvmNewLongArray(env, length);
            break;
        case 'F':
            array = (Array*) rvmNewFloatArray(env, length);
            break;
        case 'D':
            array = (Array*) rvmNewDoubleArray(env, length);
            break;
        }
    } else {
        array = (Array*) rvmNewObjectArray(env, length, NULL, arrayClass, NULL);
    }
    if (!array) return FALSE;

    jint i = 0;
    for (i = 0; i < length; i++) {
        jvalue v;
        if (!parseElementValue(env, attributes, componentType, classLoader, &v)) return FALSE;
        if (CLASS_IS_PRIMITIVE(componentType)) {
            switch (componentType->name[0]) {
            case 'Z':
                ((BooleanArray*) array)->values[i] = v.z;
                break;
            case 'B':
                ((ByteArray*) array)->values[i] = v.b;
                break;
            case 'S':
                ((ShortArray*) array)->values[i] = v.s;
                break;
            case 'C':
                ((CharArray*) array)->values[i] = v.c;
                break;
            case 'I':
                ((IntArray*) array)->values[i] = v.i;
                break;
            case 'J':
                ((LongArray*) array)->values[i] = v.j;
                break;
            case 'F':
                ((FloatArray*) array)->values[i] = v.f;
                break;
            case 'D':
                ((DoubleArray*) array)->values[i] = v.d;
                break;
            }
        } else {
            ((ObjectArray*) array)->values[i] = (Object*) v.l;
        }
    }
    result->l = (jobject) array;
    return result->l ? TRUE : FALSE;
}
Beispiel #16
0
jboolean Java_java_lang_Class_isPrimitive(Env* env, Class* thiz) {
    return CLASS_IS_PRIMITIVE(thiz) ? TRUE : FALSE;
}
Beispiel #17
0
void rvmInitialize(Env* env, Class* clazz) {
    obtainClassLock();
    // TODO: Throw java.lang.NoClassDefFoundError if state == CLASS_ERROR?
    if (CLASS_IS_STATE_ERROR(clazz)) {
        // TODO: Add the class' binary name in the message
        rvmThrowNew(env, java_lang_NoClassDefFoundError, "Could not initialize class ??");
        releaseClassLock();
        return;
    }
    if (!CLASS_IS_STATE_INITIALIZED(clazz) && !CLASS_IS_STATE_INITIALIZING(clazz)) {
        jint oldState = clazz->flags & CLASS_STATE_MASK;
        clazz->flags = (clazz->flags & (~CLASS_STATE_MASK)) | CLASS_STATE_INITIALIZING;
        if (clazz->superclass) {
            rvmInitialize(env, clazz->superclass);
            if (rvmExceptionOccurred(env)) {
                clazz->flags = (clazz->flags & (~CLASS_STATE_MASK)) | oldState;
                releaseClassLock();
                return;
            }
        }

        TRACEF("Initializing class %s", clazz->name);
        void* initializer = clazz->initializer;
        if (!initializer) {
            if (!CLASS_IS_ARRAY(clazz) && !CLASS_IS_PROXY(clazz) && !CLASS_IS_PRIMITIVE(clazz)) {
                env->vm->options->classInitialized(env, clazz);
            }
            clazz->flags = (clazz->flags & (~CLASS_STATE_MASK)) | CLASS_STATE_INITIALIZED;
            releaseClassLock();
            return;
        }

        CallInfo* callInfo = call0AllocateCallInfo(env, initializer, 1, 0, 0, 0, 0);
        call0AddPtr(callInfo, env);
        void (*f)(CallInfo*) = (void (*)(CallInfo*)) _call0;
        rvmPushGatewayFrame(env);
        TrycatchContext tc = {0};
        tc.sel = CATCH_ALL_SEL;
        if (!rvmTrycatchEnter(env, &tc)) {
            f(callInfo);
        }
        rvmTrycatchLeave(env);
        rvmPopGatewayFrame(env);

        Object* exception = rvmExceptionClear(env);
        if (exception) {
            clazz->flags = (clazz->flags & (~CLASS_STATE_MASK)) | CLASS_STATE_ERROR;
            if (!rvmIsInstanceOf(env, exception, java_lang_Error)) {
                // If exception isn't an instance of java.lang.Error 
                // we must wrap it in a java.lang.ExceptionInInitializerError
                Method* constructor = rvmGetInstanceMethod(env, java_lang_ExceptionInInitializerError, "<init>", "(Ljava/lang/Throwable;)V");
                if (!constructor) return;
                Object* wrappedException = rvmNewObject(env, java_lang_ExceptionInInitializerError, constructor, exception);
                if (!wrappedException) return;
                exception = wrappedException;
            }
            rvmThrow(env, exception);
            releaseClassLock();
            return;
        }
        if (!CLASS_IS_ARRAY(clazz) && !CLASS_IS_PROXY(clazz) && !CLASS_IS_PRIMITIVE(clazz)) {
            env->vm->options->classInitialized(env, clazz);
        }
        clazz->flags = (clazz->flags & (~CLASS_STATE_MASK)) | CLASS_STATE_INITIALIZED;
    }
    releaseClassLock();
}
Beispiel #18
0
void
java_lang_VMSystem_arraycopy0(struct Hjava_lang_Object* src,
			      jint srcpos,
			      struct Hjava_lang_Object* dst,
			      jint dstpos,
			      jint len)
{
	char* in; 	 
	char* out; 	 
	int elemsz; 	 
	Hjava_lang_Class* sclass; 	 
	Hjava_lang_Class* dclass;

	sclass = OBJECT_CLASS(src); 	 
	dclass = OBJECT_CLASS(dst);

	sclass = Kaffe_get_array_element_type(sclass); 	 
	dclass = Kaffe_get_array_element_type(dclass); 	 
	elemsz = TYPE_SIZE(sclass); 	 

	len *= elemsz; 	 
	srcpos *= elemsz; 	 
	dstpos *= elemsz; 	 

	in = &((char*)ARRAY_DATA(src))[srcpos]; 	 
	out = &((char*)ARRAY_DATA(dst))[dstpos];

	if (sclass == dclass) {
#if defined(HAVE_MEMMOVE) 	 
		memmove((void*)out, (void*)in, (size_t)len); 	 
#else 	 
		/* Do it ourself */ 	 
#if defined(HAVE_MEMCPY) 	 
		if (src != dst) { 	 
			memcpy((void*)out, (void*)in, (size_t)len); 	 
		} else 	 
#endif 	 
		if (out < in) { 	 
			/* Copy forwards */ 	 
			for (; len > 0; len--) { 	 
				*out++ = *in++; 	 
			} 	 
		} else { 	 
			/* Copy backwards */ 	 
			out += len; 	 
			in += len; 	 
			for (; len > 0; len--) { 	 
				*--out = *--in; 	 
			} 	 
		} 	 
#endif 	 
	} else {
		if (CLASS_IS_PRIMITIVE(sclass) || CLASS_IS_PRIMITIVE(dclass)) {
		  Hjava_lang_Throwable* asexc;
		  const char *stype = CLASS_CNAME(sclass);
		  const char *dtype = CLASS_CNAME(dclass);
		  char *b;
#define _FORMAT "incompatible array types `%s' and `%s'"
		  b = checkPtr(KMALLOC(strlen(stype)+strlen(dtype)+strlen(_FORMAT)));
		  sprintf(b, _FORMAT, stype, dtype);
#undef _FORMAT
		  asexc = ArrayStoreException(b);
		  KFREE(b);
		  throwException(asexc);
		}

		for (; len > 0; len -= sizeof(Hjava_lang_Object*)) { 	 
			Hjava_lang_Object* val = *(Hjava_lang_Object**)in; 	 
			if (val != 0 && !instanceof(dclass, OBJECT_CLASS(val))) { 	 
			  Hjava_lang_Throwable* asexc;
			  const char *vtype = CLASS_CNAME(OBJECT_CLASS(val));
			  const char *atype = CLASS_CNAME(dclass);
			  char *b;
#define _FORMAT "can't store `%s' in array of type `%s'"
			  b = checkPtr(KMALLOC(strlen(vtype)+strlen(atype)+strlen(_FORMAT)));
			  sprintf(b, _FORMAT, vtype, atype);
#undef _FORMAT
			  asexc = ArrayStoreException(b);
			  KFREE(b);
			  throwException(asexc);
			}
			*(Hjava_lang_Object**)out = val; 	 
			in += sizeof(Hjava_lang_Object*); 	 
			out += sizeof(Hjava_lang_Object*); 	 
		}
	}
}