/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This source file is part of SableVM. * * * * See the file "LICENSE" for the copyright information and for * * the terms and conditions for copying, distribution and * * modification of this source file. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_availableProcessors ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: availableProcessors * Signature: ()I */ JNIEXPORT jint JNICALL Java_java_lang_VMRuntime_availableProcessors (JNIEnv *_env, jclass class) { /* to do */ return 1; } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_freeMemory ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: freeMemory * Signature: ()J */ JNIEXPORT jlong JNICALL Java_java_lang_VMRuntime_freeMemory (JNIEnv *_env, jclass class) { /* to do */ return 0; } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_totalMemory ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: totalMemory * Signature: ()J */ JNIEXPORT jlong JNICALL Java_java_lang_VMRuntime_totalMemory (JNIEnv *_env, jclass class) { /* to do */ return 0; } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_maxMemory ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: maxMemory * Signature: ()J */ JNIEXPORT jlong JNICALL Java_java_lang_VMRuntime_maxMemory (JNIEnv *_env, jclass class) { /* to do */ return 0; } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_gc ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: gc * Signature: ()V */ JNIEXPORT void JNICALL Java_java_lang_VMRuntime_gc (JNIEnv *_env, jclass class) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); _svmf_resuming_java (env); #ifdef _SABLEVM_NO_GC /* do nothing ;-) */ #elif defined (_SABLEVM_COPY_GC) { _svmt_JavaVM *vm = env->vm; jint status = JNI_OK; _svmm_mutex_lock (vm->global_mutex); _svmf_halt_if_requested (env); status = _svmf_copy_gc_no_exception (env, 0); _svmm_mutex_unlock (); if (status != JNI_OK) { _svmm_fatal_error ("impossible control flow"); } } #else #error todo #endif _svmf_stopping_java (env); } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_runFinalization ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: runFinalization * Signature: ()V */ JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalization (JNIEnv *_env, jclass class) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); _svmf_resuming_java (env); /* todo */ _svmf_stopping_java (env); } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_runFinalizationForExit ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: runFinalizationForExit * Signature: ()V */ JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizationForExit (JNIEnv *_env, jclass class) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); _svmf_resuming_java (env); /* todo */ _svmf_stopping_java (env); } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_traceInstructions ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: traceInstructions * Signature: (Z)V */ JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceInstructions (JNIEnv *_env, jclass class, jboolean on) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); _svmf_resuming_java (env); #if !defined(NDEBUG) env->vm->verbose_instructions = on; #endif _svmf_stopping_java (env); } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_traceMethodCalls ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: traceMethodCalls * Signature: (Z)V */ JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceMethodCalls (JNIEnv *_env, jclass class, jboolean on) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); _svmf_resuming_java (env); #if !defined(NDEBUG) env->vm->verbose_methods = on; #endif _svmf_stopping_java (env); } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_runFinalizersOnExit ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: runFinalizersOnExit * Signature: (Z)V */ JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizersOnExit (JNIEnv *_env, jclass class, jboolean value) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); _svmf_resuming_java (env); /* todo */ _svmf_stopping_java (env); } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_exit ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: exit * Signature: (I)V */ JNIEXPORT void JNICALL Java_java_lang_VMRuntime_exit (JNIEnv *_env, jclass class, jint status) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); #ifdef STATISTICS _svmf_print_statistics (env); #endif /* STATISTICS */ /* this one is simple! */ exit (status); } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_nativeLoad ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: nativeLoad * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jint JNICALL Java_java_lang_VMRuntime_nativeLoad (JNIEnv *_env, jclass class, jstring _filename) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); _svmt_JavaVM *vm = env->vm; const char *errmsg = "unknown error"; _svmf_resuming_java (env); { char *filename; _svmt_class_loader_info *class_loader_info = _svmf_get_current_class_loader (env); _svmt_native_library *native_library = class_loader_info->native_library_list; lt_dlhandle handle; jboolean monitor_acquired = JNI_FALSE; if (_svmf_enter_object_monitor (env, *(vm->class_loading.boot_loader.classes.virtualmachine-> class_instance)) != JNI_OK) { goto end; } monitor_acquired = JNI_TRUE; if (_svmm_galloc_utf_chars (env, _filename, filename) != JNI_OK) { goto end; } handle = lt_dlopen (filename); if (handle == NULL) { errmsg = lt_dlerror (); _svmm_gfree_utf_chars (filename); goto end; } while (native_library != NULL) { if (native_library->handle == handle) { errmsg = NULL; _svmm_gfree_utf_chars (filename); goto end; } native_library = native_library->next; } /* Call JNI_OnLoad */ { JNIEXPORT jint (JNICALL *JNI_OnLoad) (JavaVM *, void *); JNI_OnLoad = (JNIEXPORT jint (JNICALL *)(JavaVM *, void *)) lt_dlsym (handle, "JNI_OnLoad"); if (JNI_OnLoad != NULL) { jint version = JNI_OnLoad (_svmf_cast_JavaVM (vm), NULL); if (version != JNI_VERSION_1_2) { lt_dlclose (handle); goto end; } } } if (_svmm_cl_zalloc_native_library (env, class_loader_info, *(class_loader_info->native_library_list_tail)) != JNI_OK) { _svmm_gfree_utf_chars (filename); goto end; } (*(class_loader_info->native_library_list_tail))->name = filename; (*(class_loader_info->native_library_list_tail))->handle = handle; class_loader_info->native_library_list_tail = &(*(class_loader_info->native_library_list_tail))->next; errmsg = NULL; end: if (monitor_acquired) { monitor_acquired = JNI_FALSE; if (_svmf_exit_object_monitor (env, *(vm->class_loading.boot_loader.classes.virtualmachine-> class_instance)) != JNI_OK) { goto end; } } } _svmf_stopping_java (env); return errmsg == NULL ? 1 : 0; } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_exec ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: exec * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/io/File;)Ljava/lang/Process; */ JNIEXPORT jobject JNICALL Java_java_lang_VMRuntime_exec (JNIEnv *env, jclass class, jobjectArray cmd, jobjectArray envArray, jobject dir) { /*** Note: env and dir are currently not supported ***/ /*** TODO: Free memory allocated (including when returns due to failure). */ /* * Note: This do not require SableVM internal access, should be implemented * in Classpath native lib... * * So, we do a pure JNI implementation... * */ int pid; jobject process_instance = NULL; int inpipe[2]; int outpipe[2]; int errpipe[2]; char *filename; char **argv; int length; int i; static jclass fd_jclass = NULL; static jclass process_jclass = NULL; /* jboolean debug = JNI_TRUE; */ jboolean debug = JNI_FALSE; assert (envArray == NULL); assert (dir == NULL); /* * 0 - for reading * 1 - for writing */ /* Creates all the pipes needed */ pipe (inpipe); /* stream connecting subprocess in */ pipe (outpipe); /* stream connecting subprocess out */ pipe (errpipe); /* stream connecting subprocess err */ if (debug) { printf ("inpipe[0] = %d, inpipe[1] = %d\n", inpipe[0], inpipe[1]); printf ("outpipe[0] = %d, outpipe[1] = %d\n", outpipe[0], outpipe[1]); printf ("errpipe[0] = %d, errpipe[1] = %d\n", errpipe[0], errpipe[1]); } pid = fork (); if (pid == -1) { /* error */ fprintf (stderr, "Fork failed!\n"); } else if (pid == 0) { /* child process */ if (debug) { fprintf (stderr, "In child\n"); } dup2 (inpipe[0], STDIN_FILENO); /* redirect subprocess in */ dup2 (outpipe[1], STDOUT_FILENO); /* redirect subprocess out */ if (!debug) { dup2 (errpipe[1], STDERR_FILENO); /* redirect subprocess err */ } /* close fds not needed */ close (inpipe[0]); close (inpipe[1]); close (outpipe[0]); close (outpipe[1]); close (errpipe[0]); close (errpipe[1]); length = (*cmd)->size; assert (length > 0); if (length < 1) { goto end; } argv = (char **) malloc (sizeof (char *) * (length + 1)); for (i = 0; i < length; i++) { /* _svmt_object_instance *name; name = _svmf_get_reference_array_element (*cmd, i); _svmm_galloc_utf_chars (env, &name, argv[i]); */ jstring name; name = (jstring) (*env)->GetObjectArrayElement (env, cmd, i); argv[i] = (char *) (*env)->GetStringUTFChars (env, name, NULL); if (argv[i] == NULL) { /* TODO: free mem */ goto end; } } argv[length] = NULL; /* need to be null-terminated for exec */ if (debug) { i = 0; while (argv[i] != NULL) { fprintf (stderr, "argv[%d] = %s\n", i, argv[i]); i++; } } if (debug) { fprintf (stderr, "Now execve...\n"); } /* Load new process image */ /* execve(argv[0], argv, envp); */ execvp (argv[0], argv); fprintf (stderr, "execve failed!\n"); /* if exec fails, free memory allocated */ } else { /* parent process */ int fdin, fdout, fderr; jobject fdin_object, fdout_object, fderr_object; jfieldID fid; jmethodID mid; fdout = dup (inpipe[1]); fdin = dup (outpipe[0]); fderr = dup (errpipe[0]); /* TODO: free mem allocated for argv strings, and argv array */ /* close fds not needed */ close (inpipe[0]); close (inpipe[1]); close (outpipe[0]); close (outpipe[1]); close (errpipe[0]); close (errpipe[1]); if (debug) { fprintf (stderr, "Creating FDs\n"); } if ((fd_jclass = (*env)->FindClass (env, "java/io/FileDescriptor")) == NULL) { goto end; } if ((process_jclass = (*env)->FindClass (env, "java/lang/ProcessImpl")) == NULL) { goto end; } mid = (*env)->GetMethodID (env, fd_jclass, "", "(J)V"); if (mid == NULL) { goto end; } fdin_object = (*env)->NewObject (env, fd_jclass, mid, (jlong) fdin); if (fdin_object == NULL) { goto end; } fdout_object = (*env)->NewObject (env, fd_jclass, mid, (jlong) fdout); if (fdout_object == NULL) { goto end; } fderr_object = (*env)->NewObject (env, fd_jclass, mid, (jlong) fderr); if (fderr_object == NULL) { goto end; } mid = (*env)->GetMethodID (env, process_jclass, "", "(ILjava/io/FileDescriptor;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;)V"); if (mid == NULL) { goto end; } process_instance = (*env)->NewObject (env, process_jclass, mid, pid, fdin_object, fdout_object, fderr_object); if (process_instance == NULL) { goto end; } } end: return process_instance; } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_getSableVMVersion ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: getSableVMVersion * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_java_lang_VMRuntime_getSableVMVersion (JNIEnv *_env, jclass class) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); jstring string; _svmf_resuming_java (env); { /* as we do nothing else after, we can safely ignore the return value (any exception being also set in the environment) */ string = _svmf_get_jni_frame_native_local (env); _svmf_get_string (env, _SABLEVM_PACKAGE_VERSION, string); } _svmf_stopping_java (env); return string; } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_getFileSeparator ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: getFileSeparator * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_java_lang_VMRuntime_getFileSeparator (JNIEnv *_env, jclass class) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); jstring string; _svmf_resuming_java (env); { /* as we do nothing else after, we can safely ignore the return value (any exception being also set in the environment) */ string = _svmf_get_jni_frame_native_local (env); _svmf_get_string (env, "/", string); } _svmf_stopping_java (env); return string; } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_getPathSeparator ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: getPathSeparator * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_java_lang_VMRuntime_getPathSeparator (JNIEnv *_env, jclass class) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); jstring string; _svmf_resuming_java (env); { /* as we do nothing else after, we can safely ignore the return value (any exception being also set in the environment) */ string = _svmf_get_jni_frame_native_local (env); _svmf_get_string (env, ":", string); } _svmf_stopping_java (env); return string; } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_getLineSeparator ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: getLineSeparator * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_java_lang_VMRuntime_getLineSeparator (JNIEnv *_env, jclass class) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); jstring string; _svmf_resuming_java (env); { /* as we do nothing else after, we can safely ignore the return value (any exception being also set in the environment) */ string = _svmf_get_jni_frame_native_local (env); _svmf_get_string (env, "\n", string); } _svmf_stopping_java (env); return string; } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_getUserName ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: getUserName * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_java_lang_VMRuntime_getUserName (JNIEnv *_env, jclass class) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); jstring string; _svmf_resuming_java (env); { const char *value = getenv ("USER"); if (value == NULL) { value = ""; } /* as we do nothing else after, we can safely ignore the return value (any exception being also set in the environment) */ string = _svmf_get_jni_frame_native_local (env); _svmf_get_string (env, value, string); } _svmf_stopping_java (env); return string; } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_getUserHome ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: getUserHome * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_java_lang_VMRuntime_getUserHome (JNIEnv *_env, jclass class) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); jstring string; _svmf_resuming_java (env); { const char *value = getenv ("HOME"); if (value == NULL) { value = ""; } /* as we do nothing else after, we can safely ignore the return value (any exception being also set in the environment) */ string = _svmf_get_jni_frame_native_local (env); _svmf_get_string (env, value, string); } _svmf_stopping_java (env); return string; } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_getWorkDir ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: getWorkDir * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_java_lang_VMRuntime_getWorkDir (JNIEnv *_env, jclass class) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); jstring string; _svmf_resuming_java (env); { _svmt_JavaVM *vm = env->vm; const char *value = vm->boot_working_directory; if (value == NULL) { value = ""; } /* as we do nothing else after, we can safely ignore the return value (any exception being also set in the environment) */ string = _svmf_get_jni_frame_native_local (env); _svmf_get_string (env, value, string); } _svmf_stopping_java (env); return string; } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_getBootstrapLibraryPath ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: getBootstrapLibraryPath * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_java_lang_VMRuntime_getBootstrapLibraryPath (JNIEnv *_env, jclass class) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); jstring string; _svmf_resuming_java (env); { _svmt_JavaVM *vm = env->vm; const char *value = vm->class_loading.boot_loader.boot_library_path; /* as we do nothing else after, we can safely ignore the return value (any exception being also set in the environment) */ string = _svmf_get_jni_frame_native_local (env); _svmf_get_string (env, value, string); } _svmf_stopping_java (env); return string; } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_getBootstrapClassPath ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: getBootstrapClassPath * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_java_lang_VMRuntime_getBootstrapClassPath (JNIEnv *_env, jclass class) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); jstring string; _svmf_resuming_java (env); { _svmt_JavaVM *vm = env->vm; const char *value = vm->class_loading.boot_loader.boot_class_path; /* as we do nothing else after, we can safely ignore the return value (any exception being also set in the environment) */ string = _svmf_get_jni_frame_native_local (env); _svmf_get_string (env, value, string); } _svmf_stopping_java (env); return string; } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_getPropertyCount ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: getPropertyCount * Signature: ()I */ JNIEXPORT jint JNICALL Java_java_lang_VMRuntime_getPropertyCount (JNIEnv *_env, jclass class) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); jint count; _svmf_resuming_java (env); { _svmt_JavaVM *vm = env->vm; count = vm->class_loading.boot_loader.system_properties.count; } _svmf_stopping_java (env); return count; } /* ---------------------------------------------------------------------- Java_java_lang_VMRuntime_getProperty ---------------------------------------------------------------------- */ /* * Class: java_lang_VMRuntime * Method: getProperty * Signature: (I)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_java_lang_VMRuntime_getProperty (JNIEnv *_env, jclass class, jint index) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); jstring string; _svmf_resuming_java (env); { _svmt_JavaVM *vm = env->vm; /* as we do nothing else after, we can safely ignore the return value (any exception being also set in the environment) */ string = _svmf_get_jni_frame_native_local (env); _svmf_get_string (env, vm->class_loading.boot_loader.system_properties. properties[index], string); } _svmf_stopping_java (env); return string; }