Пример #1
0
/**
 * set member of a Native JSObject for a given index.
 *
 * @param jEnv       - JNIEnv on which the call is being made.
 * @param obj        - A Native JS Object.
 * @param index      - Index of a member.
 * @param jobj       - Value to set. If this is a basic data type, it is converted
 *                     using standard JNI calls but if it is a wrapper to a JSObject
 *                     then a internal mapping is consulted to convert to a NJSObject.
 */
NS_METHOD	
nsCLiveconnect::SetSlot(JNIEnv *jEnv, lcjsobject obj, jint slot, jobject java_obj,  void* principalsArray[], 
                     int numPrincipals, nsISupports *securitySupports)
{
    if(jEnv == NULL || obj == 0)
    {
       return NS_ERROR_FAILURE;
    }

    JSJavaThreadState *jsj_env        = NULL;
    JSObjectHandle    *handle         = (JSObjectHandle*)obj;
    JSObject          *js_obj         = handle->js_obj;
    JSContext         *cx             = NULL;
    jsval              js_val;
    JSErrorReporter    saved_state    = NULL;

    jsj_env = jsj_enter_js(jEnv, mJavaClient, NULL, &cx, NULL, &saved_state, principalsArray, numPrincipals, securitySupports);
    if (!jsj_env)
        return NS_ERROR_FAILURE;

    AutoPushJSContext autopush(securitySupports, cx);
    if (NS_FAILED(autopush.ResultOfPush()))
        goto done;
    
    if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, &js_val))
        goto done;
    JS_SetElement(cx, js_obj, slot, &js_val);

done:
    jsj_exit_js(cx, jsj_env, saved_state);
    return NS_OK;
}
Пример #2
0
/*
 * Convert a Java value (primitive or object) to a JS value.
 *
 * This is usually an infallible operation, but JS_FALSE is returned
 * on an out-of-memory condition and the error reporter is called.
 */
JSBool
jsj_ConvertJavaValueToJSValue(JSContext *cx, JNIEnv *jEnv,
                              JavaSignature *signature,
                              jvalue *java_value,
                              jsval *vp)
{
    int32 ival32;

    switch (signature->type) {
    case JAVA_SIGNATURE_VOID:
        *vp = JSVAL_VOID;
        return JS_TRUE;

    case JAVA_SIGNATURE_BYTE:
        *vp = INT_TO_JSVAL((jsint)java_value->b);
        return JS_TRUE;

    case JAVA_SIGNATURE_CHAR:
        *vp = INT_TO_JSVAL((jsint)java_value->c);
        return JS_TRUE;

    case JAVA_SIGNATURE_SHORT:
        *vp = INT_TO_JSVAL((jsint)java_value->s);
        return JS_TRUE;

    case JAVA_SIGNATURE_INT:
        ival32 = java_value->i;
        if (INT_FITS_IN_JSVAL(ival32)) {
            *vp = INT_TO_JSVAL((jsint) ival32);
            return JS_TRUE;
        } else {
            return JS_NewDoubleValue(cx, ival32, vp);
        }

    case JAVA_SIGNATURE_BOOLEAN:
        *vp = BOOLEAN_TO_JSVAL((JSBool) java_value->z);
        return JS_TRUE;

    case JAVA_SIGNATURE_LONG:
        return JS_NewDoubleValue(cx, jlong_to_jdouble(java_value->j), vp);
  
    case JAVA_SIGNATURE_FLOAT:
        return JS_NewDoubleValue(cx, java_value->f, vp);

    case JAVA_SIGNATURE_DOUBLE:
        return JS_NewDoubleValue(cx, java_value->d, vp);

    case JAVA_SIGNATURE_UNKNOWN:
        JS_ASSERT(0);
        return JS_FALSE;
        
    /* Non-primitive (reference) type */
    default:
        JS_ASSERT(IS_REFERENCE_TYPE(signature->type));
        return jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_value->l, vp);

    }
}
Пример #3
0
/* Utility routine to wrap a Java object inside a JS object, having a 
   a result type of either JavaObject or JavaArray. */
JSBool
JSJ_ConvertJavaObjectToJSValue(JSContext *cx, jobject java_obj, jsval *vp)
{
    JNIEnv *jEnv;
    JSBool result;
    JSJavaThreadState *jsj_env;
            
    /* Get the Java per-thread environment pointer for this JSContext */
    jsj_env = jsj_EnterJava(cx, &jEnv);
    if (!jEnv)
        return JS_FALSE;

    result = jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, vp);
    jsj_ExitJava(jsj_env);
    return result;
}
Пример #4
0
/*
 * Class:     netscape_javascript_JSObject
 * Method:    setMember
 * Signature: (Ljava/lang/String;Ljava/lang/Object;)V
 */
JNIEXPORT void JNICALL
Java_netscape_javascript_JSObject_setMember(JNIEnv *jEnv,
                                            jobject java_wrapper_obj,
                                            jstring property_name_jstr,
                                            jobject java_obj)
{
    JSContext *cx = NULL;
    JSObject *js_obj;
    jsval js_val;
    const jchar *property_name_ucs2;
    jsize property_name_len;
    JSErrorReporter saved_reporter;
    jboolean is_copy;
    JSJavaThreadState *jsj_env;
    
    jsj_env = jsj_enter_js(jEnv, NULL, java_wrapper_obj, &cx, &js_obj, &saved_reporter, NULL, 0, NULL);
    if (!jsj_env)
        return;
    
    property_name_ucs2 = NULL;
    if (!property_name_jstr) {
        JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
                                            JSJMSG_NULL_MEMBER_NAME);
        goto done;
    }

    /* Get the Unicode string for the JS property name */
    property_name_ucs2 = (*jEnv)->GetStringChars(jEnv, property_name_jstr, &is_copy);
    if (!property_name_ucs2) {
        JS_ASSERT(0);
        goto done;
    }
    property_name_len = (*jEnv)->GetStringLength(jEnv, property_name_jstr);
    
    if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, &js_val))
        goto done;

    JS_SetUCProperty(cx, js_obj, property_name_ucs2, property_name_len, &js_val);

done:
    if (property_name_ucs2)
        (*jEnv)->ReleaseStringChars(jEnv, property_name_jstr, property_name_ucs2);
    jsj_exit_js(cx, jsj_env, saved_reporter);
}
Пример #5
0
/**
 * set member of a Native JSObject for a given name.
 *
 * @param jEnv       - JNIEnv on which the call is being made.
 * @param obj        - A Native JS Object.
 * @param name       - Name of a member.
 * @param jobj       - Value to set. If this is a basic data type, it is converted
 *                     using standard JNI calls but if it is a wrapper to a JSObject
 *                     then a internal mapping is consulted to convert to a NJSObject.
 */
NS_METHOD	
nsCLiveconnect::SetMember(JNIEnv *jEnv, lcjsobject obj, const jchar *name, jsize length, jobject java_obj, void* principalsArray[], 
                     int numPrincipals, nsISupports *securitySupports)
{
    if(jEnv == NULL || obj == 0)
    {
       return NS_ERROR_FAILURE;
    }

    JSJavaThreadState *jsj_env        = NULL;
    JSObjectHandle    *handle         = (JSObjectHandle*)obj;
    JSObject          *js_obj         = handle->js_obj;
    JSContext         *cx             = NULL;
    jsval              js_val;
    JSErrorReporter    saved_state    = NULL;

    jsj_env = jsj_enter_js(jEnv, mJavaClient, NULL, &cx, NULL, &saved_state, principalsArray, numPrincipals, securitySupports);
    if (!jsj_env)
        return NS_ERROR_FAILURE;

    AutoPushJSContext autopush(securitySupports, cx);
    if (NS_FAILED(autopush.ResultOfPush()))
        goto done;
    
    if (!name) {
        JS_ReportError(cx, "illegal null member name");
        goto done;
    }

    if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, &js_val))
        goto done;

    JS_SetUCProperty(cx, js_obj, name, length, &js_val);

done:
    jsj_exit_js(cx, jsj_env, saved_state);
   return NS_OK;
}
Пример #6
0
/*
 * Class:     netscape_javascript_JSObject
 * Method:    setSlot
 * Signature: (ILjava/lang/Object;)V
 */
JNIEXPORT void JNICALL
Java_netscape_javascript_JSObject_setSlot(JNIEnv *jEnv,
                                          jobject java_wrapper_obj,
                                          jint slot,
                                          jobject java_obj)
{
    JSContext *cx = NULL;
    JSObject *js_obj;
    jsval js_val;
    JSErrorReporter saved_reporter;
    JSJavaThreadState *jsj_env;
    
    jsj_env = jsj_enter_js(jEnv, NULL, java_wrapper_obj, &cx, &js_obj, &saved_reporter, NULL, 0, NULL);
    if (!jsj_env)
        return;
    
    if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, &js_val))
        goto done;
    JS_SetElement(cx, js_obj, slot, &js_val);

done:
    jsj_exit_js(cx, jsj_env, saved_reporter);
}
Пример #7
0
/*
 * Class:     netscape_javascript_JSObject
 * Method:    call
 * Signature: (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;
 */
JNIEXPORT jobject JNICALL
Java_netscape_javascript_JSObject_call(JNIEnv *jEnv, jobject java_wrapper_obj,
                                       jstring function_name_jstr, jobjectArray java_args)
{
    int i, argc, arg_num;
    jsval *argv;
    JSContext *cx = NULL;
    JSObject *js_obj;
    jsval js_val, function_val;
    int dummy_cost;
    JSBool dummy_bool;
    const jchar *function_name_ucs2;
    jsize function_name_len;
    JSErrorReporter saved_reporter;
    jboolean is_copy;
    jobject result;
    JSJavaThreadState *jsj_env;
    
    jsj_env = jsj_enter_js(jEnv, NULL, java_wrapper_obj, &cx, &js_obj, &saved_reporter, NULL, 0, NULL);
    if (!jsj_env)
        return NULL;
    
    function_name_ucs2 = NULL;
    result = NULL;
    if (!function_name_jstr) {
        JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
                                                    JSJMSG_NULL_FUNCTION_NAME);
        goto done;
    }

    /* Get the function name to eval as raw Unicode characters */
    function_name_ucs2 = (*jEnv)->GetStringChars(jEnv, function_name_jstr, &is_copy);
    if (!function_name_ucs2) {
        JS_ASSERT(0);
        goto done;
    }
    function_name_len = (*jEnv)->GetStringLength(jEnv, function_name_jstr);
    
    /* Allocate space for JS arguments */
    if (java_args) {
        argc = (*jEnv)->GetArrayLength(jEnv, java_args);
        argv = (jsval*)JS_malloc(cx, argc * sizeof(jsval));
    } else {
        argc = 0;
        argv = 0;
    }

    /* Convert arguments from Java to JS values */
    for (arg_num = 0; arg_num < argc; arg_num++) {
        jobject arg = (*jEnv)->GetObjectArrayElement(jEnv, java_args, arg_num);

        if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, arg, &argv[arg_num]))
            goto cleanup_argv;
        JS_AddNamedRoot(cx, &argv[arg_num], "&argv[arg_num]");
    }

    if (!JS_GetUCProperty(cx, js_obj, function_name_ucs2, function_name_len,
                          &function_val))
        goto cleanup_argv;

    if (!JS_CallFunctionValue(cx, js_obj, function_val, argc, argv, &js_val))
        goto cleanup_argv;

    jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
                                   &dummy_cost, &result, &dummy_bool);

cleanup_argv:
    if (argv) {
        for (i = 0; i < arg_num; i++)
            JS_RemoveRoot(cx, &argv[i]);
        JS_free(cx, argv);
    }

done:
    if (function_name_ucs2)
        (*jEnv)->ReleaseStringChars(jEnv, function_name_jstr, function_name_ucs2);
    if (!jsj_exit_js(cx, jsj_env, saved_reporter))
        return NULL;
    
    return result;
}
Пример #8
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);
}
Пример #9
0
/*
 * Read the value of a Java field and return it as a JavaScript value.
 * If the field is static, then java_obj is a Java class, otherwise
 * it's a Java instance object.
 *
 * Returns JS_TRUE on success. Otherwise, returns JS_FALSE and reports an error.
 */
JSBool
jsj_GetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
                      jobject java_obj, jsval *vp)
{
    JSBool is_static_field, success;
    jvalue java_value;
    JavaSignature *signature;
    JavaSignatureChar field_type;
    jfieldID fieldID = field_spec->fieldID;

    is_static_field = field_spec->modifiers & ACC_STATIC;

#define GET_JAVA_FIELD(Type,member)                                          \
    JS_BEGIN_MACRO                                                           \
    if (is_static_field)                                                     \
        java_value.member =                                                  \
            (*jEnv)->GetStatic##Type##Field(jEnv, (*jEnv)->GetObjectClass(jEnv, java_obj), fieldID);        \
    else                                                                     \
        java_value.member =                                                  \
            (*jEnv)->Get##Type##Field(jEnv, java_obj, fieldID);              \
    if ((*jEnv)->ExceptionOccurred(jEnv)) {                                  \
        jsj_UnexpectedJavaError(cx, jEnv, "Error reading Java field");           \
        return JS_FALSE;                                                     \
    }                                                                        \
    JS_END_MACRO

    signature = field_spec->signature;
    field_type = signature->type;
    switch(field_type) {
    case JAVA_SIGNATURE_BYTE:
        GET_JAVA_FIELD(Byte,b);
        break;

    case JAVA_SIGNATURE_CHAR:
        GET_JAVA_FIELD(Char,c);
        break;

    case JAVA_SIGNATURE_SHORT:
        GET_JAVA_FIELD(Short,s);
        break;

    case JAVA_SIGNATURE_INT:
        GET_JAVA_FIELD(Int,i);
        break;

    case JAVA_SIGNATURE_BOOLEAN:
        GET_JAVA_FIELD(Boolean,z);
        break;

    case JAVA_SIGNATURE_LONG:
        GET_JAVA_FIELD(Long,j);
        break;

    case JAVA_SIGNATURE_FLOAT:
        GET_JAVA_FIELD(Float,f);
        break;

    case JAVA_SIGNATURE_DOUBLE:
        GET_JAVA_FIELD(Double,d);
        break;

    case JAVA_SIGNATURE_UNKNOWN:
    case JAVA_SIGNATURE_VOID:
        JS_ASSERT(0);        /* Unknown java type signature */
        return JS_FALSE;

    /* Non-primitive (reference) type */
    default:
        JS_ASSERT(IS_REFERENCE_TYPE(field_type));
        GET_JAVA_FIELD(Object,l);
        success = jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_value.l, vp);
        (*jEnv)->DeleteLocalRef(jEnv, java_value.l);
        return success;
    }

#undef GET_JAVA_FIELD

    return jsj_ConvertJavaValueToJSValue(cx, jEnv, signature, &java_value, vp);
}
Пример #10
0
/**
 * call a method of Native JSObject. 
 *
 * @param jEnv       - JNIEnv on which the call is being made.
 * @param obj        - A Native JS Object.
 * @param name       - Name of a method.
 * @param jobjArr    - Array of jobjects representing parameters of method being caled.
 * @param pjobj      - return value.
 */
NS_METHOD	
nsCLiveconnect::Call(JNIEnv *jEnv, lcjsobject obj, const jchar *name, jsize length, jobjectArray java_args, void* principalsArray[], 
                     int numPrincipals, nsISupports *securitySupports, jobject *pjobj)
{
    if(jEnv == NULL || obj == 0)
    {
       return NS_ERROR_FAILURE;
    }

    int                i              = 0;
    int                argc           = 0;
    int                arg_num        = 0;
    jsval             *argv           = 0;
    JSJavaThreadState *jsj_env        = NULL;
    JSObjectHandle    *handle         = (JSObjectHandle*)obj;
    JSObject          *js_obj         = handle->js_obj;
    JSContext         *cx             = NULL;
    jsval              js_val;
    jsval              function_val   = 0;
    int                dummy_cost     = 0;
    JSBool             dummy_bool     = PR_FALSE;
    JSErrorReporter    saved_state    = NULL;
    jobject            result         = NULL;

    jsj_env = jsj_enter_js(jEnv, mJavaClient, NULL, &cx, NULL, &saved_state, principalsArray, numPrincipals, securitySupports);
    if (!jsj_env)
        return NS_ERROR_FAILURE;

    result = NULL;
    AutoPushJSContext autopush(securitySupports, cx);
    if (NS_FAILED(autopush.ResultOfPush()))
        goto done;
    
    if (!name) {
        JS_ReportError(cx, "illegal null JavaScript function name");
        goto done;
    }

    /* Allocate space for JS arguments */
    argc = java_args ? jEnv->GetArrayLength(java_args) : 0;
    if (argc) {
        argv = (jsval*)JS_malloc(cx, argc * sizeof(jsval));
        if (!argv)
            goto done;
    } else {
        argv = 0;
    }

    /* Convert arguments from Java to JS values */
    for (arg_num = 0; arg_num < argc; arg_num++) {
        jobject arg = jEnv->GetObjectArrayElement(java_args, arg_num);
        JSBool ret = jsj_ConvertJavaObjectToJSValue(cx, jEnv, arg, &argv[arg_num]);
		
        jEnv->DeleteLocalRef(arg);
        if (!ret)
            goto cleanup_argv;
        JS_AddRoot(cx, &argv[arg_num]);
    }

    if (!JS_GetUCProperty(cx, js_obj, name, length, &function_val))
        goto cleanup_argv;

    if (!JS_CallFunctionValue(cx, js_obj, function_val, argc, argv, &js_val))
        goto cleanup_argv;

    jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
                                   &dummy_cost, &result, &dummy_bool);

cleanup_argv:
    if (argv) {
        for (i = 0; i < arg_num; i++)
            JS_RemoveRoot(cx, &argv[i]);
        JS_free(cx, argv);
    }

done:
    if (!jsj_exit_js(cx, jsj_env, saved_state))
        return NS_ERROR_FAILURE;
    
    *pjobj = result;

    return NS_OK;
}