📄 jsj.c
字号:
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(java/applet/Applet, jaApplet); 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. */ for (jp = &jsjava_vm_list; (j = *jp) != NULL; jp = &j->next) { if (j == jsjava_vm) { *jp = jsjava_vm->next; break; } } JS_ASSERT(j); /* vm not found in list */#ifdef JSJ_THREADSAFE if (jsjava_vm_list == NULL) { PR_DestroyMonitor(thread_list_monitor); thread_list_monitor = NULL; }#endif /* JSJ_THREADSAFE */ free(jsjava_vm);}static JSJavaThreadState *new_jsjava_thread_state(JSJavaVM *jsjava_vm, const char *thread_name, JNIEnv *jEnv){ JSJavaThreadState *jsj_env; jsj_env = (JSJavaThreadState *)malloc(sizeof(JSJavaThreadState)); if (!jsj_env) return NULL; memset(jsj_env, 0, sizeof(JSJavaThreadState)); jsj_env->jEnv = jEnv; jsj_env->jsjava_vm = jsjava_vm; if (thread_name) jsj_env->name = strdup(thread_name);#ifdef JSJ_THREADSAFE PR_EnterMonitor(thread_list_monitor);#endif jsj_env->next = thread_list; thread_list = jsj_env;#ifdef JSJ_THREADSAFE PR_ExitMonitor(thread_list_monitor);#endif return jsj_env;}static JSJavaThreadState *find_jsjava_thread(JNIEnv *jEnv){ JSJavaThreadState *e, **p, *jsj_env; jsj_env = NULL;#ifdef JSJ_THREADSAFE PR_EnterMonitor(thread_list_monitor);#endif /* Search for the thread state among the list of all created LiveConnect threads */ for (p = &thread_list; (e = *p) != NULL; p = &(e->next)) { if (e->jEnv == jEnv) { jsj_env = e; break; } } /* Move a found thread to head of list for faster search next time. */ if (jsj_env && p != &thread_list) { *p = jsj_env->next; jsj_env->next = thread_list; thread_list = jsj_env; } #ifdef JSJ_THREADSAFE PR_ExitMonitor(thread_list_monitor);#endif return jsj_env;}JS_EXPORT_API(JSJavaThreadState *)JSJ_AttachCurrentThreadToJava(JSJavaVM *jsjava_vm, const char *name, JNIEnv **java_envp){ 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; if (JSJ_callbacks && JSJ_callbacks->attach_current_thread) jEnv = JSJ_callbacks->attach_current_thread(java_vm); else return NULL; if (jEnv == NULL) return NULL; /* If we found an existing thread state, just return it. */ jsj_env = find_jsjava_thread(jEnv); if (jsj_env) return jsj_env; /* Create a new wrapper around the thread/VM state */ jsj_env = new_jsjava_thread_state(jsjava_vm, name, jEnv); if (java_envp) *java_envp = jEnv; return jsj_env;}static JSJavaVM *map_java_vm_to_jsjava_vm(SystemJavaVM *java_vm){ JSJavaVM *v; for (v = jsjava_vm_list; v; v = v->next) { if (!jsj_ConnectToJavaVM(v)) return NULL; if (v->java_vm == java_vm) return v; } return NULL;}/* * Unfortunately, there's no standard means to associate any private data with * a JNI thread environment, so we need to use the Java environment pointer as * the key in a lookup table that maps it to a JSJavaThreadState structure, * where we store all our per-thread private data. If no existing thread state * is found, a new one is created. * * If an error occurs, returns NULL and sets the errp argument to an error * message, which the caller is responsible for free'ing. */JSJavaThreadState *jsj_MapJavaThreadToJSJavaThreadState(JNIEnv *jEnv, char **errp){ JSJavaThreadState *jsj_env; SystemJavaVM *java_vm; JSJavaVM *jsjava_vm; /* If we found an existing thread state, just return it. */ jsj_env = find_jsjava_thread(jEnv); if (jsj_env) return jsj_env; /* No one set up a LiveConnect thread state for a given Java thread. Invoke the callback to create one on-the-fly. */ /* First, figure out which Java VM is calling us */ if (JSJ_callbacks && JSJ_callbacks->get_java_vm) java_vm = JSJ_callbacks->get_java_vm(jEnv); else return NULL; if (java_vm == NULL) return NULL; /* Get our private JavaVM data */ jsjava_vm = map_java_vm_to_jsjava_vm(java_vm); if (!jsjava_vm) { *errp = JS_smprintf("Total weirdness: No JSJavaVM wrapper ever created " "for JavaVM 0x%08x", java_vm); return NULL; } jsj_env = new_jsjava_thread_state(jsjava_vm, NULL, jEnv); if (!jsj_env) return NULL; return jsj_env;}/* * This function is used to specify a particular JSContext as *the* JavaScript * execution environment to be used when LiveConnect is accessed from the given * Java thread, i.e. by using one of the methods of netscape.javascript.JSObject. * (There can only be one such JS context for a given Java thread. To * multiplex JSContexts among a single thread, this function must be called * before Java is invoked on that thread.) The return value is the previous * context associated with the given Java thread. */JS_EXPORT_API(JSContext *)JSJ_SetDefaultJSContextForJavaThread(JSContext *cx, JSJavaThreadState *jsj_env){ JSContext *old_context; old_context = jsj_env->cx; jsj_env->cx = cx; /* The following line prevents clearing of jsj_env->cx by jsj_ExitJava() */ jsj_env->recursion_depth++; return old_context;}JS_EXPORT_API(JSBool)JSJ_DetachCurrentThreadFromJava(JSJavaThreadState *jsj_env){ SystemJavaVM *java_vm; JNIEnv* jEnv; JSJavaThreadState *e, **p; /* Disassociate the current native thread from its corresponding Java thread */ java_vm = jsj_env->jsjava_vm->java_vm; jEnv = jsj_env->jEnv;#ifdef JSJ_THREADSAFE PR_EnterMonitor(thread_list_monitor);#endif /* JSJ_THREADSAFE */ if (!JSJ_callbacks->detach_current_thread(java_vm, jEnv)) {#ifdef JSJ_THREADSAFE PR_ExitMonitor(thread_list_monitor);#endif /* JSJ_THREADSAFE */ return JS_FALSE; } /* Destroy the LiveConnect execution environment passed in */ jsj_ClearPendingJSErrors(jsj_env); for (p = &thread_list; (e = *p) != NULL; p = &(e->next)) { if (e == jsj_env) { *p = jsj_env->next; break; } } JS_ASSERT(e);#ifdef JSJ_THREADSAFE PR_ExitMonitor(thread_list_monitor);#endif /* JSJ_THREADSAFE */ free(jsj_env); return JS_TRUE;}/* Utility routine to wrap a Java object inside a JS object, having a a result type of either JavaObject or JavaArray. */JSBoolJSJ_ConvertJavaObjectToJSValue(JSContext *cx, jobject java_obj, jsval *vp){ JNIEnv *jEnv; JSBool result; JSJavaThreadState *jsj_env; /* Get the Java per-thread environment pointer for this JSContext */ jsj_env = jsj_EnterJava(cx, &jEnv); if (!jEnv) return JS_FALSE; result = jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, vp); jsj_ExitJava(jsj_env); return result;}JS_EXPORT_API(JSBool)JSJ_ConvertJSValueToJavaObject(JSContext *cx, jsval v, jobject *vp){ if (!JSVAL_IS_PRIMITIVE(v)) { JSObject *js_obj = JSVAL_TO_OBJECT(v); JavaObjectWrapper *java_wrapper = JS_GetPrivate(cx, js_obj); *vp = java_wrapper->java_obj; return JS_TRUE; } return JS_FALSE;}JS_EXPORT_API(JSBool)JSJ_IsJSCallApplet(){ return jsj_JSIsCallingApplet;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -