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

📄 jsj_class.c

📁 caffeine-monkey java实现的js模拟引擎
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** *//* * This file is part of the Java-vendor-neutral implementation of LiveConnect * * It contains the code that constructs and manipulates JavaClassDescriptor * structs, which are the native wrappers for Java classes. * JavaClassDescriptors are used to describe the signatures of methods and * fields.  There is a JavaClassDescriptor associated with the reflection of * each Java Object. */#include <stdlib.h>#include <string.h>#include "jsj_private.h"        /* LiveConnect internals */#include "jsj_hash.h"           /* Hash tables */#ifdef JSJ_THREADSAFE#   include "prmon.h"#endif/* A one-to-one mapping between all referenced java.lang.Class objects and   their corresponding JavaClassDescriptor objects */static JSJHashTable *java_class_reflections;#ifdef JSJ_THREADSAFEstatic PRMonitor *java_class_reflections_monitor;#endif/* * Given a JVM handle to a java.lang.Class object, malloc a C-string * containing the UTF8 encoding of the fully qualified name of the class. * It's the caller's responsibility to free the returned string. * * If an error occurs, NULL is returned and the error reporter called. */const char *jsj_GetJavaClassName(JSContext *cx, JNIEnv *jEnv, jclass java_class){    jstring java_class_name_jstr;    const char *java_class_name;    /* Get java.lang.String object containing class name */    java_class_name_jstr =        (*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getName);    if (!java_class_name_jstr)        goto error;    /* Fix bugzilla #183092     * It is necessary to check Exception from JPI     * even though java_class_name_jstr != null */#ifdef XP_UNIX    if ((*jEnv)->ExceptionOccurred(jEnv))        goto error;#endif    /* Convert to UTF8 encoding and copy */    java_class_name = jsj_DupJavaStringUTF(cx, jEnv, java_class_name_jstr);    (*jEnv)->DeleteLocalRef(jEnv, java_class_name_jstr);    return java_class_name;error:    jsj_UnexpectedJavaError(cx, jEnv, "Can't get Java class name using"                                      "java.lang.Class.getName()");    return NULL;}/* * Convert in-place a string of the form "java.lang.String" into "java/lang/String". * Though the former style is conventionally used by Java programmers, the latter is * what the JNI functions require. */voidjsj_MakeJNIClassname(char * class_name){    char * c;    for (c = class_name; *c; c++)        if (*c == '.')            *c = '/';}/* * Classify an instance of java.lang.Class as either one of the primitive * types, e.g. int, char, etc., as an array type or as a non-array object type * (subclass of java.lang.Object) by returning the appropriate enum member. * */static JavaSignatureCharget_signature_type(JSContext *cx, JavaClassDescriptor *class_descriptor){    JavaSignatureChar type;    const char *java_class_name;    /* Get UTF8 encoding of class name */    java_class_name = class_descriptor->name;    JS_ASSERT(java_class_name);    if (!java_class_name)        return JAVA_SIGNATURE_UNKNOWN;    if (!strcmp(java_class_name, "byte"))        type = JAVA_SIGNATURE_BYTE;    else if (!strcmp(java_class_name, "char"))        type = JAVA_SIGNATURE_CHAR;    else if (!strcmp(java_class_name, "float"))        type = JAVA_SIGNATURE_FLOAT;    else if (!strcmp(java_class_name, "double"))        type = JAVA_SIGNATURE_DOUBLE;    else if (!strcmp(java_class_name, "int"))        type = JAVA_SIGNATURE_INT;    else if (!strcmp(java_class_name, "long"))        type = JAVA_SIGNATURE_LONG;    else if (!strcmp(java_class_name, "short"))        type = JAVA_SIGNATURE_SHORT;    else if (!strcmp(java_class_name, "boolean"))        type = JAVA_SIGNATURE_BOOLEAN;    else if (!strcmp(java_class_name, "void"))        type = JAVA_SIGNATURE_VOID;    else if (!strcmp(java_class_name, "java.lang.Boolean"))        type = JAVA_SIGNATURE_JAVA_LANG_BOOLEAN;    else if (!strcmp(java_class_name, "java.lang.Double"))        type = JAVA_SIGNATURE_JAVA_LANG_DOUBLE;    else if (!strcmp(java_class_name, "java.lang.String"))        type = JAVA_SIGNATURE_JAVA_LANG_STRING;    else if (!strcmp(java_class_name, "java.lang.Object"))        type = JAVA_SIGNATURE_JAVA_LANG_OBJECT;    else if (!strcmp(java_class_name, "java.lang.Class"))        type = JAVA_SIGNATURE_JAVA_LANG_CLASS;    else if (!strcmp(java_class_name, "netscape.javascript.JSObject"))        type = JAVA_SIGNATURE_NETSCAPE_JAVASCRIPT_JSOBJECT;    else        type = JAVA_SIGNATURE_OBJECT;    return type;}static JSBoolis_java_array_class(JNIEnv *jEnv, jclass java_class){    return (*jEnv)->CallBooleanMethod(jEnv, java_class, jlClass_isArray);}/* * Return the class of a Java array's component type.  This is not the same * as the array's element type.  For example, the component type of an array * of type SomeType[][][] is SomeType[][], but its element type is SomeType. * * If an error occurs, NULL is returned and an error reported. */static jclassget_java_array_component_class(JSContext *cx, JNIEnv *jEnv, jclass java_class){    jclass result;    result = (*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getComponentType);    if (!result) {        jsj_UnexpectedJavaError(cx, jEnv,                                "Can't get Java array component class using "                                "java.lang.Class.getComponentType()");        return NULL;    }    return result;}/* * Given a Java class, fill in the signature structure that describes the class. * If an error occurs, JS_FALSE is returned and the error reporter called. */static JSBoolcompute_java_class_signature(JSContext *cx, JNIEnv *jEnv, JavaSignature *signature){    jclass java_class = signature->java_class;    if (is_java_array_class(jEnv, java_class)) {        jclass component_class;                signature->type = JAVA_SIGNATURE_ARRAY;        component_class = get_java_array_component_class(cx, jEnv, java_class);        if (!component_class)            return JS_FALSE;        signature->array_component_signature =            jsj_GetJavaClassDescriptor(cx, jEnv, component_class);        if (!signature->array_component_signature) {            (*jEnv)->DeleteLocalRef(jEnv, component_class);            return JS_FALSE;        }    } else {        signature->type = get_signature_type(cx, signature);    }    return JS_TRUE;}/* * Convert from JavaSignatureChar enumeration to single-character * signature used by the JDK and JNI methods. */static charget_jdk_signature_char(JavaSignatureChar type){    return "XVZCBSIJFD[LLLLLL"[(int)type];}/* * Convert a JavaSignature object into a string format as used by * the JNI functions, e.g. java.lang.Object ==> "Ljava/lang/Object;" * The caller is responsible for freeing the resulting string. * * If an error is encountered, NULL is returned and an error reported. */const char *jsj_ConvertJavaSignatureToString(JSContext *cx, JavaSignature *signature){    char *sig;    if (IS_OBJECT_TYPE(signature->type)) {        /* A non-array object class */        sig = JS_smprintf("L%s;", signature->name);        if (sig)            jsj_MakeJNIClassname(sig);    } else if (signature->type == JAVA_SIGNATURE_ARRAY) {        /* An array class */        const char *component_signature_string;        component_signature_string =            jsj_ConvertJavaSignatureToString(cx, signature->array_component_signature);        if (!component_signature_string)            return NULL;        sig = JS_smprintf("[%s", component_signature_string);        JS_free(cx, (char*)component_signature_string);    } else {        /* A primitive class */        sig = JS_smprintf("%c", get_jdk_signature_char(signature->type));    }    if (!sig) {        JS_ReportOutOfMemory(cx);        return NULL;    }    return sig;}/* * Convert a JavaSignature object into a human-readable string format as seen * in Java source files, e.g. "byte", or "int[][]" or "java.lang.String". * The caller is responsible for freeing the resulting string. * * If an error is encountered, NULL is returned and an error reported. */const char *jsj_ConvertJavaSignatureToHRString(JSContext *cx,                                   JavaSignature *signature){    char *sig;    JavaSignature *acs;    if (signature->type == JAVA_SIGNATURE_ARRAY) {        /* An array class */        const char *component_signature_string;        acs = signature->array_component_signature;        component_signature_string =            jsj_ConvertJavaSignatureToHRString(cx, acs);        if (!component_signature_string)            return NULL;        sig = JS_smprintf("%s[]", component_signature_string);        JS_free(cx, (char*)component_signature_string);    } else {        /* A primitive class or a non-array object class */        sig = JS_strdup(cx, signature->name);    }    if (!sig) {        JS_ReportOutOfMemory(cx);        return NULL;    }    return sig;}static voiddestroy_java_member_descriptor(JSContext *cx, JNIEnv *jEnv, JavaMemberDescriptor *member_descriptor){    JavaMethodSpec *method, *next_method;    if (member_descriptor->field)        jsj_DestroyFieldSpec(cx, jEnv, member_descriptor->field);    method = member_descriptor->methods;    while (method) {        next_method = method->next;        jsj_DestroyMethodSpec(cx, jEnv, method);        method = next_method;    }    if (member_descriptor->invoke_func_obj)        JS_RemoveRoot(cx, &member_descriptor->invoke_func_obj);    JS_FREE_IF(cx, (char *)member_descriptor->name);    JS_free(cx, member_descriptor);}static voiddestroy_class_member_descriptors(JSContext *cx, JNIEnv *jEnv, JavaMemberDescriptor *member_descriptor){    JavaMemberDescriptor *next_member;        while (member_descriptor) {        next_member = member_descriptor->next;        destroy_java_member_descriptor(cx, jEnv, member_descriptor);        member_descriptor = next_member;    }}static voiddestroy_class_descriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor){    JS_FREE_IF(cx, (char *)class_descriptor->name);    if (class_descriptor->java_class)        (*jEnv)->DeleteGlobalRef(jEnv, class_descriptor->java_class);    if (class_descriptor->array_component_signature)        jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor->array_component_signature);    destroy_class_member_descriptors(cx, jEnv, class_descriptor->instance_members);    destroy_class_member_descriptors(cx, jEnv, class_descriptor->static_members);    destroy_class_member_descriptors(cx, jEnv, class_descriptor->constructors);    JS_free(cx, class_descriptor);}static JavaClassDescriptor *new_class_descriptor(JSContext *cx, JNIEnv *jEnv, jclass java_class){    JavaClassDescriptor *class_descriptor;    class_descriptor = (JavaClassDescriptor *)JS_malloc(cx, sizeof(JavaClassDescriptor));    if (!class_descriptor)        return NULL;    memset(class_descriptor, 0, sizeof(JavaClassDescriptor));    class_descriptor->name = jsj_GetJavaClassName(cx, jEnv, java_class);    if (!class_descriptor->name)        goto error;    java_class = (*jEnv)->NewGlobalRef(jEnv, java_class);

⌨️ 快捷键说明

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