зеркало из https://github.com/mozilla/gecko-dev.git
Fix for bug #26516, load Java lazily. sr=brendan, r=edburns
This commit is contained in:
Родитель
1caafa50ec
Коммит
6ea19da1fa
|
@ -448,46 +448,11 @@ JSJ_ConnectToJavaVM(SystemJavaVM *java_vm_arg, void* initargs)
|
|||
free(jsjava_vm);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
JSBool ok;
|
||||
JS_ASSERT(JSJ_callbacks->create_java_vm);
|
||||
JS_ASSERT(JSJ_callbacks->destroy_java_vm);
|
||||
|
||||
ok = JSJ_callbacks->create_java_vm(&java_vm, &jEnv, initargs);
|
||||
if (!ok || java_vm == NULL) {
|
||||
jsj_LogError("Failed to create Java VM\n");
|
||||
free(jsjava_vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Remember that we created the VM so that we know to destroy it later */
|
||||
jsjava_vm->jsj_created_java_vm = JS_TRUE;
|
||||
jsjava_vm->java_vm = java_vm;
|
||||
jsjava_vm->main_thread_env = jEnv;
|
||||
}
|
||||
|
||||
jsjava_vm->java_vm = java_vm;
|
||||
jsjava_vm->main_thread_env = jEnv;
|
||||
|
||||
/*
|
||||
* JVM initialization for netscape.javascript.JSObject is performed
|
||||
* independently of the other classes that are initialized in
|
||||
* init_java_VM_reflection, because we allow it to fail. In the case
|
||||
* of failure, LiveConnect is still operative, but only when calling
|
||||
* from JS to Java and not vice-versa.
|
||||
*/
|
||||
init_netscape_java_classes(jsjava_vm, jEnv);
|
||||
|
||||
/* Load the Java classes, and the method and field descriptors required for
|
||||
Java reflection. */
|
||||
if (!init_java_VM_reflection(jsjava_vm, jEnv) ||
|
||||
!jsj_InitJavaObjReflectionsTable()) {
|
||||
jsj_LogError("LiveConnect was unable to reflect one or more components of the Java runtime.\nGo to http://bugzilla.mozilla.org/show_bug.cgi?id=5369 for details.\n");
|
||||
/* This function crashes when called from here.
|
||||
Check that all the preconditions for this
|
||||
call are satisfied before making it. [jd]
|
||||
JSJ_DisconnectFromJavaVM(jsjava_vm); */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
if (jsjava_vm_list == NULL) {
|
||||
thread_list_monitor =
|
||||
|
@ -502,6 +467,54 @@ JSJ_ConnectToJavaVM(SystemJavaVM *java_vm_arg, void* initargs)
|
|||
return jsjava_vm;
|
||||
}
|
||||
|
||||
/* Completes a lazy connection to the host Java VM. */
|
||||
static JSBool
|
||||
jsj_ConnectToJavaVM(JSJavaVM *jsjava_vm)
|
||||
{
|
||||
if (!jsjava_vm->java_vm) {
|
||||
SystemJavaVM* java_vm;
|
||||
JNIEnv *jEnv;
|
||||
JSBool ok;
|
||||
JS_ASSERT(JSJ_callbacks->create_java_vm);
|
||||
JS_ASSERT(JSJ_callbacks->destroy_java_vm);
|
||||
|
||||
ok = JSJ_callbacks->create_java_vm(&java_vm, &jEnv, NULL);
|
||||
if (!ok || java_vm == NULL) {
|
||||
jsj_LogError("Failed to create Java VM\n");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Remember that we created the VM so that we know to destroy it later */
|
||||
jsjava_vm->jsj_created_java_vm = JS_TRUE;
|
||||
|
||||
jsjava_vm->java_vm = java_vm;
|
||||
jsjava_vm->main_thread_env = jEnv;
|
||||
|
||||
/*
|
||||
* JVM initialization for netscape.javascript.JSObject is performed
|
||||
* independently of the other classes that are initialized in
|
||||
* init_java_VM_reflection, because we allow it to fail. In the case
|
||||
* of failure, LiveConnect is still operative, but only when calling
|
||||
* from JS to Java and not vice-versa.
|
||||
*/
|
||||
init_netscape_java_classes(jsjava_vm, jEnv);
|
||||
|
||||
/* Load the Java classes, and the method and field descriptors required for
|
||||
Java reflection. */
|
||||
if (!init_java_VM_reflection(jsjava_vm, jEnv) ||
|
||||
!jsj_InitJavaObjReflectionsTable()) {
|
||||
jsj_LogError("LiveConnect was unable to reflect one or more components of the Java runtime.\nGo to http://bugzilla.mozilla.org/show_bug.cgi?id=5369 for details.\n");
|
||||
/* This function crashes when called from here.
|
||||
Check that all the preconditions for this
|
||||
call are satisfied before making it. [jd]
|
||||
JSJ_DisconnectFromJavaVM(jsjava_vm); */
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSJCallbacks *JSJ_callbacks = NULL;
|
||||
|
||||
/* Called once to set up callbacks for all instances of LiveConnect */
|
||||
|
@ -563,35 +576,37 @@ JSJ_InitJSContext(JSContext *cx, JSObject *global_obj,
|
|||
void
|
||||
JSJ_DisconnectFromJavaVM(JSJavaVM *jsjava_vm)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
SystemJavaVM *java_vm;
|
||||
JSJavaVM *j, **jp;
|
||||
|
||||
/* Since JSJ_ConnectToJavaVM is now lazy */
|
||||
java_vm = jsjava_vm->java_vm;
|
||||
jEnv = jsjava_vm->main_thread_env;
|
||||
if (java_vm) {
|
||||
JNIEnv *jEnv = jsjava_vm->main_thread_env;
|
||||
|
||||
/* Drop all references to Java objects and classes */
|
||||
jsj_DiscardJavaObjReflections(jEnv);
|
||||
jsj_DiscardJavaClassReflections(jEnv);
|
||||
/* Drop all references to Java objects and classes */
|
||||
jsj_DiscardJavaObjReflections(jEnv);
|
||||
jsj_DiscardJavaClassReflections(jEnv);
|
||||
|
||||
if (jsjava_vm->jsj_created_java_vm) {
|
||||
(void)JSJ_callbacks->destroy_java_vm(java_vm, jEnv);
|
||||
} else {
|
||||
UNLOAD_CLASS(java/lang/Object, jlObject);
|
||||
UNLOAD_CLASS(java/lang/Class, jlClass);
|
||||
UNLOAD_CLASS(java/lang/reflect/Method, jlrMethod);
|
||||
UNLOAD_CLASS(java/lang/reflect/Constructor, jlrConstructor);
|
||||
UNLOAD_CLASS(java/lang/reflect/Field, jlrField);
|
||||
UNLOAD_CLASS(java/lang/reflect/Array, jlrArray);
|
||||
UNLOAD_CLASS(java/lang/Throwable, jlThrowable);
|
||||
UNLOAD_CLASS(java/lang/System, jlSystem);
|
||||
UNLOAD_CLASS(java/lang/Boolean, jlBoolean);
|
||||
UNLOAD_CLASS(java/lang/Double, jlDouble);
|
||||
UNLOAD_CLASS(java/lang/String, jlString);
|
||||
UNLOAD_CLASS(java/lang/Void, jlVoid);
|
||||
UNLOAD_CLASS(netscape/javascript/JSObject, njJSObject);
|
||||
UNLOAD_CLASS(netscape/javascript/JSException, njJSException);
|
||||
UNLOAD_CLASS(netscape/javascript/JSUtil, njJSUtil);
|
||||
if (jsjava_vm->jsj_created_java_vm) {
|
||||
(void)JSJ_callbacks->destroy_java_vm(java_vm, jEnv);
|
||||
} else {
|
||||
UNLOAD_CLASS(java/lang/Object, jlObject);
|
||||
UNLOAD_CLASS(java/lang/Class, jlClass);
|
||||
UNLOAD_CLASS(java/lang/reflect/Method, jlrMethod);
|
||||
UNLOAD_CLASS(java/lang/reflect/Constructor, jlrConstructor);
|
||||
UNLOAD_CLASS(java/lang/reflect/Field, jlrField);
|
||||
UNLOAD_CLASS(java/lang/reflect/Array, jlrArray);
|
||||
UNLOAD_CLASS(java/lang/Throwable, jlThrowable);
|
||||
UNLOAD_CLASS(java/lang/System, jlSystem);
|
||||
UNLOAD_CLASS(java/lang/Boolean, jlBoolean);
|
||||
UNLOAD_CLASS(java/lang/Double, jlDouble);
|
||||
UNLOAD_CLASS(java/lang/String, jlString);
|
||||
UNLOAD_CLASS(java/lang/Void, jlVoid);
|
||||
UNLOAD_CLASS(netscape/javascript/JSObject, njJSObject);
|
||||
UNLOAD_CLASS(netscape/javascript/JSException, njJSException);
|
||||
UNLOAD_CLASS(netscape/javascript/JSUtil, njJSUtil);
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove this VM from the list of all JSJavaVM objects. */
|
||||
|
@ -649,7 +664,7 @@ find_jsjava_thread(JNIEnv *jEnv)
|
|||
jsj_env = NULL;
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_EnterMonitor(thread_list_monitor);
|
||||
PR_EnterMonitor(thread_list_monitor);
|
||||
#endif
|
||||
|
||||
/* Search for the thread state among the list of all created
|
||||
|
@ -669,7 +684,7 @@ find_jsjava_thread(JNIEnv *jEnv)
|
|||
}
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_ExitMonitor(thread_list_monitor);
|
||||
PR_ExitMonitor(thread_list_monitor);
|
||||
#endif
|
||||
|
||||
return jsj_env;
|
||||
|
@ -681,6 +696,10 @@ JSJ_AttachCurrentThreadToJava(JSJavaVM *jsjava_vm, const char *name, JNIEnv **ja
|
|||
JNIEnv *jEnv;
|
||||
SystemJavaVM *java_vm;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
/* Make sure we're fully connected to the Java VM */
|
||||
if (!jsj_ConnectToJavaVM(jsjava_vm))
|
||||
return NULL;
|
||||
|
||||
/* Try to attach a Java thread to the current native thread */
|
||||
java_vm = jsjava_vm->java_vm;
|
||||
|
|
Загрузка…
Ссылка в новой задаче