📄 jsj_class.c
字号:
if (!java_class) { jsj_UnexpectedJavaError(cx, jEnv, "Unable to reference Java class"); goto error; } class_descriptor->java_class = java_class; if (!compute_java_class_signature(cx, jEnv, class_descriptor)) goto error; class_descriptor->modifiers = (*jEnv)->CallIntMethod(jEnv, java_class, jlClass_getModifiers); class_descriptor->ref_count = 1; if (!JSJ_HashTableAdd(java_class_reflections, java_class, class_descriptor, (void*)jEnv)) goto error; return class_descriptor;error: destroy_class_descriptor(cx, jEnv, class_descriptor); return NULL;}/* Trivial helper for jsj_DiscardJavaClassReflections(), below */JS_STATIC_DLL_CALLBACK(JSIntn)enumerate_remove_java_class(JSJHashEntry *he, JSIntn i, void *arg){ JSJavaThreadState *jsj_env = (JSJavaThreadState *)arg; JavaClassDescriptor *class_descriptor; class_descriptor = (JavaClassDescriptor*)he->value; destroy_class_descriptor(jsj_env->cx, jsj_env->jEnv, class_descriptor); return HT_ENUMERATE_REMOVE;}/* This shutdown routine discards all JNI references to Java objects that have been reflected into JS, even if there are still references to them from JS. */voidjsj_DiscardJavaClassReflections(JNIEnv *jEnv){ JSJavaThreadState *jsj_env; char *err_msg; JSContext *cx; /* Get the per-thread state corresponding to the current Java thread */ jsj_env = jsj_MapJavaThreadToJSJavaThreadState(jEnv, &err_msg); JS_ASSERT(jsj_env); if (!jsj_env) return; /* Get the JSContext that we're supposed to use for this Java thread */ cx = jsj_env->cx; if (!cx) { /* We called spontaneously into JS from Java, rather than from JS into Java and back into JS. Invoke a callback to obtain/create a JSContext for us to use. */ if (JSJ_callbacks->map_jsj_thread_to_js_context) {#ifdef OJI cx = JSJ_callbacks->map_jsj_thread_to_js_context(jsj_env, NULL, /* FIXME: What should this argument be ? */ jEnv, &err_msg);#else cx = JSJ_callbacks->map_jsj_thread_to_js_context(jsj_env, jEnv, &err_msg);#endif if (!cx) return; } else { err_msg = JS_smprintf("Unable to find/create JavaScript execution " "context for JNI thread 0x%08x", jEnv); jsj_LogError(err_msg); free(err_msg); return; } } if (java_class_reflections) { JSJ_HashTableEnumerateEntries(java_class_reflections, enumerate_remove_java_class, (void*)jsj_env); JSJ_HashTableDestroy(java_class_reflections); java_class_reflections = NULL; }}extern JavaClassDescriptor *jsj_GetJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, jclass java_class){ JavaClassDescriptor *class_descriptor = NULL;#ifdef JSJ_THREADSAFE PR_EnterMonitor(java_class_reflections_monitor);#endif if (java_class_reflections) { class_descriptor = JSJ_HashTableLookup(java_class_reflections, (const void *)java_class, (void*)jEnv); } if (!class_descriptor) { class_descriptor = new_class_descriptor(cx, jEnv, java_class);#ifdef JSJ_THREADSAFE PR_ExitMonitor(java_class_reflections_monitor);#endif return class_descriptor; }#ifdef JSJ_THREADSAFE PR_ExitMonitor(java_class_reflections_monitor);#endif JS_ASSERT(class_descriptor->ref_count > 0); class_descriptor->ref_count++; return class_descriptor;}voidjsj_ReleaseJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor){#if 0 /* The ref-counting code doesn't work very well because cycles in the data structures routinely lead to uncollectible JavaClassDescriptor's. Skip it. */ JS_ASSERT(class_descriptor->ref_count >= 1); if (!--class_descriptor->ref_count) { JSJ_HashTableRemove(java_class_reflections, class_descriptor->java_class, (void*)jEnv); destroy_class_descriptor(cx, jEnv, class_descriptor); }#endif}#ifdef JSJ_THREADSAFEstatic PRMonitor *java_reflect_monitor = NULL;#endifstatic JSBoolreflect_java_methods_and_fields(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor, JSBool reflect_statics_only){ JavaMemberDescriptor *member_descriptor; JSBool success; success = JS_TRUE; /* optimism */#ifdef JSJ_THREADSAFE PR_EnterMonitor(java_reflect_monitor);#endif /* See if we raced with another thread to reflect members of this class. If the status is REFLECT_COMPLETE, another thread beat us to it. If the status is REFLECT_IN_PROGRESS, we've recursively called this function within a single thread. Either way, we're done. */ if (reflect_statics_only) { if (class_descriptor->static_members_reflected != REFLECT_NO) goto done; class_descriptor->static_members_reflected = REFLECT_IN_PROGRESS; } else { if (class_descriptor->instance_members_reflected != REFLECT_NO) goto done; class_descriptor->instance_members_reflected = REFLECT_IN_PROGRESS; } if (!jsj_ReflectJavaMethods(cx, jEnv, class_descriptor, reflect_statics_only)) goto error; if (!jsj_ReflectJavaFields(cx, jEnv, class_descriptor, reflect_statics_only)) goto error; if (reflect_statics_only) { member_descriptor = class_descriptor->static_members; while (member_descriptor) { class_descriptor->num_static_members++; member_descriptor = member_descriptor->next; } class_descriptor->static_members_reflected = REFLECT_COMPLETE; } else { member_descriptor = class_descriptor->instance_members; while (member_descriptor) { class_descriptor->num_instance_members++; member_descriptor = member_descriptor->next; } class_descriptor->instance_members_reflected = REFLECT_COMPLETE; }done:#ifdef JSJ_THREADSAFE PR_ExitMonitor(java_reflect_monitor);#endif return success;error: success = JS_FALSE; goto done;}JavaMemberDescriptor *jsj_GetClassStaticMembers(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor){ if (class_descriptor->static_members_reflected != REFLECT_COMPLETE) reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_TRUE); return class_descriptor->static_members;}JavaMemberDescriptor *jsj_GetClassInstanceMembers(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor){ if (class_descriptor->instance_members_reflected != REFLECT_COMPLETE) reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_FALSE); return class_descriptor->instance_members;}JavaMemberDescriptor *jsj_LookupJavaStaticMemberDescriptorById(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor, jsid id){ JavaMemberDescriptor *member_descriptor; member_descriptor = jsj_GetClassStaticMembers(cx, jEnv, class_descriptor); while (member_descriptor) { if (id == member_descriptor->id) return member_descriptor; member_descriptor = member_descriptor->next; } return NULL;}JavaMemberDescriptor *jsj_GetJavaStaticMemberDescriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor, jstring member_name_jstr){ JavaMemberDescriptor *member_descriptor; jsid id; if (!JavaStringToId(cx, jEnv, member_name_jstr, &id)) return NULL; member_descriptor = jsj_LookupJavaStaticMemberDescriptorById(cx, jEnv, class_descriptor, id); if (member_descriptor) return member_descriptor; member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor)); if (!member_descriptor) return NULL; memset(member_descriptor, 0, sizeof(JavaMemberDescriptor)); member_descriptor->name = jsj_DupJavaStringUTF(cx, jEnv, member_name_jstr); if (!member_descriptor->name) { JS_free(cx, member_descriptor); return NULL; } member_descriptor->id = id; member_descriptor->next = class_descriptor->static_members; class_descriptor->static_members = member_descriptor; return member_descriptor;}JavaMemberDescriptor *jsj_GetJavaClassConstructors(JSContext *cx, JavaClassDescriptor *class_descriptor){ JavaMemberDescriptor *member_descriptor; if (class_descriptor->constructors) return class_descriptor->constructors; member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor)); if (!member_descriptor) return NULL; memset(member_descriptor, 0, sizeof(JavaMemberDescriptor)); member_descriptor->name = JS_strdup(cx, "<init>"); if (!member_descriptor->name) { JS_free(cx, member_descriptor); return NULL; } class_descriptor->constructors = member_descriptor; return member_descriptor;}JavaMemberDescriptor *jsj_LookupJavaClassConstructors(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor){ if (class_descriptor->static_members_reflected != REFLECT_COMPLETE) reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_TRUE); return class_descriptor->constructors;}JavaMemberDescriptor *jsj_LookupJavaMemberDescriptorById(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor, jsid id){ JavaMemberDescriptor *member_descriptor; member_descriptor = jsj_GetClassInstanceMembers(cx, jEnv, class_descriptor); while (member_descriptor) { if (id == member_descriptor->id) return member_descriptor; member_descriptor = member_descriptor->next; } return NULL;}JavaMemberDescriptor *jsj_GetJavaMemberDescriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor, jstring member_name_jstr){ JavaMemberDescriptor *member_descriptor; jsid id; if (!JavaStringToId(cx, jEnv, member_name_jstr, &id)) return NULL; member_descriptor = jsj_LookupJavaMemberDescriptorById(cx, jEnv, class_descriptor, id); if (member_descriptor) return member_descriptor; member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor)); if (!member_descriptor) return NULL; memset(member_descriptor, 0, sizeof(JavaMemberDescriptor)); member_descriptor->name = jsj_DupJavaStringUTF(cx, jEnv, member_name_jstr); if (!member_descriptor->name) { JS_free(cx, member_descriptor); return NULL; } member_descriptor->id = id; member_descriptor->next = class_descriptor->instance_members; class_descriptor->instance_members = member_descriptor; return member_descriptor;}JSBooljsj_InitJavaClassReflectionsTable(){ if (!java_class_reflections) { java_class_reflections = JSJ_NewHashTable(64, jsj_HashJavaObject, jsj_JavaObjectComparator, NULL, NULL, NULL); if (!java_class_reflections) return JS_FALSE;#ifdef JSJ_THREADSAFE java_class_reflections_monitor = (struct PRMonitor *) PR_NewMonitor(); if (!java_class_reflections_monitor) return JS_FALSE; java_reflect_monitor = (struct PRMonitor *) PR_NewMonitor(); if (!java_reflect_monitor) return JS_FALSE;#endif } return JS_TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -