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

📄 jsj_method.c

📁 caffeine-monkey java实现的js模拟引擎
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (lowest_cost != 0)        return NULL;    return best_method_match;}#else   /* !OLD_STYLE_METHOD_RESOLUTION *//* * Determine the more natural (preferred) JavaScript->Java conversion * given one JavaScript value and two Java types. * See http://www.mozilla.org/js/liveconnect/lc3_method_overloading.html * for details. */static JSJTypePreferencepreferred_conversion(JSContext *cx, JNIEnv *jEnv, jsval js_val,                     JavaClassDescriptor *descriptor1,                     JavaClassDescriptor *descriptor2){    JSJType js_type;    int rank1, rank2;    jclass java_class1, java_class2;    JavaObjectWrapper *java_wrapper;    jobject java_obj;    JSObject *js_obj;        js_type = compute_jsj_type(cx, js_val);    rank1 = rank_table[js_type][(int)descriptor1->type - 2];    rank2 = rank_table[js_type][(int)descriptor2->type - 2];            /* Fast path for conversion from most JS types */      if (rank1 < rank2)        return JSJPREF_FIRST_ARG;    /*     * Special logic is required for matching the classes of wrapped     * Java objects.     */    if (rank2 == 0) {        java_class1 = descriptor1->java_class;        java_class2 = descriptor2->java_class;                js_obj = JSVAL_TO_OBJECT(js_val);        java_wrapper = JS_GetPrivate(cx, js_obj);        java_obj = java_wrapper->java_obj;                /* Unwrapped JavaObject must be compatible with Java arg type */        if (!(*jEnv)->IsInstanceOf(jEnv, java_obj, java_class2))            return JSJPREF_FIRST_ARG;        /*         * For JavaObject arguments, any compatible reference type is preferable         * to any primitive Java type or to java.lang.String.         */        if (rank1 != 0)            return JSJPREF_SECOND_ARG;                /*         * If argument of type descriptor1 is subclass of type descriptor 2, then         * descriptor1 is preferred and vice-versa.         */        if ((*jEnv)->IsAssignableFrom(jEnv, java_class1, java_class2))            return JSJPREF_FIRST_ARG;                if ((*jEnv)->IsAssignableFrom(jEnv, java_class2, java_class1))            return JSJPREF_SECOND_ARG;        /* This can happen in unusual situations involving interface types. */        return JSJPREF_AMBIGUOUS;    }        if (rank1 > rank2)        return JSJPREF_SECOND_ARG;        return JSJPREF_AMBIGUOUS;}              static JSJTypePreferencemethod_preferred(JSContext *cx, JNIEnv *jEnv, jsval *argv,                 JavaMethodSignature *method_signature1,                 JavaMethodSignature *method_signature2){    int arg_index, argc, preference;    jsval val;    JavaSignature* *arg_signatures1;    JavaSignature* *arg_signatures2;    JavaSignature *arg_type1, *arg_type2;    arg_signatures1 = method_signature1->arg_signatures;    arg_signatures2 = method_signature2->arg_signatures;    argc = method_signature1->num_args;    JS_ASSERT(argc == method_signature2->num_args);    preference = 0;    for (arg_index = 0; arg_index < argc; arg_index++) {        val = argv[arg_index];        arg_type1 = *arg_signatures1++;        arg_type2 = *arg_signatures2++;        if (arg_type1 == arg_type2)            continue;        preference |= preferred_conversion(cx, jEnv, val, arg_type1, arg_type2);        if ((JSJTypePreference)preference == JSJPREF_AMBIGUOUS)            return JSJPREF_AMBIGUOUS;    }    return (JSJTypePreference)preference;}/* * This routine applies heuristics to guess the intended Java method given the * runtime JavaScript argument types and the type signatures of the candidate * methods.  Informally, the method with Java parameter types that most closely * match the JavaScript types is chosen.  A more precise specification is * provided in the lc3_method_resolution.html file.  The code uses a very * brute-force approach. */static JavaMethodSpec *resolve_overloaded_method(JSContext *cx, JNIEnv *jEnv,                          JavaMemberDescriptor *member_descriptor,                          JavaClassDescriptor *class_descriptor,                          JSBool is_static_method,                          uintN argc, jsval *argv){    JSJTypePreference preference;    JavaMethodSpec *method, *best_method_match;    MethodList ambiguous_methods;    MethodListElement *method_list_element, *next_element;    /*     * Determine the first Java method among the overloaded methods of the same name     * that matches all the JS arguments.     */    for (method = member_descriptor->methods; method; method = method->next) {        if (method_signature_matches_JS_args(cx, jEnv, argc, argv, &method->signature))            break;    }    /* Report an error if no method matched the JS arguments */    if (!method) {        report_method_match_failure(cx, member_descriptor, class_descriptor,                                    is_static_method, argc, argv);        return NULL;    }    /* Shortcut a common case */    if (!method->next)        return method;    /*     * Form a list of all methods that are neither more or less preferred than the     * best matching method discovered so far.     */    JS_INIT_CLIST(&ambiguous_methods);    best_method_match = method;    /* See if there are any Java methods that are a better fit for the JS args */    for (method = method->next; method; method = method->next) {        if (method->signature.num_args != (int)argc)            continue;        preference = method_preferred(cx, jEnv, argv, &best_method_match->signature,                                      &method->signature);        if (preference == JSJPREF_SECOND_ARG) {            best_method_match = method;        } else  if (preference == JSJPREF_AMBIGUOUS) {            /* Add this method to the list of ambiguous methods */            method_list_element =                (MethodListElement*)JS_malloc(cx, sizeof(MethodListElement));            if (!method_list_element)                goto error;            method_list_element->method = method;            JS_APPEND_LINK(&method_list_element->linkage, &ambiguous_methods);        }    }        /*     * Ensure that best_method_match is preferred to all methods on the     * ambiguous_methods list.     */        for (method_list_element = (MethodListElement*)JS_LIST_HEAD(&ambiguous_methods);        (MethodList*)method_list_element != &ambiguous_methods;         method_list_element = next_element) {        next_element = (MethodListElement*)method_list_element->linkage.next;        method = method_list_element->method;        preference = method_preferred(cx, jEnv, argv, &best_method_match->signature,                                      &method->signature);        if (preference != JSJPREF_FIRST_ARG)            continue;        JS_REMOVE_LINK(&method_list_element->linkage);        JS_free(cx, method_list_element);    }        /*     * The chosen method must be maximally preferred, i.e. there can be no other     * method that is just as preferred.     */    if (!JS_CLIST_IS_EMPTY(&ambiguous_methods)) {        /* Add the best_method_match to the list of ambiguous methods */	method_list_element =	    (MethodListElement*)JS_malloc(cx, sizeof(MethodListElement));	if (!method_list_element)	    goto error;	method_list_element->method = best_method_match;	JS_APPEND_LINK(&method_list_element->linkage, &ambiguous_methods);	/* Report the problem */        report_ambiguous_method_match(cx, member_descriptor, class_descriptor,                                      &ambiguous_methods, is_static_method, argc, argv);        goto error;    }    return best_method_match;error:    /* Delete the storage for the ambiguous_method list */    while (!JS_CLIST_IS_EMPTY(&ambiguous_methods)) {        method_list_element = (MethodListElement*)JS_LIST_HEAD(&ambiguous_methods);        JS_REMOVE_LINK(&method_list_element->linkage);        JS_free(cx, method_list_element);    }    return NULL;}#endif  /* !HAS_OLD_STYLE_METHOD_RESOLUTION */static jvalue *convert_JS_method_args_to_java_argv(JSContext *cx, JNIEnv *jEnv, jsval *argv,                        JavaMethodSpec *method, JSBool **localvp){    jvalue *jargv;    JSBool ok, *localv;    uintN i, argc;    JavaSignature **arg_signatures;    JavaMethodSignature *signature;            signature = &method->signature;    argc = signature->num_args;    JS_ASSERT(argc != 0);    arg_signatures = signature->arg_signatures;        jargv = (jvalue *)JS_malloc(cx, sizeof(jvalue) * argc);        if (!jargv)        return NULL;    /*     * Allocate an array that contains a flag for each argument, indicating whether     * or not the conversion from a JS value to a Java value resulted in a new     * JNI local reference.     */    localv = (JSBool *)JS_malloc(cx, sizeof(JSBool) * argc);    *localvp = localv;    if (!localv) {        JS_free(cx, jargv);        return NULL;    }     for (i = 0; i < argc; i++) {        int dummy_cost;                ok = jsj_ConvertJSValueToJavaValue(cx, jEnv, argv[i], arg_signatures[i],                                           &dummy_cost, &jargv[i], &localv[i]);        if (!ok) {            JS_free(cx, jargv);            JS_free(cx, localv);            *localvp = NULL;            return NULL;        }    }    return jargv;}  static JSBoolinvoke_java_method(JSContext *cx, JSJavaThreadState *jsj_env,                   jobject java_class_or_instance,                   JavaClassDescriptor *class_descriptor,                   JavaMethodSpec *method,                   JSBool is_static_method,                   jsval *argv, jsval *vp){    jvalue java_value;    jvalue *jargv;    uintN argc, i;    jobject java_object;    jclass java_class;    jmethodID methodID;    JavaMethodSignature *signature;    JavaSignature *return_val_signature;    JNIEnv *jEnv;    JSBool *localv, error_occurred, success;    success = error_occurred = JS_FALSE;    return_val_signature = NULL;    /* Quiet gcc uninitialized variable warning */    methodID = method->methodID;    signature = &method->signature;    argc = signature->num_args;    jEnv = jsj_env->jEnv;    if (is_static_method) {        java_object = NULL;        java_class = java_class_or_instance;    } else {        java_object = java_class_or_instance;        java_class = NULL;    }    jargv = NULL;    localv = NULL;    if (argc) {        jargv = convert_JS_method_args_to_java_argv(cx, jEnv, argv, method, &localv);        if (!jargv) {            error_occurred = JS_TRUE;            goto out;        }    }    /* Prevent deadlocking if we re-enter JS on another thread as a result of a Java       method call and that new thread wants to perform a GC. */#ifdef JSJ_THREADSAFE    JS_EndRequest(cx);#endif#define CALL_JAVA_METHOD(type, member)                                       \    JS_BEGIN_MACRO                                                           \    if (is_static_method) {                                                  \        java_value.member = (*jEnv)->CallStatic##type##MethodA(jEnv, java_class, methodID, jargv);\    } else {                                                                 \        java_value.member = (*jEnv)->Call##type##MethodA(jEnv, java_object, methodID, jargv);\    }                                                                        \    if ((*jEnv)->ExceptionOccurred(jEnv)) {                                  \        jsj_ReportJavaError(cx, jEnv, "Error calling method %s.%s()",        \                            class_descriptor->name, method->name);           \        error_occurred = JS_TRUE;                                            \        goto out;                                                            \    }                                                                        \    JS_END_MACRO    return_val_signature = signature->return_val_signature;    switch(return_val_signature->type) {    case JAVA_SIGNATURE_BYTE:        CALL_JAVA_METHOD(Byte, b);        break;    case JAVA_SIGNATURE_CHAR:        CALL_JAVA_METHOD(Char, c);        break;        case JAVA_SIGNATURE_FLOAT:        CALL_JAVA_METHOD(Float, f);        break;        case JAVA_SIGNATURE_DOUBLE:        CALL_JAVA_METHOD(Double, d);        break;        case JAVA_SIGNATURE_INT:        CALL_JAVA_METHOD(Int, i);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -