Env* rvmStartup(Options* options) { // TODO: Error handling TRACE("Initializing GC"); if (!initGC(options)) 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->basePath, options->rawBootclasspath, &options->bootclasspath)) return NULL; if (!initClasspathEntries(env, options->basePath, options->rawClasspath, &options->classpath)) return NULL; // Call init on modules TRACE("Initializing logging"); if (!rvmInitLog(env)) return NULL; TRACE("Initializing classes"); if (!rvmInitClasses(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 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 memory"); if (!rvmInitMemory(env)) return NULL; // Initialize the RoboVM rt JNI code // RT_JNI_OnLoad(&vm->javaVM, NULL); // Initialize dalvik's JNIHelp code in libnativehelper TRACE("Initializing dalvik's libnativehelper"); registerJniHelp((JNIEnv*) env); // Initialize the dalvik rt JNI code TRACE("Initializing dalvik's runtime JNI code"); registerCoreLibrariesJni((JNIEnv*) env); TRACE("Creating system ClassLoader"); systemClassLoader = rvmGetSystemClassLoader(env); if (rvmExceptionOccurred(env)) goto error_system_ClassLoader; env->currentThread->threadObj->contextClassLoader = systemClassLoader; TRACE("Initialization done"); // 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"); return env; error_daemons: error_system_ClassLoader: rvmDetachCurrentThread(env->vm, TRUE); return NULL; }
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; }
Env* rvmStartup(Options* options) { // TODO: Error handling #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 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->basePath, options->rawBootclasspath, &options->bootclasspath)) return NULL; if (!initClasspathEntries(env, options->basePath, options->rawClasspath, &options->classpath)) return NULL; // Call init on modules TRACE("Initializing logging"); if (!rvmInitLog(env)) return NULL; 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; // 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); 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"); return env; error_daemons: error_system_ClassLoader: rvmDetachCurrentThread(env->vm, TRUE, FALSE); return NULL; }