示例#1
0
文件: attribute.c 项目: Zubnix/aura
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;
}
示例#2
0
文件: bc.c 项目: SinoJerk/robovm
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;
}
示例#3
0
文件: class.c 项目: John-Chan/robovm
Object* rvmAllocateObject(Env* env, Class* clazz) {
    if (CLASS_IS_ABSTRACT(clazz) || CLASS_IS_INTERFACE(clazz)) {
        // TODO: Message
        rvmThrowNew(env, java_lang_InstantiationException, "");
        return NULL;
    }
    rvmInitialize(env, clazz);
    if (rvmExceptionOccurred(env)) return NULL;
    Object* obj = rvmAllocateMemoryForObject(env, clazz);
    if (!obj) return NULL;
    obj->clazz = clazz;
    return obj;
}
示例#4
0
/**
 * Allocate an object and execute the constructor.
 *
 * @param cname the name of the class to be instantiated (may be 0 if cc is != 0)
 * @param loader the class loader that's to be used to lookup the class
 * @param cc the class to be instantiated (may be 0 if cname is != 0)
 * @param signature the signature of the constructor to be executed
 * @param argptr arguments to be passed to the constructor
 *
 * @throws InstantiationException if class is an interface or abstract
 * @throws NoSuchMethodError if the specified constructor cannot be found
 *
 * @return the newly allocated object
 */
Hjava_lang_Object*
execute_java_constructor_v(const char* cname, Hjava_lang_ClassLoader* loader,
	Hjava_lang_Class* cc, const char* signature, va_list argptr)
{
	Hjava_lang_Object* obj;
	Method* mb;
	jvalue retval;
	errorInfo info;
	Utf8Const* sig;

	if (cc == 0) {
		char *buf;

		/* Convert "." to "/" and lookup class */
		buf = checkPtr(KMALLOC(strlen(cname) + 1));
		classname2pathname(cname, buf);
		cc = lookupClass(buf, loader, &info);
		KFREE(buf);
		if (!cc) {
			throwError(&info);
		}
	}

	/* We cannot construct interfaces or abstract classes */
	if (CLASS_IS_INTERFACE(cc) || CLASS_IS_ABSTRACT(cc)) {
		throwException(InstantiationException(cc->name->data));
	}

	if (cc->state < CSTATE_USABLE) {
		if (processClass(cc, CSTATE_COMPLETE, &info) == false) {
			throwError(&info);
		}
	}

	sig = checkPtr(utf8ConstFromString(signature));
	mb = findMethodLocal(cc, constructor_name, sig);
	utf8ConstRelease(sig);
	if (mb == 0) {
		throwException(NoSuchMethodError(constructor_name->data));
	}

	obj = newObject(cc);
	assert(obj != 0);

	/* Make the call */
	KaffeVM_callMethodV(mb, METHOD_NATIVECODE(mb), obj, argptr, &retval);

	return (obj);
}
示例#5
0
文件: class.c 项目: John-Chan/robovm
jboolean rvmAddInterface(Env* env, Class* clazz, Class* interf) {
    if (!CLASS_IS_INTERFACE(interf)) {
        // TODO: Message should look like ?
        rvmThrowIncompatibleClassChangeError(env, "");
        return FALSE;
    }
    Interface* interface = rvmAllocateMemory(env, sizeof(Interface));
    if (!interface) return FALSE;
    interface->interface = interf;
    if (clazz->_interfaces == &INTERFACES_NOT_LOADED) {
        clazz->_interfaces = NULL;
    }
    LL_APPEND(clazz->_interfaces, interface);
    return TRUE;
}
示例#6
0
文件: class.c 项目: John-Chan/robovm
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;
}
示例#7
0
文件: class.c 项目: John-Chan/robovm
Class* rvmAllocateClass(Env* env, const char* className, Class* superclass, ClassLoader* classLoader, jint flags, 
        jint classDataSize, jint instanceDataSize, jint instanceDataOffset, unsigned short classRefCount, 
        unsigned short instanceRefCount, void* attributes, void* initializer) {

    if (superclass && CLASS_IS_INTERFACE(superclass)) {
        // TODO: Message should look like ?
        rvmThrowIncompatibleClassChangeError(env, "");
        return NULL;
    }

    Class* clazz = rvmAllocateMemoryForClass(env, classDataSize);
    if (!clazz) return NULL;

    /*
     * NOTE: All classes we load before we have cached java.lang.Class will have NULL here so it is 
     * important that we cache java.lang.Class as soon as possible. However, we have to cache
     * java.lang.Object first since it is the superclass of java.lang.Class. This means that
     * the java_lang_Object global variable will actually have NULL as clazz until we fix this in
     * rvmInitClasses().
     */
    clazz->object.clazz = java_lang_Class;
    clazz->name = className;
    clazz->superclass = superclass;
    clazz->classLoader = classLoader;
    clazz->flags = flags;
    clazz->classDataSize = classDataSize;
    clazz->instanceDataSize = instanceDataSize;
    clazz->instanceDataOffset = instanceDataOffset;
    clazz->classRefCount = classRefCount;
    clazz->instanceRefCount = instanceRefCount;
    clazz->_interfaces = &INTERFACES_NOT_LOADED;
    clazz->_fields = &FIELDS_NOT_LOADED;
    clazz->_methods = &METHODS_NOT_LOADED;
    clazz->attributes = attributes;
    clazz->initializer = initializer;

    // Inherit the CLASS_FLAG_FINALIZABLE flag from the superclass
    if (superclass && !CLASS_IS_FINALIZABLE(clazz) && CLASS_IS_FINALIZABLE(superclass)) {
        clazz->flags |= CLASS_FLAG_FINALIZABLE;
    }

    return clazz;
}
示例#8
0
static Method* getMethod(Env* env, Class* clazz, const char* name, const char* desc) {
    if (!strcmp("<init>", name) || !strcmp("<clinit>", name)) {
        // Constructors and static initializers are not inherited so we shouldn't check with the superclasses.
        return findMethod(env, clazz, name, desc);
    }

    Class* c = clazz;
    for (c = clazz; c != NULL; c = c->superclass) {
        Method* method = findMethod(env, c, name, desc);
        if (rvmExceptionCheck(env)) return NULL;
        if (method) return method;
    }

    /*
     * Check with interfaces.
     * TODO: Should we really do this? Does the JNI GetMethodID() function do this?
     */
    for (c = clazz; c != NULL; c = c->superclass) {
        Interface* interfaze = rvmGetInterfaces(env, c);
        if (rvmExceptionCheck(env)) return NULL;
        for (; interfaze != NULL; interfaze = interfaze->next) {
            Method* method = getMethod(env, interfaze->interfaze, name, desc);
            if (rvmExceptionCheck(env)) return NULL;
            if (method) return method;
        }
    }

    if (CLASS_IS_INTERFACE(clazz)) {
        /*
         * Class is an interface so check with java.lang.Object.
         * TODO: Should we really do this? Does the JNI GetMethodID() function do this?
         */
        return getMethod(env, java_lang_Object, name, desc);
    }

    return NULL;
}
示例#9
0
jboolean Java_java_lang_Class_isInterface(Env* env, Class* thiz) {
    return CLASS_IS_INTERFACE(thiz) ? TRUE : FALSE;
}