コード例 #1
0
ファイル: bc.c プロジェクト: SinoJerk/robovm
static void wrapClassNotFoundException(Env* env, const char* className) {
    Object* exception = rvmExceptionOccurred(env);
    if (exception && exception->clazz == java_lang_ClassNotFoundException) {
        // If ClassNotFoundException is thrown we have to wrap it in a NoClassDefFoundError
        exception = rvmExceptionClear(env);
        Method* constructor = rvmGetInstanceMethod(env, java_lang_NoClassDefFoundError, "<init>", "(Ljava/lang/String;)V");
        if (!constructor) return;
        Object* message = rvmNewStringUTF(env, className, -1);
        if (!message) return;
        Object* wrappedException = rvmNewObject(env, java_lang_NoClassDefFoundError, constructor, message);
        if (!wrappedException) return;
        Class* java_lang_StackTraceElement = rvmFindClassUsingLoader(env, "java/lang/StackTraceElement", NULL);
        if (!java_lang_StackTraceElement) return;
        ObjectArray* stackTrace = rvmNewObjectArray(env, 0, java_lang_StackTraceElement, NULL, NULL);
        if (!stackTrace) return;
        Method* setStackTrace = rvmGetInstanceMethod(env, java_lang_Throwable, "setStackTrace", "([Ljava/lang/StackTraceElement;)V");
        if (!setStackTrace) return;
        rvmCallVoidInstanceMethod(env, wrappedException, setStackTrace, stackTrace);
        if (rvmExceptionCheck(env)) return;
        Method* initCause = rvmGetInstanceMethod(env, java_lang_NoClassDefFoundError, "initCause", "(Ljava/lang/Throwable;)Ljava/lang/Throwable;");
        if (!initCause) return;
        rvmCallObjectInstanceMethod(env, wrappedException, initCause, exception);
        if (!rvmExceptionCheck(env)) rvmThrow(env, wrappedException);
    }
}
コード例 #2
0
ファイル: bc.c プロジェクト: SinoJerk/robovm
void* lookupInterfaceMethod(Env* env, ClassInfoHeader* header, Object* thiz, char* name, char* desc) {
    initializeClass(env, header);
    if (rvmExceptionCheck(env)) return NULL;
    Class* ownerInterface = header->clazz;
    if (!rvmIsInstanceOf(env, thiz, ownerInterface)) {
        char message[256];
        snprintf(message, 256, "Class %s does not implement the requested interface %s", 
            rvmToBinaryClassName(env, thiz->clazz->name), rvmToBinaryClassName(env, ownerInterface->name));
        rvmThrowIncompatibleClassChangeError(env, message);
        return NULL;
    }
    Method* method = rvmGetInstanceMethod(env, thiz->clazz, name, desc);
    Object* throwable = rvmExceptionClear(env);
    if (!method && throwable->clazz != java_lang_NoSuchMethodError) { 
        rvmThrow(env, throwable);
        return NULL;
    }
    if (!method || METHOD_IS_ABSTRACT(method)) {
        rvmThrowAbstractMethodError(env, ""); // TODO: Message
        return NULL;
    }
    if (!METHOD_IS_PUBLIC(method)) {
        rvmThrowIllegalAccessError(env, ""); // TODO: Message
        return NULL;
    }
    return method->synchronizedImpl ? method->synchronizedImpl : method->impl;
}
コード例 #3
0
ファイル: method.c プロジェクト: Svyatoslavik/robovm
jboolean rvmInitMethods(Env* env) {
    if (rvmInitMutex(&nativeLibsLock) != 0) {
        return FALSE;
    }
    if (rvmInitMutex(&threadStackTraceLock) != 0) {
        return FALSE;
    }
    java_lang_StackTraceElement = rvmFindClassUsingLoader(env, "java/lang/StackTraceElement", NULL);
    if (!java_lang_StackTraceElement) {
        return FALSE;
    }
    java_lang_StackTraceElement_constructor = rvmGetInstanceMethod(env, java_lang_StackTraceElement, "<init>", 
                                      "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V");
    if (!java_lang_StackTraceElement_constructor) {
        return FALSE;
    }
    empty_java_lang_StackTraceElement_array = rvmNewObjectArray(env, 0, java_lang_StackTraceElement, NULL, NULL);
    if (!empty_java_lang_StackTraceElement_array) {
        return FALSE;
    }
    if (!rvmAddObjectGCRoot(env, (Object*) empty_java_lang_StackTraceElement_array)) {
        return FALSE;
    }

    return TRUE;
}
コード例 #4
0
ファイル: exception.c プロジェクト: John-Chan/robovm
jboolean rvmInitExceptions(Env* env) {
    stackStateField = rvmGetInstanceField(env, java_lang_Throwable, "stackState", "J");
    if (!stackStateField) return FALSE;
    printStackTraceMethod = rvmGetInstanceMethod(env, java_lang_Thread, "printStackTrace", "(Ljava/lang/Throwable;)V");
    if (!printStackTraceMethod) return FALSE;
    return TRUE;
}
コード例 #5
0
ファイル: attribute.c プロジェクト: Andorion/robovm
jboolean rvmInitAttributes(Env* env) {
    java_lang_TypeNotPresentException = rvmFindClassUsingLoader(env, "java/lang/TypeNotPresentException", NULL);
    if (!java_lang_TypeNotPresentException) return FALSE;
    java_lang_annotation_AnnotationFormatError = rvmFindClassUsingLoader(env, "java/lang/annotation/AnnotationFormatError", NULL);
    if (!java_lang_annotation_AnnotationFormatError) return FALSE;
    java_lang_reflect_Method = rvmFindClassUsingLoader(env, "java/lang/reflect/Method", NULL);
    if (!java_lang_reflect_Method) return FALSE;
    java_lang_reflect_Method_init = rvmGetInstanceMethod(env, java_lang_reflect_Method, "<init>", "(J)V");
    if (!java_lang_reflect_Method_init) return FALSE;

    java_lang_annotation_Annotation = rvmFindClassUsingLoader(env, "java/lang/annotation/Annotation", NULL);
    if (!java_lang_annotation_Annotation) return FALSE;
    array_of_java_lang_annotation_Annotation = rvmFindClassUsingLoader(env, "[Ljava/lang/annotation/Annotation;", NULL);
    if (!array_of_java_lang_annotation_Annotation) return FALSE;

    Class* array_java_lang_Class = rvmFindClassUsingLoader(env, "[Ljava/lang/Class;", NULL);
    if (!array_java_lang_Class) return FALSE;
    emptyExceptionTypes = rvmNewObjectArray(env, 0, NULL, array_java_lang_Class, NULL);
    if (!emptyExceptionTypes) return FALSE;
    if (!rvmAddGlobalRef(env, (Object*) emptyExceptionTypes)) return FALSE;

    emptyAnnotations = rvmNewObjectArray(env, 0, NULL, array_of_java_lang_annotation_Annotation, NULL);
    if (!emptyAnnotations) return FALSE;
    if (!rvmAddGlobalRef(env, (Object*) emptyAnnotations)) return FALSE;

    return TRUE;
}
コード例 #6
0
ファイル: java_lang_Class.c プロジェクト: Andorion/robovm
Object* Java_java_lang_Class_getEnclosingMethod(Env* env, Class* thiz) {
    Method* method = rvmAttributeGetEnclosingMethod(env, thiz);
    if (!method || METHOD_IS_CONSTRUCTOR(method)) return NULL;
    Class* jlr_Method = rvmFindClassUsingLoader(env, "java/lang/reflect/Method", NULL);
    if (!jlr_Method) return NULL;
    Method* constructor = rvmGetInstanceMethod(env, jlr_Method, "<init>", "(J)V");
    if (!constructor) return NULL;
    jvalue args[1];
    args[0].j = PTR_TO_LONG(method);
    return rvmNewObjectA(env, jlr_Method, constructor, args);
}
コード例 #7
0
ファイル: reflection_helpers.c プロジェクト: Arcnor/robovm
Object* createFieldObject(Env* env, Field* field) {
    if (!java_lang_reflect_Field) {
        java_lang_reflect_Field = rvmFindClassUsingLoader(env, "java/lang/reflect/Field", NULL);
        if (!java_lang_reflect_Field) return NULL;
    }
    if (!java_lang_reflect_Field_init) {
        java_lang_reflect_Field_init = rvmGetInstanceMethod(env, java_lang_reflect_Field, "<init>", "(J)V");
        if (!java_lang_reflect_Field_init) return NULL;
    }
    jvalue initArgs[1];
    initArgs[0].j = PTR_TO_LONG(field);
    return rvmNewObjectA(env, java_lang_reflect_Field, java_lang_reflect_Field_init, initArgs);
}
コード例 #8
0
ファイル: reflection_helpers.c プロジェクト: Arcnor/robovm
Object* createConstructorObject(Env* env, Method* method) {
    if (!java_lang_reflect_Constructor) {
        java_lang_reflect_Constructor = rvmFindClassUsingLoader(env, "java/lang/reflect/Constructor", NULL);
        if (!java_lang_reflect_Constructor) return NULL;
    }
    if (!java_lang_reflect_Constructor_init) {
        java_lang_reflect_Constructor_init = rvmGetInstanceMethod(env, java_lang_reflect_Constructor, "<init>", "(J)V");
        if (!java_lang_reflect_Constructor_init) return NULL;
    }
    jvalue initArgs[1];
    initArgs[0].j = PTR_TO_LONG(method);
    return rvmNewObjectA(env, java_lang_reflect_Constructor, java_lang_reflect_Constructor_init, initArgs);
}
コード例 #9
0
ファイル: exception.c プロジェクト: John-Chan/robovm
jboolean rvmThrowNew(Env* env, Class* clazz, const char* message) {
    Method* constructor = rvmGetInstanceMethod(env, clazz, "<init>", "(Ljava/lang/String;)V");
    if (!constructor) return FALSE;
    Object* string = NULL;
    // TODO: Check that clazz != NULL?
    if (message) {
        string = rvmNewStringUTF(env, message, -1);
        if (!string) return FALSE;
    }
    Object* e = rvmNewObject(env, clazz, constructor, string);
    if (!e) return FALSE;
    rvmThrow(env, e);
    return TRUE;
}
コード例 #10
0
ファイル: class.c プロジェクト: John-Chan/robovm
Class* rvmFindClassUsingLoader(Env* env, const char* className, ClassLoader* classLoader) {
    if (!classLoader || classLoader->parent == NULL) {
        // This is the bootstrap classloader. No need to call ClassLoader.loadClass()
        return findBootClass(env, className);
    }
    char* binaryClassName = rvmToBinaryClassName(env, className);
    if (!binaryClassName) return NULL;
    Object* binaryClassNameString = rvmNewInternedStringUTF(env, binaryClassName, -1);
    if (!binaryClassNameString) return NULL;
    Method* loadClassMethod = rvmGetInstanceMethod(env, java_lang_ClassLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
    if (!loadClassMethod) return NULL;
    Object* clazz = rvmCallObjectInstanceMethod(env, (Object*) classLoader, loadClassMethod, binaryClassNameString);
    if (rvmExceptionOccurred(env)) return NULL;
    return (Class*) clazz;
}
コード例 #11
0
ファイル: memory.c プロジェクト: TimurTarasenko/robovm
jboolean rvmInitMemory(Env* env) {
    vm = env->vm;
    java_lang_ref_Reference = rvmFindClassUsingLoader(env, "java/lang/ref/Reference", NULL);
    if (!java_lang_ref_Reference) return FALSE;
    java_lang_ref_Reference_referent = rvmGetInstanceField(env, java_lang_ref_Reference, "referent", "Ljava/lang/Object;");
    if (!java_lang_ref_Reference_referent) return FALSE;
    java_lang_ref_Reference_pendingNext = rvmGetInstanceField(env, java_lang_ref_Reference, "pendingNext", "Ljava/lang/ref/Reference;");
    if (!java_lang_ref_Reference_pendingNext) return FALSE;
    java_lang_ref_Reference_queue = rvmGetInstanceField(env, java_lang_ref_Reference, "queue", "Ljava/lang/ref/ReferenceQueue;");
    if (!java_lang_ref_Reference_queue) return FALSE;
    java_lang_ref_Reference_queueNext = rvmGetInstanceField(env, java_lang_ref_Reference, "queueNext", "Ljava/lang/ref/Reference;");
    if (!java_lang_ref_Reference_queueNext) return FALSE;
    java_lang_ref_PhantomReference = rvmFindClassUsingLoader(env, "java/lang/ref/PhantomReference", NULL);
    if (!java_lang_ref_PhantomReference) return FALSE;
    java_lang_ref_WeakReference = rvmFindClassUsingLoader(env, "java/lang/ref/WeakReference", NULL);
    if (!java_lang_ref_WeakReference) return FALSE;
    java_lang_ref_SoftReference = rvmFindClassUsingLoader(env, "java/lang/ref/SoftReference", NULL);
    if (!java_lang_ref_SoftReference) return FALSE;
    java_lang_ref_FinalizerReference = rvmFindClassUsingLoader(env, "java/lang/ref/FinalizerReference", NULL);
    if (!java_lang_ref_FinalizerReference) return FALSE;
    java_lang_ref_FinalizerReference_add = rvmGetClassMethod(env, java_lang_ref_FinalizerReference, "add", "(Ljava/lang/Object;)V");
    if (!java_lang_ref_FinalizerReference_add) return FALSE;
    java_lang_ref_FinalizerReference_zombie = rvmGetInstanceField(env, java_lang_ref_FinalizerReference, "zombie", "Ljava/lang/Object;");
    if (!java_lang_ref_FinalizerReference_zombie) return FALSE;
    java_lang_ref_ReferenceQueue = rvmFindClassUsingLoader(env, "java/lang/ref/ReferenceQueue", NULL);
    if (!java_lang_ref_ReferenceQueue) return FALSE;
    java_lang_ref_ReferenceQueue_add = rvmGetClassMethod(env, java_lang_ref_ReferenceQueue, "add", "(Ljava/lang/ref/Reference;)V");
    if (!java_lang_ref_ReferenceQueue_add) return FALSE;
    java_nio_ReadWriteDirectByteBuffer = rvmFindClassUsingLoader(env, "java/nio/ReadWriteDirectByteBuffer", NULL);
    if (!java_nio_ReadWriteDirectByteBuffer) return FALSE;
    java_nio_ReadWriteDirectByteBuffer_init = rvmGetInstanceMethod(env, java_nio_ReadWriteDirectByteBuffer, "<init>", "(II)V");
    if (!java_nio_ReadWriteDirectByteBuffer_init) return FALSE;
    Class* java_nio_Buffer = rvmFindClassUsingLoader(env, "java/nio/Buffer", NULL);
    if (!java_nio_Buffer) return FALSE;
    java_nio_Buffer_effectiveDirectAddress = rvmGetInstanceField(env, java_nio_Buffer, "effectiveDirectAddress", "I");
    if (!java_nio_Buffer_effectiveDirectAddress) return FALSE;
    java_nio_Buffer_capacity = rvmGetInstanceField(env, java_nio_Buffer, "capacity", "I");
    if (!java_nio_Buffer_capacity) return FALSE;

    // Make sure that java.lang.ReferenceQueue is initialized now to prevent deadlocks during finalization
    // when both holding the referentsLock and the classLock.
    rvmInitialize(env, java_lang_ref_ReferenceQueue);
    if (rvmExceptionOccurred(env)) return FALSE;

    return TRUE;
}
コード例 #12
0
static jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char* name, const char* sig) {
    return (jmethodID) rvmGetInstanceMethod((Env*) env, (Class*) clazz, (char*) name, (char*) sig);
}
コード例 #13
0
ファイル: class.c プロジェクト: John-Chan/robovm
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();
}
コード例 #14
0
ファイル: memory.c プロジェクト: tobium/robovm
jboolean rvmInitMemory(Env* env) {
    vm = env->vm;

    gcAddRoot(&referents);

    java_lang_ref_Reference_referent = rvmGetInstanceField(env, java_lang_ref_Reference, "referent", "Ljava/lang/Object;");
    if (!java_lang_ref_Reference_referent) return FALSE;
    java_lang_ref_Reference_pendingNext = rvmGetInstanceField(env, java_lang_ref_Reference, "pendingNext", "Ljava/lang/ref/Reference;");
    if (!java_lang_ref_Reference_pendingNext) return FALSE;
    java_lang_ref_Reference_queue = rvmGetInstanceField(env, java_lang_ref_Reference, "queue", "Ljava/lang/ref/ReferenceQueue;");
    if (!java_lang_ref_Reference_queue) return FALSE;
    java_lang_ref_Reference_queueNext = rvmGetInstanceField(env, java_lang_ref_Reference, "queueNext", "Ljava/lang/ref/Reference;");
    if (!java_lang_ref_Reference_queueNext) return FALSE;
    java_lang_ref_PhantomReference = rvmFindClassUsingLoader(env, "java/lang/ref/PhantomReference", NULL);
    if (!java_lang_ref_PhantomReference) return FALSE;
    java_lang_ref_WeakReference = rvmFindClassUsingLoader(env, "java/lang/ref/WeakReference", NULL);
    if (!java_lang_ref_WeakReference) return FALSE;
    java_lang_ref_SoftReference = rvmFindClassUsingLoader(env, "java/lang/ref/SoftReference", NULL);
    if (!java_lang_ref_SoftReference) return FALSE;
    java_lang_ref_FinalizerReference = rvmFindClassUsingLoader(env, "java/lang/ref/FinalizerReference", NULL);
    if (!java_lang_ref_FinalizerReference) return FALSE;
    java_lang_ref_FinalizerReference_add = rvmGetClassMethod(env, java_lang_ref_FinalizerReference, "add", "(Ljava/lang/Object;)V");
    if (!java_lang_ref_FinalizerReference_add) return FALSE;
    java_lang_ref_FinalizerReference_zombie = rvmGetInstanceField(env, java_lang_ref_FinalizerReference, "zombie", "Ljava/lang/Object;");
    if (!java_lang_ref_FinalizerReference_zombie) return FALSE;
    java_lang_ref_ReferenceQueue = rvmFindClassUsingLoader(env, "java/lang/ref/ReferenceQueue", NULL);
    if (!java_lang_ref_ReferenceQueue) return FALSE;
    java_lang_ref_ReferenceQueue_add = rvmGetClassMethod(env, java_lang_ref_ReferenceQueue, "add", "(Ljava/lang/ref/Reference;)V");
    if (!java_lang_ref_ReferenceQueue_add) return FALSE;
    java_nio_ReadWriteDirectByteBuffer = rvmFindClassUsingLoader(env, "java/nio/ReadWriteDirectByteBuffer", NULL);
    if (!java_nio_ReadWriteDirectByteBuffer) return FALSE;
    java_nio_ReadWriteDirectByteBuffer_init = rvmGetInstanceMethod(env, java_nio_ReadWriteDirectByteBuffer, "<init>", "(II)V");
    if (!java_nio_ReadWriteDirectByteBuffer_init) return FALSE;
    Class* java_nio_Buffer = rvmFindClassUsingLoader(env, "java/nio/Buffer", NULL);
    if (!java_nio_Buffer) return FALSE;
    java_nio_Buffer_effectiveDirectAddress = rvmGetInstanceField(env, java_nio_Buffer, "effectiveDirectAddress", "I");
    if (!java_nio_Buffer_effectiveDirectAddress) return FALSE;
    java_nio_Buffer_capacity = rvmGetInstanceField(env, java_nio_Buffer, "capacity", "I");
    if (!java_nio_Buffer_capacity) return FALSE;
    java_lang_Throwable_stackState = rvmGetInstanceField(env, java_lang_Throwable, "stackState", "J");
    if (!java_lang_Throwable_stackState) return FALSE;
    org_robovm_rt_bro_Struct = rvmFindClassUsingLoader(env, "org/robovm/rt/bro/Struct", NULL);
    if (!org_robovm_rt_bro_Struct) {
        // We don't need Struct if it hasn't been compiled in
        rvmExceptionClear(env);
    } else {
        org_robovm_rt_bro_Struct_handle = rvmGetInstanceField(env, org_robovm_rt_bro_Struct, "handle", "J");
        if (!org_robovm_rt_bro_Struct_handle) return FALSE;
    }
    java_nio_MemoryBlock = rvmFindClassUsingLoader(env, "java/nio/MemoryBlock", NULL);
    if (!java_nio_MemoryBlock) return FALSE;
    java_nio_MemoryBlock_address = rvmGetInstanceField(env, java_nio_MemoryBlock, "address", "I");
    if (!java_nio_MemoryBlock_address) return FALSE;

    criticalOutOfMemoryError = rvmAllocateMemoryForObject(env, java_lang_OutOfMemoryError);
    if (!criticalOutOfMemoryError) return FALSE;
    criticalOutOfMemoryError->clazz = java_lang_OutOfMemoryError;
    if (!rvmAddObjectGCRoot(env, criticalOutOfMemoryError)) return FALSE;

    return TRUE;
}