📄 jsj.c
字号:
LOAD_METHOD(java.lang.Boolean, booleanValue, "()Z", jlBoolean); LOAD_STATIC_METHOD(java.lang.System, identityHashCode, "(Ljava/lang/Object;)I", jlSystem); LOAD_CONSTRUCTOR(java.lang.Boolean, Boolean, "(Z)V", jlBoolean); LOAD_CONSTRUCTOR(java.lang.Double, Double, "(D)V", jlDouble); LOAD_FIELD_OBJ(java.lang.Void, TYPE, "Ljava/lang/Class;", jlVoid); return JS_TRUE;}#if !defined(OJI) /** * Workaround for the fact that MRJ loads a different instance of the shared library. */#include "netscape_javascript_JSObject.h"/* Manually load the required native methods. */static JSBoolJSObject_RegisterNativeMethods(JNIEnv* jEnv){ static JNINativeMethod nativeMethods[] = { {"initClass", "()V", (void*)&Java_netscape_javascript_JSObject_initClass},#ifndef OJI {"getMember", "(Ljava/lang/String;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_getMember}, {"getSlot", "(I)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_getSlot}, {"setMember", "(Ljava/lang/String;Ljava/lang/Object;)V", (void*)&Java_netscape_javascript_JSObject_setMember}, {"setSlot", "(ILjava/lang/Object;)V", (void*)&Java_netscape_javascript_JSObject_setSlot}, {"removeMember", "(Ljava/lang/String;)V", (void*)&Java_netscape_javascript_JSObject_removeMember}, {"call", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_call}, {"eval", "(Ljava/lang/String;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_eval}, {"toString", "()Ljava/lang/String;", (void*)&Java_netscape_javascript_JSObject_toString}, {"getWindow", "(Ljava/applet/Applet;)Lnetscape/javascript/JSObject;", (void*)&Java_netscape_javascript_JSObject_getWindow}, {"finalize", "()V", (void*)&Java_netscape_javascript_JSObject_finalize}, {"equals", "(Ljava/lang/Object;)Z", (void*)&Java_netscape_javascript_JSObject_equals}#endif /* !OJI */ }; (*jEnv)->RegisterNatives(jEnv, njJSObject, nativeMethods, sizeof(nativeMethods) / sizeof(JNINativeMethod)); if ((*jEnv)->ExceptionOccurred(jEnv)) { report_java_initialization_error(jEnv, "Couldn't initialize JSObject native methods."); (*jEnv)->ExceptionClear(jEnv); return JS_FALSE; } /* Call the initClass method */ Java_netscape_javascript_JSObject_initClass(jEnv, njJSObject); return JS_TRUE;}#endif/* Load Netscape-specific Java extension classes, methods, and fields */static JSBoolinit_netscape_java_classes(JSJavaVM *jsjava_vm, JNIEnv *jEnv){ LOAD_CLASS(netscape/javascript/JSObject, njJSObject); LOAD_CLASS(netscape/javascript/JSException, njJSException); LOAD_CLASS(netscape/javascript/JSUtil, njJSUtil);#if !defined(OJI) JSObject_RegisterNativeMethods(jEnv);#endif#ifndef OJI LOAD_CONSTRUCTOR(netscape.javascript.JSObject, JSObject, "(I)V", njJSObject);#endif LOAD_CONSTRUCTOR(netscape.javascript.JSException, JSException, "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;I)V", njJSException); /* Load second constructor for wrapping JS exception objects inside JSExceptions */ _LOAD_METHOD(netscape.javascript.JSException,<init>, JSException_wrap, "(ILjava/lang/Object;)V", njJSException, JS_FALSE);#ifndef OJI LOAD_FIELDID(netscape.javascript.JSObject, internal, "I", njJSObject);#endif LOAD_FIELDID(netscape.javascript.JSException, lineno, "I", njJSException); LOAD_FIELDID(netscape.javascript.JSException, tokenIndex, "I", njJSException); LOAD_FIELDID(netscape.javascript.JSException, source, "Ljava/lang/String;", njJSException); LOAD_FIELDID(netscape.javascript.JSException, filename, "Ljava/lang/String;", njJSException); LOAD_FIELDID(netscape.javascript.JSException, wrappedExceptionType, "I", njJSException); LOAD_FIELDID(netscape.javascript.JSException, wrappedException, "Ljava/lang/Object;", njJSException); LOAD_STATIC_METHOD(netscape.javascript.JSUtil, getStackTrace, "(Ljava/lang/Throwable;)Ljava/lang/String;", njJSUtil); return JS_TRUE;}JSJavaVM *jsjava_vm_list = NULL;static JSJavaThreadState *thread_list = NULL;#ifdef JSJ_THREADSAFEstatic PRMonitor *thread_list_monitor = NULL;#endif/* * Called once per Java VM, this function initializes the classes, fields, and * methods required for Java reflection. If java_vm is NULL, a new Java VM is * created, using the provided classpath in addition to any default classpath. * The classpath argument is ignored, however, if java_vm_arg is non-NULL. */JSJavaVM *JSJ_ConnectToJavaVM(SystemJavaVM *java_vm_arg, void* initargs){ SystemJavaVM* java_vm; JSJavaVM *jsjava_vm; JNIEnv *jEnv; JS_ASSERT(JSJ_callbacks); JS_ASSERT(JSJ_callbacks->attach_current_thread); JS_ASSERT(JSJ_callbacks->detach_current_thread); JS_ASSERT(JSJ_callbacks->get_java_vm); jsjava_vm = (JSJavaVM*)malloc(sizeof(JSJavaVM)); if (!jsjava_vm) return NULL; memset(jsjava_vm, 0, sizeof(JSJavaVM)); java_vm = java_vm_arg; /* If a Java VM was passed in, try to attach to it on the current thread. */ if (java_vm) { jEnv = JSJ_callbacks->attach_current_thread(java_vm); if (jEnv == NULL) { jsj_LogError("Failed to attach to Java VM thread\n"); free(jsjava_vm); return NULL; } jsjava_vm->java_vm = java_vm; jsjava_vm->main_thread_env = jEnv; } else { jsjava_vm->init_args = initargs; } #ifdef JSJ_THREADSAFE if (jsjava_vm_list == NULL) { thread_list_monitor = (struct PRMonitor *) PR_NewMonitor(); }#endif /* JSJ_THREADSAFE */ /* Put this VM on the list of all created VMs */ jsjava_vm->next = jsjava_vm_list; jsjava_vm_list = jsjava_vm; return jsjava_vm;}/* Completes a lazy connection to the host Java VM. */static JSBooljsj_ConnectToJavaVM(JSJavaVM *jsjava_vm){ if (!jsjava_vm->java_vm) { JSBool ok; JS_ASSERT(JSJ_callbacks->create_java_vm); JS_ASSERT(JSJ_callbacks->destroy_java_vm); ok = JSJ_callbacks->create_java_vm(&jsjava_vm->java_vm, &jsjava_vm->main_thread_env, jsjava_vm->init_args); if (!ok) { 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; } if (!jsjava_vm->jsj_inited_java_vm) { /* * 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, jsjava_vm->main_thread_env); /* Load the Java classes, and the method and field descriptors required for Java reflection. */ if (!init_java_VM_reflection(jsjava_vm, jsjava_vm->main_thread_env) || !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; } jsjava_vm->jsj_inited_java_vm = JS_TRUE; } return JS_TRUE;}JSJCallbacks *JSJ_callbacks = NULL;/* Called once to set up callbacks for all instances of LiveConnect */voidJSJ_Init(JSJCallbacks *callbacks){ JS_ASSERT(callbacks); JSJ_callbacks = callbacks;}/* * Initialize the provided JSContext by setting up the JS classes necessary for * reflection and by defining JavaPackage objects for the default Java packages * as properties of global_obj. Additional packages may be pre-defined by * setting the predefined_packages argument. (Pre-defining a Java package at * initialization time is not necessary, but it will make package lookup faster * and, more importantly, will avoid unnecessary network accesses if classes * are being loaded over the network.) */JSBoolJSJ_InitJSContext(JSContext *cx, JSObject *global_obj, JavaPackageDef *predefined_packages){ /* Initialize the JavaScript classes used for reflection */ if (!jsj_init_JavaObject(cx, global_obj)) return JS_FALSE; /* if (!jsj_init_JavaMember(cx, global_obj)) return JS_FALSE; */ if (!jsj_init_JavaPackage(cx, global_obj, predefined_packages)) return JS_FALSE; if (!jsj_init_JavaClass(cx, global_obj)) return JS_FALSE; if (!jsj_init_JavaArray(cx, global_obj)) return JS_FALSE; if (!jsj_init_JavaMember(cx, global_obj)) return JS_FALSE; return JS_TRUE;}/* Eliminate a reference to a Java class */#define UNLOAD_CLASS(qualified_name, class) \ if (class) { \ (*jEnv)->DeleteGlobalRef(jEnv, class); \ class = NULL; \ }/* * This routine severs the connection to a Java VM, freeing all related resources. * It shouldn't be called until the global scope has been cleared in all related * JSContexts (so that all LiveConnect objects are finalized) and a JavaScript * GC is performed. Otherwise, accessed to free'ed memory could result. */voidJSJ_DisconnectFromJavaVM(JSJavaVM *jsjava_vm){ SystemJavaVM *java_vm; JSJavaVM *j, **jp; /* Since JSJ_ConnectToJavaVM is now lazy */ java_vm = jsjava_vm->java_vm; if (java_vm) { JNIEnv *jEnv = jsjava_vm->main_thread_env; /* 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -