Beispiel #1
0
static jboolean parseStringElementValue(Env* env, void** attributes, jvalue* result) {
    jbyte tag = getByte(attributes);
    if (tag != 's') return throwFormatError(env, "java.lang.String");
    char* s = getString(attributes);
    result->l = (jobject) rvmNewStringUTF(env, s, -1);
    return result->l ? TRUE : FALSE;
}
Beispiel #2
0
jboolean rvmRun(Env* env) {
    Options* options = env->vm->options;
    Class* clazz = NULL;

    rvmHookBeforeAppEntryPoint(env, options->mainClass);
    clazz = rvmFindClassUsingLoader(env, options->mainClass, systemClassLoader);
    if (clazz) {
        Method* method = rvmGetClassMethod(env, clazz, "main", "([Ljava/lang/String;)V");
        if (method) {
            ObjectArray* args = rvmNewObjectArray(env, options->commandLineArgsCount, java_lang_String, NULL, NULL);
            if (args) {
                jint i = 0;
                for (i = 0; i < args->length; i++) {
                    // TODO: Don't assume modified UTF-8
                    args->values[i] = rvmNewStringUTF(env, options->commandLineArgs[i], -1);
                    if (!args->values[i]) {
                        args = NULL;
                        break;
                    }
                }
                if (args) {
                    rvmCallVoidClassMethod(env, clazz, method, args);
                }
            }
        }
    }

    return rvmDestroyVM(env->vm);
}
Beispiel #3
0
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);
    }
}
Beispiel #4
0
jboolean rvmRun(Env* env) {
    Options* options = env->vm->options;
    Class* clazz = NULL;
    clazz = rvmFindClassUsingLoader(env, options->mainClass, systemClassLoader);
    if (clazz) {
        Method* method = rvmGetClassMethod(env, clazz, "main", "([Ljava/lang/String;)V");
        if (method) {
            ObjectArray* args = rvmNewObjectArray(env, options->commandLineArgsCount, java_lang_String, NULL, NULL);
            if (args) {
                jint i = 0;
                for (i = 0; i < args->length; i++) {
                    // TODO: Don't assume modified UTF-8
                    args->values[i] = rvmNewStringUTF(env, options->commandLineArgs[i], -1);
                    if (!args->values[i]) {
                        args = NULL;
                        break;
                    }
                }
                if (args) rvmCallVoidClassMethod(env, clazz, method, args);
            }
        }
    }

    Object* throwable = rvmExceptionOccurred(env);
    rvmDetachCurrentThread(env->vm, TRUE);
    return throwable == NULL ? TRUE : FALSE;
}
Beispiel #5
0
static jboolean getSourceFileIterator(Env* env, jbyte type, void* attributes, void* data) {
    Object** result = (Object**) data;
    if (type == SOURCE_FILE) {
        *result = rvmNewStringUTF(env, getString(&attributes), -1);
        return FALSE; // Stop iterating
    }
    return TRUE; // Continue with next attribute
}
Beispiel #6
0
ObjectArray* Java_java_lang_System_robovmSpecialProperties(Env* env, Class* c) {
    char* osArch = NULL;
#if defined(RVM_X86)
    osArch = "os.arch=x86";
#elif defined(RVM_ARMV6) || defined(RVM_ARMV7) || defined(RVM_THUMBV6) || defined(RVM_THUMBV7)
    osArch = "os.arch=arm";
#endif

#if defined(DARWIN)
    char* osName = NULL;
#   if defined(IOS) && defined(RVM_X86)
    osName = "os.name=iOS Simulator";
#   elif defined(IOS)
    osName = "os.name=iOS";
#   elif defined(MACOSX)
    osName = "os.name=Mac OS X";
#   endif

    char osVersion[64];
    memset(osVersion, 0, sizeof(osVersion));
    strcat(osVersion, "os.version=");
    readDarwinOSVersionFromSystemVersionPList(osVersion);

    ObjectArray* result = rvmNewObjectArray(env, 3, java_lang_String, NULL, NULL);
    if (!result) return NULL;

    result->values[0] = rvmNewStringUTF(env, osName, -1);
    if (!result->values[0]) return NULL;
    result->values[1] = rvmNewStringUTF(env, osVersion, -1);
    if (!result->values[1]) return NULL;
    result->values[2] = rvmNewStringUTF(env, osArch, -1);
    if (!result->values[2]) return NULL;

    return result;
#else
    ObjectArray* result = rvmNewObjectArray(env, 1, java_lang_String, NULL, NULL);
    if (!result) return NULL;
    result->values[0] = rvmNewStringUTF(env, osArch, -1);
    if (!result->values[0]) return NULL;
    return result;
#endif
}
Beispiel #7
0
Object* Java_java_lang_System_mapLibraryName0(Env* env, Class* c, Object* userLibName) {
    if (!userLibName) return NULL;
    char* libName = rvmGetStringUTFChars(env, userLibName);
    if (!libName) return NULL;
    char* result = rvmAllocateMemoryAtomic(env, strlen(libName) + strlen(DSO_PREFIX) + strlen(DSO_EXT) + 1);
    if (!result) return NULL;
    strcpy(result, DSO_PREFIX);
    strcat(result, libName);
    strcat(result, DSO_EXT);
    return rvmNewStringUTF(env, result, -1);
}
Beispiel #8
0
ObjectArray* Java_java_lang_System_robovmSpecialProperties(Env* env, Class* c) {
    char* osArch = NULL;
#if defined(RVM_X86)
    osArch = "os.arch=x86";
#elif defined(RVM_ARMV6) || defined(RVM_ARMV7) || defined(RVM_THUMBV6) || defined(RVM_THUMBV7)
    osArch = "os.arch=arm";
#endif

#if defined(DARWIN)
    char* osName = NULL;
#   if defined(IOS) && defined(RVM_X86)
    osName = "os.name=iOS Simulator";
#   elif defined(IOS)
    osName = "os.name=iOS";
#   elif defined(MACOSX)
    osName = "os.name=Mac OS X";
#   endif

    char osVersion[64];
    memset(osVersion, 0, sizeof(osVersion));
    strcat(osVersion, "os.version=");
    readDarwinOSVersionFromSystemVersionPList(osVersion);

    char userLanguage[64] = "user.language=";
    char userRegion[64] = "user.region=";
    char userVariant[64] = "user.variant=";
    getDarwinLocaleParts(userLanguage, userRegion, userVariant);
    jboolean hasLocale = strcmp(userLanguage, "user.language=") != 0;

    ObjectArray* result = rvmNewObjectArray(env, hasLocale ? 6 : 3, java_lang_String, NULL, NULL);
    if (!result) return NULL;

    result->values[0] = rvmNewStringUTF(env, osName, -1);
    if (!result->values[0]) return NULL;
    result->values[1] = rvmNewStringUTF(env, osVersion, -1);
    if (!result->values[1]) return NULL;
    result->values[2] = rvmNewStringUTF(env, osArch, -1);
    if (!result->values[2]) return NULL;
    if (hasLocale) {
        result->values[3] = rvmNewStringUTF(env, userLanguage, -1);
        if (!result->values[3]) return NULL;
        result->values[4] = rvmNewStringUTF(env, userRegion, -1);
        if (!result->values[4]) return NULL;
        result->values[5] = rvmNewStringUTF(env, userVariant, -1);
        if (!result->values[5]) return NULL;
    }

    return result;
#else
    ObjectArray* result = rvmNewObjectArray(env, 1, java_lang_String, NULL, NULL);
    if (!result) return NULL;
    result->values[0] = rvmNewStringUTF(env, osArch, -1);
    if (!result->values[0]) return NULL;
    return result;
#endif
}
Beispiel #9
0
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;
}
Beispiel #10
0
static jboolean getInnerClassIterator(Env* env, char* innerClass, char* outerClass, char* innerName, jint access, void* data) {
    GetInnerClassArgs* args = (GetInnerClassArgs*) data;
    Class* clazz = args->clazz;
    if (!innerClass || strcmp(innerClass, clazz->name)) {
        return TRUE; // Continue with next attribute
    }
    if (args->access) {
        *args->access = access;
    }
    if (innerName && args->innerClassName) {
        *args->innerClassName = rvmNewStringUTF(env, innerName, -1);
    }
    args->found = TRUE;
    return FALSE; // Stop iterating
}
Beispiel #11
0
ObjectArray* rvmCallStackToStackTraceElements(Env* env, CallStack* callStack, jint first) {
    if (!callStack || callStack->length == 0) {
        return empty_java_lang_StackTraceElement_array;
    }

    // Count the number of methods
    jint index = first;
    jint length = 0;
    while (rvmGetNextCallStackMethod(env, callStack, &index)) {
        length++;
    }

    if (length == 0) {
        return empty_java_lang_StackTraceElement_array;
    }

    ObjectArray* array = rvmNewObjectArray(env, length, java_lang_StackTraceElement, NULL, NULL);
    if (!array) return NULL;

    if (length > 0) {
        jvalue args[4];
        index = first;
        jint i;
        for (i = 0; i < length; i++) {
            Method* m = rvmGetNextCallStackMethod(env, callStack, &index);
            args[0].l = (jobject) m->clazz;
            args[1].l = (jobject) rvmNewStringUTF(env, m->name, -1);
            if (!args[1].l) return NULL;
            args[2].l = (jobject) rvmAttributeGetClassSourceFile(env, m->clazz);
            if (rvmExceptionOccurred(env)) {
                return NULL;
            }
            args[3].i = METHOD_IS_NATIVE(m) ? -2 : -1; // TODO: Line numbers
            array->values[i] = rvmNewObjectA(env, java_lang_StackTraceElement, 
                java_lang_StackTraceElement_constructor, args);
            if (!array->values[i]) return NULL;
        }
    }

    return array;
}
Beispiel #12
0
ObjectArray* Java_aura_rt_VM_staticLibs(Env* env, Class* c) {
    Options* options = env->vm->options;
    if (!options->staticLibs || options->staticLibs[0] == NULL) {
        return rvmNewObjectArray(env, 0, java_lang_String, NULL, NULL);
    }

    jint length = 0;
    while (options->staticLibs[length] != NULL) {
        length++;
    }

    ObjectArray* result = rvmNewObjectArray(env, length, java_lang_String, NULL, NULL);
    if (!result) return NULL;

    jint i;
    for (i = 0; i < length; i++) {
        Object* s = rvmNewStringUTF(env, options->staticLibs[i], -1);
        if (!s) return NULL;
        result->values[i] = s;
    }

    return result;
}
ObjectArray* Java_java_net_NetworkInterface_getInterfaceNames(Env* env, JClass* cls) {
    if (!java_lang_String_array) {
        java_lang_String_array = rvmFindClassUsingLoader(env, "[Ljava/lang/String;", NULL);
        if (!java_lang_String_array) {
            return NULL;
        }
    }

    struct if_nameindex* ifs = if_nameindex();
    if (!ifs) {
        // Assume out of memory
        rvmThrowOutOfMemoryError(env);
        return NULL;
    }
    jint count = 0;
    while (ifs[count].if_index > 0) {
        count++;
    }

    ObjectArray* result = rvmNewObjectArray(env, count, NULL, java_lang_String_array, NULL);
    if (!result) {
        goto done;
    }

    jint i = 0;
    for (i = 0; i < count; i++) {
        Object* name = rvmNewStringUTF(env, ifs[i].if_name, -1);
        if (!name) {
            goto done;
        }
        result->values[i] = name;
    }

done:
    if_freenameindex(ifs);
    return result;
}
Beispiel #14
0
static jint attachThread(VM* vm, Env** envPtr, char* name, Object* group, jboolean daemon) {
    Env* env = *envPtr; // env is NULL if rvmAttachCurrentThread() was called. If non NULL rvmInitThreads() was called.
    if (!env) {
        // If the thread was already attached there's an Env* associated with the thread.
        env = (Env*) pthread_getspecific(tlsEnvKey);
        if (env) {
            env->attachCount++;
            *envPtr = env;
            return JNI_OK;
        }
    }
    
    if (!env) {
        env = rvmCreateEnv(vm);
        if (!env) goto error;
    }

    setThreadEnv(env);
    if (rvmExceptionOccurred(env)) goto error;

    Thread* thread = allocThread(env);
    if (!thread) goto error;
    thread->stackAddr = getStackAddress();
    thread->pThread = pthread_self();
    env->currentThread = thread;
    rvmChangeThreadStatus(env, thread, THREAD_RUNNING);
    
    JavaThread* threadObj = (JavaThread*) rvmAllocateObject(env, java_lang_Thread);
    if (!threadObj) goto error;

    rvmLockThreadsList();
    if (!initThread(env, thread, threadObj)) {
        rvmUnlockThreadsList();
        goto error;
    }
    if (!rvmSetupSignals(env)) {
        rvmUnlockThreadsList();
        goto error;
    }
    DL_PREPEND(threads, thread);
    pthread_cond_broadcast(&threadsChangedCond);
    rvmUnlockThreadsList();

    Object* threadName = NULL;
    if (name) {
        threadName = rvmNewStringUTF(env, name, -1);
        if (!threadName) goto error_remove;
    }

    Method* threadConstructor = rvmGetInstanceMethod2(env, java_lang_Thread, "<init>", "(JLjava/lang/String;Ljava/lang/ThreadGroup;Z)V");
    if (!threadConstructor) goto error_remove;

    rvmCallNonvirtualVoidInstanceMethod(env, (Object*) threadObj, threadConstructor, PTR_TO_LONG(thread), threadName, group, daemon);
    if (rvmExceptionOccurred(env)) goto error_remove;

    *envPtr = env;

    return JNI_OK;

error_remove:
    rvmLockThreadsList();
    DL_DELETE(threads, thread);
    pthread_cond_broadcast(&threadsChangedCond);
    rvmTearDownSignals(env);
    rvmUnlockThreadsList();
error:
    if (env) env->currentThread = NULL;
    clearThreadEnv();
    return JNI_ERR;
}
Beispiel #15
0
Env* rvmStartup(Options* options) {
    // TODO: Error handling

    TRACE("Initializing logging");
    if (!rvmInitLog(options)) return NULL;

#if defined(IOS) && (defined(RVM_ARMV7) || defined(RVM_THUMBV7))
    // Enable IEEE-754 denormal support.
    // Without this the VFP treats numbers that are close to zero as zero itself.
    // See http://developer.apple.com/library/ios/#technotes/tn2293/_index.html.
    fenv_t fenv;
    fegetenv(&fenv);
    fenv.__fpscr &= ~__fpscr_flush_to_zero;
    fesetenv(&fenv);
#endif
    // print PID if it was requested
    if(options->printPID) {
        pid_t pid = getpid();
        if(options->pidFile) {
            FILE* f = fopen(options->pidFile, "w");
            if (!f) return NULL;
            fprintf(f, "%d", pid);
            fclose(f);
        } else {
            fprintf(stderr, "[DEBUG] %s: pid=%d\n", LOG_TAG, pid);
        }
    }

    // setup the TCP channel socket and wait
    // for the debugger to connect
    if(options->enableHooks) {
        if(!rvmHookSetupTCPChannel(options)) return NULL;
        if(!rvmHookHandshake(options)) return NULL;
    }

    TRACE("Initializing GC");
    if (!initGC(options)) return NULL;

    // Ignore SIGPIPE signals. SIGPIPE interrupts write() calls which we don't
    // want. Dalvik does this too in dalvikvm/Main.cpp.
    if (!ignoreSignal(SIGPIPE)) return NULL;

    // Ignore SIGXFSZ signals. SIGXFSZ is raised when writing beyond the RLIMIT_FSIZE
    // of the current process (at least on Darwin) using pwrite().
    if (!ignoreSignal(SIGXFSZ)) return NULL;

    VM* vm = rvmCreateVM(options);
    if (!vm) return NULL;

    Env* env = rvmCreateEnv(vm);
    if (!env) return NULL;
    // TODO: What if we can't allocate Env?

    if (!initClasspathEntries(env, options->resourcesPath, options->rawBootclasspath, &options->bootclasspath)) return NULL;
    if (!initClasspathEntries(env, options->resourcesPath, options->rawClasspath, &options->classpath)) return NULL;

    // Call init on modules
    TRACE("Initializing classes");
    if (!rvmInitClasses(env)) return NULL;
    TRACE("Initializing memory");
    if (!rvmInitMemory(env)) return NULL;
    TRACE("Initializing methods");
    if (!rvmInitMethods(env)) return NULL;
    TRACE("Initializing strings");
    if (!rvmInitStrings(env)) return NULL;
    TRACE("Initializing monitors");
    if (!rvmInitMonitors(env)) return NULL;
    TRACE("Initializing proxy");
    if (!rvmInitProxy(env)) return NULL;
    TRACE("Initializing threads");
    if (!rvmInitThreads(env)) return NULL;
    TRACE("Initializing attributes");
    if (!rvmInitAttributes(env)) return NULL;
    TRACE("Initializing primitive wrapper classes");
    if (!rvmInitPrimitiveWrapperClasses(env)) return NULL;
    TRACE("Initializing exceptions");
    if (!rvmInitExceptions(env)) return NULL;
    TRACE("Initializing signals");
    if (!rvmInitSignals(env)) return NULL;
    TRACE("Initializing JNI");
    if (!rvmInitJNI(env)) return NULL;

    // Initialize the RoboVM rt JNI code
//    RT_JNI_OnLoad(&vm->javaVM, NULL);
    // Initialize the dalvik rt JNI code
    TRACE("Initializing dalvik's runtime JNI code");
    registerCoreLibrariesJni((JNIEnv*) env);

#ifdef DARWIN
    TRACE("Initializing JAR NSURLProtocol");
    registerJARURLProtocol();
#endif

    TRACE("Creating system ClassLoader");
    systemClassLoader = rvmGetSystemClassLoader(env);
    if (rvmExceptionOccurred(env)) goto error_system_ClassLoader;
    env->currentThread->threadObj->contextClassLoader = systemClassLoader;

    TRACE("Initialization done");
    env->vm->initialized = TRUE;
    
    // Start Daemons
    TRACE("Starting Daemons");
    java_lang_Daemons = rvmFindClassUsingLoader(env, "java/lang/Daemons", NULL);
    if (!java_lang_Daemons) goto error_daemons;
    java_lang_Daemons_start = rvmGetClassMethod(env, java_lang_Daemons, "start", "()V");
    if (!java_lang_Daemons_start) goto error_daemons;
    rvmCallVoidClassMethod(env, java_lang_Daemons, java_lang_Daemons_start);
    if (rvmExceptionCheck(env)) goto error_daemons;
    TRACE("Daemons started");

    jboolean errorDuringSetup = FALSE;

    //If our options has any properties, let's set them before we call our main.
    if (options->properties) {
        //First, find java.lang.System, which has the setProperty method.
        Class* clazz = rvmFindClassUsingLoader(env, "java/lang/System", NULL);
        if (clazz) {
            //Get the setProperty method.
            Method* method = rvmGetClassMethod(env, clazz, "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
            if (method) {
                SystemProperty* property = options->properties;

                //Go through all of our properties and add each one in turn by calling setProperty.
                while (property != NULL) {
                    Object* key = NULL;
                    Object* value = NULL;
                    //The key is not allowed to be an empty string, so don't set it if we don't get a key.
                    if(property->key && strlen(property->key) > 0) {
                        key = rvmNewStringUTF(env, property->key, -1);
                    } else {
                        FATAL("Cannot have empty key in system property.");
                        errorDuringSetup = TRUE;
                        break;
                    }
                    if (property->value) {
                        value = rvmNewStringUTF(env, property->value, -1);
                    } else {
                        value = rvmNewStringUTF(env, "", -1);
                    }

                    if (key && value) {
                        rvmCallObjectClassMethod(env, clazz, method, key, value);
                    } else {
                        if (!key) {
                            FATALF("Error creating string from system property key: %s", property->key);
                        }
                        if (!value) {
                            FATALF("Error creating string from system property value: %s", property->value);
                        }
                        errorDuringSetup = TRUE;
                        break;
                    }
                    property = property->next; //Advance to the next property.
                }
            }
        }
    }

    return (errorDuringSetup) ? NULL : env;

error_daemons:
error_system_ClassLoader:
    rvmDetachCurrentThread(env->vm, TRUE, FALSE);

    return NULL;
}
Beispiel #16
0
Object* Java_aura_rt_VM_imagePath(Env* env, Class* c) {
    return rvmNewStringUTF(env, env->vm->options->imagePath, -1);
}
Beispiel #17
0
Object* Java_aura_rt_VM_classPath(Env* env, Class* c) {
    char* classpath = createClasspathFromClasspathEntries(env, env->vm->options->classpath);
    if (!classpath) return NULL;
    return rvmNewStringUTF(env, classpath, -1);
}
Beispiel #18
0
Object* Java_aura_rt_VM_newStringUTF(Env* env, Class* c, jlong address) {
    return rvmNewStringUTF(env, (char*) LONG_TO_PTR(address), -1);
}
Beispiel #19
0
Object* Java_java_lang_reflect_Method_getName(Env* env, Class* clazz, jlong methodPtr) {
    Method* method = (Method*) LONG_TO_PTR(methodPtr);
    return rvmNewStringUTF(env, method->name, -1);
}
Beispiel #20
0
Object* Java_java_lang_Class_getName0(Env* env, Class* thiz) {
    return rvmNewStringUTF(env, thiz->name, -1);
}
Beispiel #21
0
Object* Java_org_robovm_rt_VM_bootClassPath(Env* env, Class* c) {
    char* bootclasspath = createClasspathFromClasspathEntries(env, env->vm->options->bootclasspath);
    if (!bootclasspath) return NULL;
    return rvmNewStringUTF(env, bootclasspath, -1);
}
Beispiel #22
0
Object* Java_org_robovm_rt_VM_basePath(Env* env, Class* c) {
    return rvmNewStringUTF(env, env->vm->options->basePath, -1);
}
Beispiel #23
0
jboolean rvmRun(Env* env) {
    Options* options = env->vm->options;
    Class* clazz = NULL;

    jboolean errorDuringSetup = FALSE;

    //If our options has any properties, let's set them before we call our main.
    if (options->properties) {
        //First, find java.lang.System, which has the setProperty method.
        clazz = rvmFindClassUsingLoader(env, "java/lang/System", NULL);
        if (clazz) {
            //Get the setProperty method.
            Method* method = rvmGetClassMethod(env, clazz, "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
            if (method) {
                SystemProperty* property = options->properties;

                //Go through all of our properties and add each one in turn by calling setProperty.
                while (property != NULL) {
                    Object* key = NULL;
                    Object* value = NULL;
                    //The key is not allowed to be an empty string, so don't set it if we don't get a key.
                    if(property->key && strlen(property->key) > 0) {
                        key = rvmNewStringUTF(env, property->key, -1);
                    } else {
                        FATAL("Cannot have empty key in system property.");
                        errorDuringSetup = TRUE;
                        break;
                    }
                    if (property->value) {
                        value = rvmNewStringUTF(env, property->value, -1);
                    } else {
                        value = rvmNewStringUTF(env, "", -1);
                    }

                    if (key && value) {
                        rvmCallObjectClassMethod(env, clazz, method, key, value);
                    } else {
                        if (!key) {
                            FATALF("Error creating string from system property key: %s", property->key);
                        }
                        if (!value) {
                            FATALF("Error creating string from system property value: %s", property->value);
                        }
                        errorDuringSetup = TRUE;
                        break;
                    }
                    property = property->next; //Advance to the next property.
                }
            }
        }
    }

    if (!errorDuringSetup) {
        clazz = rvmFindClassUsingLoader(env, options->mainClass, systemClassLoader);
        if (clazz) {
            Method* method = rvmGetClassMethod(env, clazz, "main", "([Ljava/lang/String;)V");
            if (method) {
                ObjectArray* args = rvmNewObjectArray(env, options->commandLineArgsCount, java_lang_String, NULL, NULL);
                if (args) {
                    jint i = 0;
                    for (i = 0; i < args->length; i++) {
                        // TODO: Don't assume modified UTF-8
                        args->values[i] = rvmNewStringUTF(env, options->commandLineArgs[i], -1);
                        if (!args->values[i]) {
                            args = NULL;
                            break;
                        }
                    }
                    if (args) rvmCallVoidClassMethod(env, clazz, method, args);
                }
            }
        }
    }

    Object* throwable = rvmExceptionOccurred(env);
    rvmDetachCurrentThread(env->vm, TRUE, FALSE);

    rvmJoinNonDaemonThreads(env);

    return throwable == NULL ? TRUE : FALSE;
}
Beispiel #24
0
static jstring NewStringUTF(JNIEnv* env, const char* utf) {
    return (jstring) rvmNewStringUTF((Env*) env, (char*) utf, -1);
}