jsj.c

来自「一个基于alice开发的机器人」· C语言 代码 · 共 872 行 · 第 1/3 页

C
872
字号
/* -*- 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 top-level initialization code and the implementation of the
 * public API.
 *
 */

#include <stdlib.h>
#include <string.h>

#include "jsj_private.h"        /* LiveConnect internals */
#include "jsjava.h"             /* LiveConnect external API */

#ifdef JSJ_THREADSAFE
#    include "prmon.h"
#endif

/*
 * At certain times during initialization, there may be no JavaScript context
 * available to direct error reports to, in which case the error messages
 * are sent to this function.  The caller is responsible for free'ing
 * the js_error_msg argument.
 */
static void
report_java_initialization_error(JNIEnv *jEnv, const char *js_error_msg)
{
    const char *error_msg, *java_error_msg;

    java_error_msg = NULL;

    if (jEnv) {
        java_error_msg = jsj_GetJavaErrorMessage(jEnv);
        (*jEnv)->ExceptionClear(jEnv);
    }

    if (java_error_msg) { 
        error_msg = JS_smprintf("initialization error: %s (%s)\n",
                                js_error_msg, java_error_msg);
        free((void*)java_error_msg);
    } else {
        error_msg = JS_smprintf("initialization error: %s\n",
                                js_error_msg);
    }

    jsj_LogError(error_msg);
    free((void*)error_msg);
}

/*
 * Opaque JVM handles to Java classes and methods required for Java reflection.
 * These are computed and cached during initialization.
 */

jclass jlObject;                        /* java.lang.Object */
jclass jlrMethod;                       /* java.lang.reflect.Method */
jclass jlrField;                        /* java.lang.reflect.Field */
jclass jlrArray;                        /* java.lang.reflect.Array */
jclass jlVoid;                          /* java.lang.Void */
jclass jlrConstructor;                  /* java.lang.reflect.Constructor */
jclass jlThrowable;                     /* java.lang.Throwable */
jclass jlSystem;                        /* java.lang.System */
jclass jlClass;                         /* java.lang.Class */
jclass jlBoolean;                       /* java.lang.Boolean */
jclass jlDouble;                        /* java.lang.Double */
jclass jlString;                        /* java.lang.String */
jclass njJSObject;                      /* netscape.javascript.JSObject */
jclass njJSException;                   /* netscape.javascript.JSException */
jclass njJSUtil;                        /* netscape.javascript.JSUtil */

jmethodID jlClass_getMethods;           /* java.lang.Class.getMethods() */
jmethodID jlClass_getConstructors;      /* java.lang.Class.getConstructors() */
jmethodID jlClass_getFields;            /* java.lang.Class.getFields() */
jmethodID jlClass_getName;              /* java.lang.Class.getName() */
jmethodID jlClass_getComponentType;     /* java.lang.Class.getComponentType() */
jmethodID jlClass_getModifiers;         /* java.lang.Class.getModifiers() */
jmethodID jlClass_isArray;              /* java.lang.Class.isArray() */

jmethodID jlrMethod_getName;            /* java.lang.reflect.Method.getName() */
jmethodID jlrMethod_getParameterTypes;  /* java.lang.reflect.Method.getParameterTypes() */
jmethodID jlrMethod_getReturnType;      /* java.lang.reflect.Method.getReturnType() */
jmethodID jlrMethod_getModifiers;       /* java.lang.reflect.Method.getModifiers() */

jmethodID jlrConstructor_getParameterTypes; /* java.lang.reflect.Constructor.getParameterTypes() */
jmethodID jlrConstructor_getModifiers;  /* java.lang.reflect.Constructor.getModifiers() */

jmethodID jlrField_getName;             /* java.lang.reflect.Field.getName() */
jmethodID jlrField_getType;             /* java.lang.reflect.Field.getType() */
jmethodID jlrField_getModifiers;        /* java.lang.reflect.Field.getModifiers() */

jmethodID jlrArray_newInstance;         /* java.lang.reflect.Array.newInstance() */

jmethodID jlBoolean_Boolean;            /* java.lang.Boolean constructor */
jmethodID jlBoolean_booleanValue;       /* java.lang.Boolean.booleanValue() */
jmethodID jlDouble_Double;              /* java.lang.Double constructor */
jmethodID jlDouble_doubleValue;         /* java.lang.Double.doubleValue() */

jmethodID jlThrowable_toString;         /* java.lang.Throwable.toString() */
jmethodID jlThrowable_getMessage;       /* java.lang.Throwable.getMessage() */

jmethodID jlSystem_identityHashCode;    /* java.lang.System.identityHashCode() */

jobject jlVoid_TYPE;                    /* java.lang.Void.TYPE value */

jmethodID njJSException_JSException;    /* netscape.javascript.JSException constructor */
jmethodID njJSException_JSException_wrap;/*netscape.javascript.JSException alternate constructor */
jmethodID njJSObject_JSObject;          /* netscape.javascript.JSObject constructor */
jmethodID njJSUtil_getStackTrace;       /* netscape.javascript.JSUtil.getStackTrace() */
jfieldID njJSObject_internal;           /* netscape.javascript.JSObject.internal */
jfieldID njJSObject_long_internal;      /* netscape.javascript.JSObject.long_internal */
jfieldID njJSException_lineno;          /* netscape.javascript.JSException.lineno */
jfieldID njJSException_tokenIndex;      /* netscape.javascript.JSException.tokenIndex */
jfieldID njJSException_source;          /* netscape.javascript.JSException.source */
jfieldID njJSException_filename;        /* netscape.javascript.JSException.filename */
jfieldID njJSException_wrappedExceptionType;        /* netscape.javascript.JSException.wrappedExceptionType */
jfieldID njJSException_wrappedException;        /* netscape.javascript.JSException.wrappedException */

/* Obtain a reference to a Java class */
#define LOAD_CLASS(qualified_name, class)                                    \
    {                                                                        \
        jclass _##class = (*jEnv)->FindClass(jEnv, #qualified_name);         \
        if (_##class == 0) {                                                 \
            (*jEnv)->ExceptionClear(jEnv);                                   \
            report_java_initialization_error(jEnv,                           \
                "Can't load class " #qualified_name);                        \
            return JS_FALSE;                                                 \
        }                                                                    \
        class = (*jEnv)->NewGlobalRef(jEnv, _##class);                       \
        (*jEnv)->DeleteLocalRef(jEnv, _##class);                             \
    }

/* Obtain a methodID reference to a Java method or constructor */
#define _LOAD_METHOD(qualified_class, method, mvar, signature, class, is_static)\
    if (is_static) {                                                         \
        class##_##mvar =                                                     \
            (*jEnv)->GetStaticMethodID(jEnv, class, #method, signature);     \
    } else {                                                                 \
        class##_##mvar =                                                     \
            (*jEnv)->GetMethodID(jEnv, class, #method, signature);           \
    }                                                                        \
    if (class##_##mvar == 0) {                                               \
            (*jEnv)->ExceptionClear(jEnv);                                   \
        report_java_initialization_error(jEnv,                               \
               "Can't get mid for " #qualified_class "." #method "()");      \
        return JS_FALSE;                                                     \
    }

/* Obtain a methodID reference to a Java instance method */
#define LOAD_METHOD(qualified_class, method, signature, class)               \
    _LOAD_METHOD(qualified_class, method, method, signature, class, JS_FALSE)

/* Obtain a methodID reference to a Java static method */
#define LOAD_STATIC_METHOD(qualified_class, method, signature, class)        \
    _LOAD_METHOD(qualified_class, method, method, signature, class, JS_TRUE)

/* Obtain a methodID reference to a Java constructor */
#define LOAD_CONSTRUCTOR(qualified_class, method, signature, class)          \
    _LOAD_METHOD(qualified_class,<init>, method, signature, class, JS_FALSE)

/* Obtain a fieldID reference to a Java instance or static field */
#define _LOAD_FIELDID(qualified_class, field, signature, class, is_static)   \
    if (is_static) {                                                         \
        class##_##field = (*jEnv)->GetStaticFieldID(jEnv, class, #field, signature);\
    } else {                                                                 \
        class##_##field = (*jEnv)->GetFieldID(jEnv, class, #field, signature);\
    }                                                                        \
    if (class##_##field == 0) {                                              \
            (*jEnv)->ExceptionClear(jEnv);                                   \
        report_java_initialization_error(jEnv,                               \
                "Can't get fid for " #qualified_class "." #field);           \
        return JS_FALSE;                                                     \
    }

/* Obtain a fieldID reference to a Java instance field */
#define LOAD_FIELDID(qualified_class, field, signature, class)               \
    _LOAD_FIELDID(qualified_class, field, signature, class, JS_FALSE)

/* Obtain the value of a static field in a Java class */
#define LOAD_FIELD_VAL(qualified_class, field, signature, class, type)       \
    {                                                                        \
        jfieldID field_id;                                                   \
        field_id = (*jEnv)->GetStaticFieldID(jEnv, class, #field, signature);\
        if (field_id == 0) {                                                 \
            report_java_initialization_error(jEnv,                           \
                "Can't get fid for " #qualified_class "." #field);           \
            return JS_FALSE;                                                 \
        }                                                                    \
        class##_##field =                                                    \
            (*jEnv)->GetStatic##type##Field(jEnv, class, field_id);          \
        if (class##_##field == 0) {                                          \
            (*jEnv)->ExceptionClear(jEnv);                                   \
            report_java_initialization_error(jEnv,                           \
                "Can't read static field " #qualified_class "." #field);     \
            return JS_FALSE;                                                 \
        }                                                                    \
    }

/* Obtain the value of a static field in a Java class, which is known to
   contain an object value. */
#define LOAD_FIELD_OBJ(qualified_class, field, signature, class)             \
    LOAD_FIELD_VAL(qualified_class, field, signature, class, Object);        \
    class##_##field = (*jEnv)->NewGlobalRef(jEnv, class##_##field);

/*
 * Load the Java classes, and the method and field descriptors required for Java reflection.
 * Returns JS_TRUE on success, JS_FALSE on failure.
 */
static JSBool
init_java_VM_reflection(JSJavaVM *jsjava_vm, JNIEnv *jEnv)
{
    /* Load Java system classes and method, including java.lang.reflect classes */
    LOAD_CLASS(java/lang/Object,                jlObject);
    LOAD_CLASS(java/lang/Class,                 jlClass);
    LOAD_CLASS(java/lang/reflect/Method,        jlrMethod);
    LOAD_CLASS(java/lang/reflect/Constructor,   jlrConstructor);
    LOAD_CLASS(java/lang/reflect/Field,         jlrField);
    LOAD_CLASS(java/lang/reflect/Array,         jlrArray);
    LOAD_CLASS(java/lang/Throwable,             jlThrowable);
    LOAD_CLASS(java/lang/System,                jlSystem);
    LOAD_CLASS(java/lang/Boolean,               jlBoolean);
    LOAD_CLASS(java/lang/Double,                jlDouble);
    LOAD_CLASS(java/lang/String,                jlString);
    LOAD_CLASS(java/lang/Void,                  jlVoid);

    LOAD_METHOD(java.lang.Class,            getMethods,         "()[Ljava/lang/reflect/Method;",jlClass);
    LOAD_METHOD(java.lang.Class,            getConstructors,    "()[Ljava/lang/reflect/Constructor;",jlClass);
    LOAD_METHOD(java.lang.Class,            getFields,          "()[Ljava/lang/reflect/Field;", jlClass);
    LOAD_METHOD(java.lang.Class,            getName,            "()Ljava/lang/String;",         jlClass);
    LOAD_METHOD(java.lang.Class,            isArray,            "()Z",                          jlClass);
    LOAD_METHOD(java.lang.Class,            getComponentType,   "()Ljava/lang/Class;",          jlClass);
    LOAD_METHOD(java.lang.Class,            getModifiers,       "()I",                          jlClass);

    LOAD_METHOD(java.lang.reflect.Method,   getName,            "()Ljava/lang/String;",         jlrMethod);
    LOAD_METHOD(java.lang.reflect.Method,   getParameterTypes,  "()[Ljava/lang/Class;",         jlrMethod);
    LOAD_METHOD(java.lang.reflect.Method,   getReturnType,      "()Ljava/lang/Class;",          jlrMethod);
    LOAD_METHOD(java.lang.reflect.Method,   getModifiers,       "()I",                          jlrMethod);

    LOAD_METHOD(java.lang.reflect.Constructor,  getParameterTypes,  "()[Ljava/lang/Class;",     jlrConstructor);
    LOAD_METHOD(java.lang.reflect.Constructor,  getModifiers,       "()I",                      jlrConstructor);
    
    LOAD_METHOD(java.lang.reflect.Field,    getName,            "()Ljava/lang/String;",         jlrField);
    LOAD_METHOD(java.lang.reflect.Field,    getType,            "()Ljava/lang/Class;",          jlrField);
    LOAD_METHOD(java.lang.reflect.Field,    getModifiers,       "()I",                          jlrField);

    LOAD_STATIC_METHOD(java.lang.reflect.Array,
                                            newInstance,        "(Ljava/lang/Class;I)Ljava/lang/Object;",jlrArray);

    LOAD_METHOD(java.lang.Throwable,        toString,           "()Ljava/lang/String;",         jlThrowable);
    LOAD_METHOD(java.lang.Throwable,        getMessage,         "()Ljava/lang/String;",         jlThrowable);

    LOAD_METHOD(java.lang.Double,           doubleValue,        "()D",                          jlDouble);

⌨️ 快捷键说明

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