示例#1
0
/*
 * 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 JSBool
compute_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;
}
示例#2
0
/* Get the JavaClassDescriptor that corresponds to java.lang.Object */
JavaClassDescriptor *
jsj_get_jlObject_descriptor(JSContext *cx, JNIEnv *jEnv)
{
    /* The JavaClassDescriptor for java.lang.Object */
    static JavaClassDescriptor *jlObject_descriptor = NULL;

    if (!jlObject_descriptor)
        jlObject_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, jlObject);
    return jlObject_descriptor;
}
示例#3
0
JavaClass_construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
    JSObject *obj_arg, *JavaClass_obj;
    JavaObjectWrapper *java_wrapper;
    JavaClassDescriptor *class_descriptor;
    JNIEnv *jEnv;
    JSJavaThreadState *jsj_env;

    if (argc != 1 ||
	!JSVAL_IS_OBJECT(argv[0]) ||
	!(obj_arg = JSVAL_TO_OBJECT(argv[0])) ||
	!JS_InstanceOf(cx, obj_arg, &JavaObject_class, 0) ||
	((java_wrapper = JS_GetPrivate(cx, obj_arg)) == NULL)) {
        JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, 
                             JSJMSG_NEED_JCLASS_ARG);
        return JS_FALSE;
    }

    jsj_env = jsj_EnterJava(cx, &jEnv);
    if (!jEnv)
        return JS_FALSE;

    class_descriptor = java_wrapper->class_descriptor;
    if (!(*jEnv)->IsSameObject(jEnv, class_descriptor->java_class, jlClass)) {
	JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, 
                             JSJMSG_NEED_JCLASS_ARG);
	jsj_ExitJava(jsj_env);
        return JS_FALSE;
    }

    class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_wrapper->java_obj);
    JavaClass_obj = jsj_new_JavaClass(cx, jEnv, NULL, class_descriptor);
    if (!JavaClass_obj) {
	jsj_ExitJava(jsj_env);
        return JS_FALSE;
    }

    *rval = OBJECT_TO_JSVAL(JavaClass_obj);
    jsj_ExitJava(jsj_env);
    return JS_TRUE;
}
示例#4
0
/*
 * Reflect a Java object into a JS value.  The source object, java_obj, must
 * be of type java.lang.Object or a subclass and may, therefore, be an array.
 */
JSBool
jsj_ConvertJavaObjectToJSValue(JSContext *cx, JNIEnv *jEnv,
                               jobject java_obj, jsval *vp)
{
    JavaClassDescriptor *class_descriptor;
    jclass java_class;
    JSBool ret;

    /* A null in Java-land is also null in JS */
    if (!java_obj) {
        *vp = JSVAL_NULL;
        return JS_TRUE;
    }

    java_class = (*jEnv)->GetObjectClass(jEnv, java_obj);

    class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);
    if (!class_descriptor)
        return JS_FALSE;

    switch (class_descriptor->type) {
    case JAVA_SIGNATURE_JAVA_LANG_BOOLEAN:
        ret = jsj_ConvertJavaObjectToJSBoolean(cx, jEnv, class_descriptor, java_obj, vp);
        break;
    case JAVA_SIGNATURE_JAVA_LANG_DOUBLE:
        ret = jsj_ConvertJavaObjectToJSNumber(cx, jEnv, class_descriptor, java_obj, vp);
        break;
    case JAVA_SIGNATURE_JAVA_LANG_STRING:
        ret = jsj_ConvertJavaObjectToJSString(cx, jEnv, class_descriptor, java_obj, vp);
        break;
    default:
        ret = convert_javaobject_to_jsobject(cx, jEnv, class_descriptor, java_obj, vp);
        break;
    }

    (*jEnv)->DeleteLocalRef(jEnv, java_class);
    jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor);
    return ret;
}
示例#5
0
JSObject *
jsj_define_JavaClass(JSContext *cx, JNIEnv *jEnv, JSObject* parent_obj,
                     const char *simple_class_name,
                     jclass java_class)
{
    JavaClassDescriptor *class_descriptor;
    JSObject *JavaClass_obj;

    class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);
    if (!class_descriptor)
        return NULL;

    JavaClass_obj = jsj_new_JavaClass(cx, jEnv, parent_obj, class_descriptor);
    if (!JavaClass_obj)
        return NULL;

    if (!JS_DefineProperty(cx, parent_obj, simple_class_name,
                           OBJECT_TO_JSVAL(JavaClass_obj), 0, 0,
                           JSPROP_PERMANENT|JSPROP_READONLY|JSPROP_ENUMERATE))
        return NULL;
    return JavaClass_obj;
}
示例#6
0
/*
 * This is a wrapper around JS_ReportError(), useful when an error condition
 * is the result of a JVM failure or exception condition.  It appends the
 * message associated with the pending Java exception to the passed in
 * printf-style format string and arguments.
 */
static void
vreport_java_error(JSContext *cx, JNIEnv *jEnv, const char *format, va_list ap)
{
    jobject java_obj;
    jclass java_class;
    JavaClassDescriptor *class_descriptor;
    jthrowable java_exception;
    JSType wrapped_exception_type;
    jsval js_exception;
       
    java_obj = NULL;
    class_descriptor = NULL;

    /* Get the exception out of the java environment. */
    java_exception = (*jEnv)->ExceptionOccurred(jEnv);
    if (!java_exception) {
        JSString *err_jsstr;
        char *err = JS_vsmprintf(format, ap);
        if (!err)
            return;
        err_jsstr = JS_NewString(cx, err, strlen(err));
        if (!err_jsstr)
            return;
        JS_SetPendingException(cx, STRING_TO_JSVAL(err_jsstr));
        return;
    }

    
    (*jEnv)->ExceptionClear(jEnv);
    
    /* Check for JSException */
    if (njJSException && 
        (*jEnv)->IsInstanceOf(jEnv, java_exception, njJSException)) {
        
        wrapped_exception_type = 
            (*jEnv)->GetIntField(jEnv, java_exception,
            njJSException_wrappedExceptionType);
        
        /* (int) to suppress warning */
        if ((int)wrapped_exception_type != JSTYPE_EMPTY) {
            java_obj = 
                (*jEnv)->GetObjectField(jEnv, java_exception, 
                njJSException_wrappedException);
            
            if ((java_obj == NULL) && 
                (wrapped_exception_type == JSTYPE_OBJECT)) {
                js_exception = JSVAL_NULL;
            } else { 
                java_class = (*jEnv)->GetObjectClass(jEnv, java_obj); 
                class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);
                /* OK to delete ref, since above call adds global ref */
                (*jEnv)->DeleteLocalRef(jEnv, java_class);  
                
                /* Convert native JS values back to native types. */
                switch(wrapped_exception_type) {
                case JSTYPE_NUMBER:
                    if (!jsj_ConvertJavaObjectToJSNumber(cx, jEnv,
                        class_descriptor,
                        java_obj, 
                        &js_exception))
                        goto error;
                    break;
                case JSTYPE_BOOLEAN:
                    if (!jsj_ConvertJavaObjectToJSBoolean(cx, jEnv,
                        class_descriptor,
                        java_obj, 
                        &js_exception))
                        goto error;
                    break;
                case JSTYPE_STRING:
                    if (!jsj_ConvertJavaObjectToJSString(cx, jEnv,
                        class_descriptor,
                        java_obj, 
                        &js_exception))
                        goto error;
                    break;
                case JSTYPE_VOID:
                    js_exception = JSVAL_VOID;
                    break;
                case JSTYPE_OBJECT:
                case JSTYPE_FUNCTION:
                default:
                    if ((*jEnv)->IsInstanceOf(jEnv, java_obj, njJSObject)) {
                        js_exception = OBJECT_TO_JSVAL(jsj_UnwrapJSObjectWrapper(jEnv, java_obj));
                        if (!js_exception)
                            goto error;                        
                    } else {
                        if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, 
                            &js_exception)) 
                            goto error;
                    }
                }
            }
        }
        /* Check for internal exception */
    } else {
        if (!JSJ_ConvertJavaObjectToJSValue(cx, java_exception,
            &js_exception)) {
            goto error;
        }
    }
    
    /* Set pending JS exception and clear the java exception. */
    JS_SetPendingException(cx, js_exception);                        
    goto done;

error:
    
    JS_ASSERT(0);
    jsj_LogError("Out of memory while attempting to throw JSException\n");
    
done:
    if (class_descriptor)
        jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor);
    if (java_obj)
        (*jEnv)->DeleteLocalRef(jEnv, java_obj);
    if (java_exception)
        (*jEnv)->DeleteLocalRef(jEnv, java_exception);
}
示例#7
0
/*
 * Add a single field, described by java_field, to the JavaMemberDescriptor
 * named by field_name within the given JavaClassDescriptor.
 *
 * Returns JS_TRUE on success. Otherwise, returns JS_FALSE and reports an error.
 */
static JSBool
add_java_field_to_class_descriptor(JSContext *cx,
                                   JNIEnv *jEnv,
                                   JavaClassDescriptor *class_descriptor,
                                   jstring field_name_jstr,
                                   jobject java_field,  /* a java.lang.reflect.Field */
                                   jint modifiers)
{
    jclass fieldType;
    jfieldID fieldID;
    jclass java_class;

    JSBool is_static_field;
    JavaMemberDescriptor *member_descriptor = NULL;
    const char *sig_cstr = NULL;
    const char *field_name = NULL;
    JavaSignature *signature = NULL;
    JavaFieldSpec *field_spec = NULL;

    is_static_field = modifiers & ACC_STATIC;
    if (is_static_field) {
        member_descriptor = jsj_GetJavaStaticMemberDescriptor(cx, jEnv, class_descriptor, field_name_jstr);
    } else {
        member_descriptor = jsj_GetJavaMemberDescriptor(cx, jEnv, class_descriptor, field_name_jstr);
    }
    if (!member_descriptor)
        goto error;

    field_spec = (JavaFieldSpec*)JS_malloc(cx, sizeof(JavaFieldSpec));
    if (!field_spec)
        goto error;

    field_spec->modifiers = modifiers;

    /* Get the Java class corresponding to the type of the field */
    fieldType = (*jEnv)->CallObjectMethod(jEnv, java_field, jlrField_getType);
    if (!fieldType) {
        jsj_UnexpectedJavaError(cx, jEnv,
                                "Unable to determine type of field using"
                                " java.lang.reflect.Field.getType()");
        goto error;
    }

    signature = jsj_GetJavaClassDescriptor(cx, jEnv, fieldType);
    (*jEnv)->DeleteLocalRef(jEnv, fieldType);
    if (!signature)
        goto error;
    field_spec->signature = signature;

    field_name = jsj_DupJavaStringUTF(cx, jEnv, field_name_jstr);
    if (!field_name)
        goto error;
    field_spec->name = field_name;

    /* Compute the JNI-style (string-based) signature of the field type */
    sig_cstr = jsj_ConvertJavaSignatureToString(cx, signature);
    if (!sig_cstr)
        goto error;

    /* Compute the JNI fieldID and cache it for quick field access */
    java_class = class_descriptor->java_class;
    if (is_static_field)
        fieldID = (*jEnv)->GetStaticFieldID(jEnv, java_class, field_name, sig_cstr);
    else
        fieldID = (*jEnv)->GetFieldID(jEnv, java_class, field_name, sig_cstr);
    if (!fieldID) {
        jsj_UnexpectedJavaError(cx, jEnv,
                                "Can't get Java field ID for class %s, field %s (sig=%s)",
                                class_descriptor->name, field_name, sig_cstr);
        goto error;
    }
    field_spec->fieldID = fieldID;

    JS_free(cx, (char*)sig_cstr);

    member_descriptor->field = field_spec;

    /* Success */
    return JS_TRUE;

error:
    if (field_spec) {
        JS_FREE_IF(cx, (char*)field_spec->name);
        JS_free(cx, field_spec);
    }
    JS_FREE_IF(cx, (char*)sig_cstr);
    if (signature)
        jsj_ReleaseJavaClassDescriptor(cx, jEnv, signature);
    return JS_FALSE;
}