Esempio n. 1
0
/*
 * Convert a Java object to a JSObject.
 */
static JSBool
convert_javaobject_to_jsobject(JSContext *cx, JNIEnv *jEnv,
                               JavaClassDescriptor *class_descriptor,
                               jobject java_obj, jsval *vp)
{
    JSObject *js_obj;

    /*
     * If it's an instance of netscape.javascript.JSObject, i.e. a wrapper
     * around a JS object that has been passed into the Java world, unwrap
     * it to obtain the original JS object.
     */
    if (njJSObject && (*jEnv)->IsInstanceOf(jEnv, java_obj, njJSObject)) {
#ifdef PRESERVE_JSOBJECT_IDENTITY
#if JS_BYTES_PER_LONG == 8
        js_obj = (JSObject *)((*jEnv)->GetLongField(jEnv, java_obj, njJSObject_long_internal));
#else
        js_obj = (JSObject *)((*jEnv)->GetIntField(jEnv, java_obj, njJSObject_internal));
#endif
#else
        js_obj = jsj_UnwrapJSObjectWrapper(jEnv, java_obj);
#endif
    } else {
        /* otherwise, wrap it inside a JavaObject */
        js_obj = jsj_WrapJavaObject(cx, jEnv, java_obj, class_descriptor->java_class);
        if (!js_obj)
            return JS_FALSE;
    }

    *vp = OBJECT_TO_JSVAL(js_obj);
    return JS_TRUE;
}
Esempio n. 2
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)
{
    jclass java_class;
    JSObject *js_obj;

    /* 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);

    /*
     * If it's an instance of netscape.javascript.JSObject, i.e. a wrapper
     * around a JS object that has been passed into the Java world, unwrap
     * it to obtain the original JS object.
     */
     if (njJSObject && (*jEnv)->IsInstanceOf(jEnv, java_obj, njJSObject)) {
#ifdef PRESERVE_JSOBJECT_IDENTITY
#if JS_BYTES_PER_LONG == 8
        js_obj = (JSObject *)((*jEnv)->GetLongField(jEnv, java_obj, njJSObject_long_internal));
#else
        js_obj = (JSObject *)((*jEnv)->GetIntField(jEnv, java_obj, njJSObject_internal));
#endif
#else
        js_obj = jsj_UnwrapJSObjectWrapper(jEnv, java_obj);
#endif
		/* NULL is actually a valid value. It means 'null'.

        JS_ASSERT(js_obj);
        if (!js_obj)
            goto error;
		*/

        *vp = OBJECT_TO_JSVAL(js_obj);
        goto done;
     }

    /* otherwise, wrap it inside a JavaObject */
    js_obj = jsj_WrapJavaObject(cx, jEnv, java_obj, java_class);
    if (!js_obj)
        goto error;
    *vp = OBJECT_TO_JSVAL(js_obj);

done:
    (*jEnv)->DeleteLocalRef(jEnv, java_class);
    return JS_TRUE;

error:
    (*jEnv)->DeleteLocalRef(jEnv, java_class);
    return JS_FALSE;
}
Esempio n. 3
0
JNIEXPORT jboolean JNICALL
Java_netscape_javascript_JSObject_equals(JNIEnv *jEnv,
                                         jobject java_wrapper_obj,
                                         jobject comparison_obj)
{
#ifdef PRESERVE_JSOBJECT_IDENTITY
#    error "Missing code should be added here"
#else
    JSObject *js_obj1, *js_obj2;

    /* Check that we're comparing with another netscape.javascript.JSObject */
    if (!comparison_obj)
        return 0;
    if (!(*jEnv)->IsInstanceOf(jEnv, comparison_obj, njJSObject))
        return 0;

    js_obj1 = jsj_UnwrapJSObjectWrapper(jEnv, java_wrapper_obj);
    js_obj2 = jsj_UnwrapJSObjectWrapper(jEnv, comparison_obj);

    return (js_obj1 == js_obj2);
#endif  /* PRESERVE_JSOBJECT_IDENTITY */
}
Esempio n. 4
0
JSJavaThreadState *
jsj_enter_js(JNIEnv *jEnv, void* applet_obj, jobject java_wrapper_obj,
             JSContext **cxp, JSObject **js_objp, JSErrorReporter *old_error_reporterp,
             void **pNSIPrincipaArray, int numPrincipals, void *pNSISecurityContext)
{
    JSContext *cx;
    char *err_msg;
    JSObject *js_obj;
    JSJavaThreadState *jsj_env;

    cx = NULL;
    err_msg = NULL;

    /* Invoke callback, presumably used to implement concurrency constraints */
    if (JSJ_callbacks && JSJ_callbacks->enter_js_from_java) {
#ifdef OJI
        if (!JSJ_callbacks->enter_js_from_java(jEnv, &err_msg, pNSIPrincipaArray, numPrincipals, pNSISecurityContext,applet_obj))
#else
        if (!JSJ_callbacks->enter_js_from_java(jEnv, &err_msg))
#endif
            goto entry_failure;
    }

    /* Check the JSObject pointer in the wrapper object. */
    if (js_objp) {

#ifdef PRESERVE_JSOBJECT_IDENTITY
#if JS_BYTES_PER_LONG == 8
        js_obj = (JSObject *)((*jEnv)->GetLongField(jEnv, java_wrapper_obj, njJSObject_long_internal));
#else
        js_obj = (JSObject *)((*jEnv)->GetIntField(jEnv, java_wrapper_obj, njJSObject_internal));
#endif
#else   /* !PRESERVE_JSOBJECT_IDENTITY */
        js_obj = jsj_UnwrapJSObjectWrapper(jEnv, java_wrapper_obj);
#endif  /* PRESERVE_JSOBJECT_IDENTITY */

        JS_ASSERT(js_obj);
        if (!js_obj)
            goto error;
        *js_objp = js_obj;
    }

    /* Get the per-thread state corresponding to the current Java thread */
    jsj_env = jsj_MapJavaThreadToJSJavaThreadState(jEnv, &err_msg);
    if (!jsj_env)
        goto error;

    /* Get the JSContext that we're supposed to use for this Java thread */
    cx = jsj_env->cx;
    if (!cx) {
        /* We called spontaneously into JS from Java, rather than from JS into
           Java and back into JS.  Invoke a callback to obtain/create a
           JSContext for us to use. */
        if (JSJ_callbacks && JSJ_callbacks->map_jsj_thread_to_js_context) {
#ifdef OJI
            cx = JSJ_callbacks->map_jsj_thread_to_js_context(jsj_env,
                                                             applet_obj,
                                                             jEnv, &err_msg);
#else
            cx = JSJ_callbacks->map_jsj_thread_to_js_context(jsj_env,
                                                             jEnv, &err_msg);
#endif
            if (!cx)
                goto error;
        } else {
            err_msg = JS_smprintf("Unable to find/create JavaScript execution "
                                  "context for JNI thread 0x%08x", jEnv);
            goto error;
        }
    }
    *cxp = cx;

    /*
     * Capture all JS error reports so that they can be thrown into the Java
     * caller as an instance of netscape.javascript.JSException.
     */
    *old_error_reporterp =
        JS_SetErrorReporter(cx, capture_js_error_reports_for_java);

#ifdef JSJ_THREADSAFE
    JS_BeginRequest(cx);
#endif

    return jsj_env;

error:
    /* Invoke callback, presumably used to implement concurrency constraints */
    if (JSJ_callbacks && JSJ_callbacks->exit_js)
        JSJ_callbacks->exit_js(jEnv, cx);

entry_failure:
    if (err_msg) {
        if (cx)
            JS_ReportError(cx, err_msg);
        else
            jsj_LogError(err_msg);
        free(err_msg);
    }

    return NULL;
}
Esempio n. 5
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);
}