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

📄 jsj_method.c

📁 caffeine-monkey java实现的js模拟引擎
💻 C
📖 第 1 页 / 共 5 页
字号:
error:    if (arg_classes)        (*jEnv)->DeleteLocalRef(jEnv, arg_classes);    jsj_PurgeJavaMethodSignature(cx, jEnv, method_signature);    return NULL;}/* * Compute a JNI-style (string) signature for the given method, e.g. the method * "String MyFunc(int, byte)" is translated to "(IB)Ljava/lang/String;". * * If an error is encountered, NULL is returned and the error reporter is called. */const char *jsj_ConvertJavaMethodSignatureToString(JSContext *cx,                                       JavaMethodSignature *method_signature){    JavaSignature **arg_signatures, *return_val_signature;    const char *arg_sigs_cstr;    const char *return_val_sig_cstr;    const char *sig_cstr;    arg_signatures = method_signature->arg_signatures;    return_val_signature = method_signature->return_val_signature;    /* Convert the method argument signatures to a C-string */    arg_sigs_cstr = NULL;    if (arg_signatures) {        arg_sigs_cstr =            convert_java_method_arg_signatures_to_string(cx, arg_signatures,                                                         method_signature->num_args);        if (!arg_sigs_cstr)            return NULL;    }    /* Convert the method return value signature to a C-string */    return_val_sig_cstr = jsj_ConvertJavaSignatureToString(cx, return_val_signature);    if (!return_val_sig_cstr) {        free((void*)arg_sigs_cstr);        return NULL;    }    /* Compose method arg signatures string and return val signature string */    if (arg_sigs_cstr) {        sig_cstr = JS_smprintf("(%s)%s", arg_sigs_cstr, return_val_sig_cstr);        free((void*)arg_sigs_cstr);    } else {        sig_cstr = JS_smprintf("()%s", return_val_sig_cstr);    }    free((void*)return_val_sig_cstr);    if (!sig_cstr) {        JS_ReportOutOfMemory(cx);        return NULL;    }    return sig_cstr;}static JSBooladd_java_method_to_class_descriptor(JSContext *cx, JNIEnv *jEnv,                                    JavaClassDescriptor *class_descriptor,                                     jstring method_name_jstr,                                    jobject java_method,                                    JSBool is_static_method,                                    JSBool is_constructor){    jmethodID methodID;    JSFunction *fun;    jclass java_class = class_descriptor->java_class;    JavaMemberDescriptor *member_descriptor = NULL;    const char *sig_cstr = NULL;    const char *method_name = NULL;    JavaMethodSignature *signature = NULL;    JavaMethodSpec **specp, *method_spec = NULL;                if (is_constructor) {        member_descriptor = jsj_GetJavaClassConstructors(cx, class_descriptor);    } else {        if (is_static_method) {            member_descriptor = jsj_GetJavaStaticMemberDescriptor(cx, jEnv, class_descriptor, method_name_jstr);        } else {            member_descriptor = jsj_GetJavaMemberDescriptor(cx, jEnv, class_descriptor, method_name_jstr);	}        fun = JS_NewFunction(cx, jsj_JavaInstanceMethodWrapper, 0,	                     JSFUN_BOUND_METHOD, NULL, member_descriptor->name);	member_descriptor->invoke_func_obj = JS_GetFunctionObject(fun);        JS_AddNamedRoot(cx, &member_descriptor->invoke_func_obj,                        "&member_descriptor->invoke_func_obj");    }    if (!member_descriptor)        return JS_FALSE;        method_spec = (JavaMethodSpec*)JS_malloc(cx, sizeof(JavaMethodSpec));    if (!method_spec)        goto error;    memset(method_spec, 0, sizeof(JavaMethodSpec));    signature = jsj_InitJavaMethodSignature(cx, jEnv, java_method, &method_spec->signature);    if (!signature)        goto error;    method_name = JS_strdup(cx, member_descriptor->name);    if (!method_name)        goto error;    method_spec->name = method_name;        sig_cstr = jsj_ConvertJavaMethodSignatureToString(cx, signature);    if (!sig_cstr)        goto error;    if (is_static_method)        methodID = (*jEnv)->GetStaticMethodID(jEnv, java_class, method_name, sig_cstr);    else        methodID = (*jEnv)->GetMethodID(jEnv, java_class, method_name, sig_cstr);    method_spec->methodID = methodID;        if (!methodID) {        jsj_UnexpectedJavaError(cx, jEnv,                                "Can't get Java method ID for %s.%s() (sig=%s)",                                class_descriptor->name, method_name, sig_cstr);        goto error;    }        JS_free(cx, (char*)sig_cstr);    /* Add method to end of list of overloaded methods for this class member */     specp = &member_descriptor->methods;    while (*specp) {        specp = &(*specp)->next;    }    *specp = method_spec;    return JS_TRUE;error:    if (method_spec)        JS_FREE_IF(cx, (char*)method_spec->name);    JS_FREE_IF(cx, (char*)sig_cstr);    if (signature)        jsj_PurgeJavaMethodSignature(cx, jEnv, signature);    JS_FREE_IF(cx, method_spec);    return JS_FALSE;}JSBool jsj_ReflectJavaMethods(JSContext *cx, JNIEnv *jEnv,                       JavaClassDescriptor *class_descriptor,                       JSBool reflect_only_static_methods){    jarray joMethodArray, joConstructorArray;    jsize num_methods, num_constructors;    int i;    jclass java_class;    JSBool ok, reflect_only_instance_methods;    reflect_only_instance_methods = !reflect_only_static_methods;    /* Get a java array of java.lang.reflect.Method objects, by calling       java.lang.Class.getMethods(). */    java_class = class_descriptor->java_class;    joMethodArray = (*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getMethods);    if (!joMethodArray) {        jsj_UnexpectedJavaError(cx, jEnv,                                "Can't determine Java object's methods "                                "using java.lang.Class.getMethods()");        return JS_FALSE;    }    /* Iterate over the class methods */    num_methods = (*jEnv)->GetArrayLength(jEnv, joMethodArray);    for (i = 0; i < num_methods; i++) {        jstring method_name_jstr;                /* Get the i'th reflected method */        jobject java_method = (*jEnv)->GetObjectArrayElement(jEnv, joMethodArray, i);        /* Get the method modifiers, eg static, public, private, etc. */        jint modifiers = (*jEnv)->CallIntMethod(jEnv, java_method, jlrMethod_getModifiers);        /* Don't allow access to private or protected Java methods. */        if (!(modifiers & ACC_PUBLIC))            goto dont_reflect_method;        /* Abstract methods can't be invoked */        if (modifiers & ACC_ABSTRACT)            goto dont_reflect_method;        /* Reflect all instance methods or all static methods, but not both */        if (reflect_only_static_methods != ((modifiers & ACC_STATIC) != 0))            goto dont_reflect_method;                /* Add a JavaMethodSpec object to the JavaClassDescriptor */        method_name_jstr = (*jEnv)->CallObjectMethod(jEnv, java_method, jlrMethod_getName);        ok = add_java_method_to_class_descriptor(cx, jEnv, class_descriptor, method_name_jstr, java_method,                                                 reflect_only_static_methods, JS_FALSE);        (*jEnv)->DeleteLocalRef(jEnv, method_name_jstr);        if (!ok) {            (*jEnv)->DeleteLocalRef(jEnv, java_method);            (*jEnv)->DeleteLocalRef(jEnv, joMethodArray);            return JS_FALSE;        }dont_reflect_method:        (*jEnv)->DeleteLocalRef(jEnv, java_method);    }    (*jEnv)->DeleteLocalRef(jEnv, joMethodArray);    if (reflect_only_instance_methods)        return JS_TRUE;            joConstructorArray = (*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getConstructors);    if (!joConstructorArray) {        jsj_UnexpectedJavaError(cx, jEnv, "internal error: "                                "Can't determine Java class's constructors "                                "using java.lang.Class.getConstructors()");        return JS_FALSE;    }    /* Iterate over the class constructors */    num_constructors = (*jEnv)->GetArrayLength(jEnv, joConstructorArray);    for (i = 0; i < num_constructors; i++) {        /* Get the i'th reflected constructor */        jobject java_constructor =            (*jEnv)->GetObjectArrayElement(jEnv, joConstructorArray, i);        /* Get the method modifiers, eg public, private, etc. */        jint modifiers = (*jEnv)->CallIntMethod(jEnv, java_constructor,                                                jlrConstructor_getModifiers);        /* Don't allow access to private or protected Java methods. */        if (!(modifiers & ACC_PUBLIC))            goto dont_reflect_constructor;                /* Add a JavaMethodSpec object to the JavaClassDescriptor */        ok = add_java_method_to_class_descriptor(cx, jEnv, class_descriptor, NULL,                                                 java_constructor,                                                 JS_FALSE, JS_TRUE);        if (!ok) {            (*jEnv)->DeleteLocalRef(jEnv, joConstructorArray);            (*jEnv)->DeleteLocalRef(jEnv, java_constructor);            return JS_FALSE;        }dont_reflect_constructor:        (*jEnv)->DeleteLocalRef(jEnv, java_constructor);    }    (*jEnv)->DeleteLocalRef(jEnv, joConstructorArray);    return JS_TRUE;}/* * Free up a JavaMethodSpec and all its resources. */voidjsj_DestroyMethodSpec(JSContext *cx, JNIEnv *jEnv, JavaMethodSpec *method_spec){    if (!method_spec->is_alias) {	JS_FREE_IF(cx, (char*)method_spec->name);	jsj_PurgeJavaMethodSignature(cx, jEnv, &method_spec->signature);    }    JS_free(cx, method_spec);}static JavaMethodSpec *copy_java_method_descriptor(JSContext *cx, JavaMethodSpec *method){    JavaMethodSpec *copy;    copy = (JavaMethodSpec*)JS_malloc(cx, sizeof(JavaMethodSpec));    if (!copy)        return NULL;    memcpy(copy, method, sizeof(JavaMethodSpec));    copy->next = NULL;    copy->is_alias = JS_TRUE;    return copy;}/* * See if a reference to a JavaObject/JavaClass's property looks like the * explicit resolution of an overloaded method, e.g.  * java.lang.String["max(double,double)"].  If so, add a new member * (JavaMemberDescriptor) to the object that is an alias for the resolved * method. */JavaMemberDescriptor *jsj_ResolveExplicitMethod(JSContext *cx, JNIEnv *jEnv,			  JavaClassDescriptor *class_descriptor, 			  jsid method_name_id,			  JSBool is_static){    JavaMethodSpec *method;    JavaMemberDescriptor *member_descriptor;    JavaMethodSignature *ms;    JSString *simple_name_jsstr;    JSFunction *fun;    JSBool is_constructor;    int left_paren;    const char *sig_cstr, *method_name;    char *arg_start;    jsid id;    jsval method_name_jsval;          /*     * Get the simple name of the explicit method, i.e. get "cos" from     * "cos(double)", and use it to create a new JS string.     */    JS_IdToValue(cx, method_name_id, &method_name_jsval);    method_name = JS_GetStringBytes(JSVAL_TO_STRING(method_name_jsval));    arg_start = strchr(method_name, '(');	/* Skip until '(' */    /* If no left-paren, then this is not a case of explicit method resolution */    if (!arg_start)	return NULL;    /* Left-paren must be first character for constructors */    is_constructor = (is_static && (arg_start == method_name));            left_paren = arg_start - method_name;    simple_name_jsstr = JS_NewStringCopyN(cx, method_name, left_paren);    if (!simple_name_jsstr)	return NULL;    /* Find all the methods in the same class with the same simple name */    JS_ValueToId(cx, STRING_TO_JSVAL(simple_name_jsstr), &id);    if (is_constructor)        member_descriptor = jsj_LookupJavaClassConstructors(cx, jEnv, class_descriptor);    else if (is_static)	member_descriptor = jsj_LookupJavaStaticMemberDescriptorById(cx, jEnv, class_descriptor, id);    else	member_descriptor = jsj_LookupJavaMemberDescriptorById(cx, jEnv, class_descriptor, id);    if (!member_descriptor)	/* No member with matching simple name ? */	return NULL;        /*     * Do a UTF8 comparison of method signatures with all methods of the same name,     * so as to discover a method which exactly matches the specified argument types.     */    if (!strlen(arg_start + 1))	return NULL;    arg_start = JS_strdup(cx, arg_start + 1);    if (!arg_start)	return NULL;    arg_start[strlen(arg_start) - 1] = '\0';	/* Get rid of ')' */    sig_cstr = NULL;	/* Quiet gcc warning about uninitialized variable */    for (method = member_descriptor->methods; method; method = method->next) {	ms = &method->signature;	sig_cstr = convert_java_method_arg_signatures_to_hr_string(cx, ms->arg_signatures,								   ms->num_args, JS_FALSE);	if (!sig_cstr)	    return NULL;	if (!strcmp(sig_cstr, arg_start))	    break;	JS_free(cx, (void*)sig_cstr);    }    JS_free(cx, arg_start);    if (!method)	return NULL;    JS_free(cx, (void*)sig_cstr);        /* Don't bother doing anything if the method isn't overloaded */    if (!member_descriptor->methods->next)

⌨️ 快捷键说明

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