⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsj_class.c

📁 caffeine-monkey java实现的js模拟引擎
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -