/*
 * Copyright 2007 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

#include <jni.h>
#include "JsRootedValue.h"
#include "gwt-jni.h"
#include "ExternalWrapper.h"
#include "Tracer.h"

// include javah-generated header to make sure things match
#include "JsValueMoz.h"

/*
 * Returns the value of a field on a Java object.
 * 
 * context - JavaScript context
 * clazz - class of obj
 * obj - Java object to retreive field from
 * fieldName - name of field on Java object to retrieve
 * 
 * Returns null on failure.  Caller is responsible for deleting
 * returned JsRootedValue when done with it.
 */
static JsRootedValue* GetFieldAsRootedValue(JSContext* cx, jclass clazz,
    jobject obj, jstring fieldName)
{
  Tracer tracer("GetFieldAsRootedValue");
  JsRootedValue::ContextManager context(cx);
  jmethodID getFieldMeth = savedJNIEnv->GetMethodID(clazz, "getField",
      "(Ljava/lang/String;I)V");
  if (!getFieldMeth || savedJNIEnv->ExceptionCheck()) {
    return 0;
  }

  JsRootedValue* jsRootedValue = new JsRootedValue();
  savedJNIEnv->CallVoidMethod(obj, getFieldMeth, fieldName,
  	 reinterpret_cast<jint>(jsRootedValue));
  if (savedJNIEnv->ExceptionCheck()) {
  	 delete jsRootedValue;
    return 0;
  }
  return jsRootedValue;
}
  
/*
 * Sets the value of a field on a Java object.
 * 
 * context - JavaScript context
 * clazz - class of obj
 * obj - Java object to store into field
 * fieldName - name of field on Java object to store into
 * jsRootedValue - the value to store in the field
 * 
 * returns true on success, false on failure
 */
static bool SetFieldFromRootedValue(JSContext* cx, jclass clazz,
    jobject obj, jstring fieldName, JsRootedValue* jsRootedValue)
{
  Tracer tracer("SetFieldAsRootedValue");
  JsRootedValue::ContextManager context(cx);
  jmethodID getFieldMeth = savedJNIEnv->GetMethodID(clazz, "setField",
      "(Ljava/lang/String;I)V");
  if (!getFieldMeth || savedJNIEnv->ExceptionCheck()) {
    return false;
  }

  savedJNIEnv->CallVoidMethod(obj, getFieldMeth, fieldName,
  	 reinterpret_cast<jint>(jsRootedValue));
  if (savedJNIEnv->ExceptionCheck()) {
    return false;
  }

  return true;
}

/*
 * Throws a HostedModeException with the specified message.
 */
static void ThrowHostedModeException(JNIEnv* jniEnv, const char* msg) {
  jclass exceptionClass
      = jniEnv->FindClass("com/google/gwt/dev/shell/HostedModeException");
  jniEnv->ThrowNew(exceptionClass, msg);
}

/*
 * Types of jsvals.
 */
enum JsValueType {
  JSVAL_TYPE_VOID=0,
  JSVAL_TYPE_NULL,
  JSVAL_TYPE_BOOLEAN,
  JSVAL_TYPE_NUMBER,
  JSVAL_TYPE_STRING,
  JSVAL_TYPE_OBJECT,
  JSVAL_TYPE_UNKNOWN,
};

/*
 * Names of jsval types -- must match the order of the enum above.
 */
static const char* JsValueTypeStrings[]={
  "undefined",
  "null",
  "boolean",
  "number",
  "string",
  "object",
  "unknown",
};

/*
 * Return the type of a jsval.
 */
static JsValueType GetValueType(jsval val) {
  if(JSVAL_IS_VOID(val)) {
    return JSVAL_TYPE_VOID;
  } else if(JSVAL_IS_NULL(val)) {
    return JSVAL_TYPE_NULL;
  } else if(JSVAL_IS_BOOLEAN(val)) {
    return JSVAL_TYPE_BOOLEAN;
  } else if(JSVAL_IS_NUMBER(val)) {
    return JSVAL_TYPE_NUMBER;
  } else if(JSVAL_IS_STRING(val)) {
    return JSVAL_TYPE_STRING;
  } else if(JSVAL_IS_OBJECT(val)) {
    return JSVAL_TYPE_OBJECT;
  } else {
    return JSVAL_TYPE_UNKNOWN;
  } 
}

/*
 * Called from JavaScript to call a Java method that has previously been
 * wrapped.  See _setWrappedFunction for use.
 */ 
static JSBool invokeJavaMethod(JSContext *cx, JSObject *obj, uintN argc,
    jsval *argv, jsval *rval)
{
  Tracer tracer("invokeJavaMethod");
  JsRootedValue::ContextManager context(cx);

  // I kid you not; this is how XPConnect gets their function object so they can
  // multiplex dispatch the call from a common site.  See XPCDispObject.cpp(466)
  //
  // I now have a secondary confirmation that this trick is legit.
  // brandon@mozilla.org writes:
  //
  // argv[-2] is part of the JS API, unabstracted.  Just as argv[0] is the
  // first argument (if argc != 0), argv[-1] is the |this| parameter (equal
  // to OBJECT_TO_JSVAL(obj) in a native method with the standard |obj|
  // second formal parameter name), and argv[-2] is the callee object, tagged
  // as a jsval.
  if (JS_TypeOfValue(cx, argv[-2]) != JSTYPE_FUNCTION) {
    tracer.setFail("not a function type");
    return JS_FALSE;
  }
  JSObject* funObj = JSVAL_TO_OBJECT(argv[-2]);

  // Pull the wrapper object out of the funObj's reserved slot
  jsval jsCleanupObj;
  if (!JS_GetReservedSlot(cx, funObj, 0, &jsCleanupObj)) {
    tracer.setFail("JS_GetReservedSlot failed");
    return JS_FALSE;
  }
  JSObject* cleanupObj = JSVAL_TO_OBJECT(jsCleanupObj);
  if (!cleanupObj) {
    tracer.setFail("cleanupObj is null");
    return JS_FALSE;
  }

  // Get DispatchMethod instance out of the wrapper object
  jobject dispMeth =
      NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, cleanupObj));
  if (!dispMeth) {
    tracer.setFail("dispMeth is null");
    return JS_FALSE;
  }
  jclass dispClass = savedJNIEnv->GetObjectClass(dispMeth);
  if (!dispClass || savedJNIEnv->ExceptionCheck()) {
    tracer.setFail("GetObjectClass returns null");
    return JS_FALSE;
  }

  // lookup the invoke method on the dispatch object
  jmethodID invokeID =
      savedJNIEnv->GetMethodID(dispClass, "invoke", "(I[II)V");
  if (!invokeID || savedJNIEnv->ExceptionCheck()) {
    tracer.setFail("GetMethodID failed");
    return JS_FALSE;
  }

  // create an array of integers to hold the JsRootedValue pointers passed
  // to the invoke method
  jintArray args = savedJNIEnv->NewIntArray(argc);
  if (!args || savedJNIEnv->ExceptionCheck()) {
    tracer.setFail("NewIntArray failed");
    return JS_FALSE;
  }

  // these arguments are already rooted by the JS interpreter, but we
  // can't easily take advantage of that without complicating the JsRootedValue
  // interface.
  
  // argv[-1] is OBJECT_TO_JSVAL(this)
  JsRootedValue* jsThis = new JsRootedValue(argv[-1]);
  tracer.log("jsthis=%08x, RV=%08x", unsigned(argv[-1]), unsigned(jsThis));

  // create JsRootedValues for arguments  
  JsRootedValue *jsArgs[argc]; 
  for (uintN i = 0; i < argc; ++i) {
    jsArgs[i] = new JsRootedValue(argv[i]);
  }
  savedJNIEnv->SetIntArrayRegion(args, 0, argc,
      reinterpret_cast<jint*>(jsArgs));
  if (savedJNIEnv->ExceptionCheck()) {
    tracer.setFail("SetIntArrayRegion failed");
    return JS_FALSE;
  }
  
  // slot for return value
  JsRootedValue* jsReturnVal = new JsRootedValue();

  // TODO(jat): small window here where invocation may fail before Java
  // takes ownership of the JsRootedValue objects.  One solution would be
  // to reference-count them between Java and C++ (so the reference count
  // would always be 0, 1, or 2).  Also setField has a similar problem.
  // I plan to fix this when switching away from Java holding pointers to
  // C++ objects as part of the fix for 64-bit support (which we could
  // accomplish inefficiently by changing int to long everywhere, but there
  // are other 64-bit issues to resolve and we need to reduce the number of
  // roots the JS interpreter has to search.
  
  // call Java method
  savedJNIEnv->CallVoidMethod(dispMeth, invokeID, reinterpret_cast<int>(jsThis),
      args, reinterpret_cast<int>(jsReturnVal));
  
  JSBool returnValue = JS_TRUE;
  
  if (savedJNIEnv->ExceptionCheck()) {
    tracer.log("dispMeth=%08x", unsigned(dispMeth));
    tracer.setFail("java exception is active:");
    jobject exception = savedJNIEnv->ExceptionOccurred();
    if (exception) {
      fprintf(stderr, "Exception occurred in MethodDispatch.invoke:\n");
      savedJNIEnv->ExceptionDescribe();
      savedJNIEnv->DeleteLocalRef(exception);
    }
    returnValue = JS_FALSE;
  } else if (JS_IsExceptionPending(cx)) {
    tracer.setFail("js exception is active");
    returnValue = JS_FALSE;
  }

  // extract return value
  *rval = jsReturnVal->getValue();

#if 0
  // NOTE: C++ objects are not cleaned up here because Java now owns them.
  // TODO(jat): if reference-counted, they *do* need to be Released here.
  
  // free JsRootedValues
  for (uintN i = 0; i < argc; ++i) {
    delete jsArgs[i];
  }
  delete jsThis;
  delete jsReturnVal;
#endif

  return returnValue;
}

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _createJsRootedValue()
 * Signature: (I)I
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1createJsRootedValue
  (JNIEnv* jniEnv, jclass, jint jsval)
{
  Tracer tracer("JsValueMoz._createJsRootedValue");
  JsRootedValue* jsRootedValue = new JsRootedValue(jsval);
  return NS_REINTERPRET_CAST(jint, jsRootedValue);
}

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _copyJsRootedValue()
 * Signature: (I)I
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1copyJsRootedValue
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  const JsRootedValue* jsRootedValue = reinterpret_cast<const JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._copyJsRootedValue", jsRootedValue);
  JsRootedValue* newRootedValue = new JsRootedValue(*jsRootedValue);
  return NS_REINTERPRET_CAST(jint, newRootedValue);
}

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _destroyJsRootedValue()
 * Signature: (I)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1destroyJsRootedValue
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._destroyJsRootedValue", jsRootedValue);
  delete jsRootedValue;
}

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _getBoolean()
 * Signature: (I)Z
 * 
 * TODO(jat): unboxing Javascript Boolean type?
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getBoolean
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._getBoolean", jsRootedValue);
  return jsRootedValue->getBoolean();
}

/**
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _getInt()
 * Signature: (I)I
 * 
 * @see com.google.gwt.dev.shell.moz.JsValueMoz#getInt()
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getInt
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._getInt", jsRootedValue);
  int val = jsRootedValue->getInt();
  tracer.log("value=%d", val);
  return val;
}

/**
 * Return a Javascript number as a Java double.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _getNumber()
 * Signature: (I)D
 */
extern "C" JNIEXPORT jdouble JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getNumber
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._getNumber", jsRootedValue);
  return jsRootedValue->getDouble();
}

/**
 * Return a Javascript string as a Java string.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _getString()
 * Signature: (I)Ljava/lang/String;
 * 
 * Note that this relies on jschar being assignment compatible with jchar
 */
extern "C" JNIEXPORT jstring JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getString
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._getString", jsRootedValue);
  const JSString* str = jsRootedValue->getString();
  int len = JS_GetStringLength(const_cast<JSString*>(str));
  jstring javaStr =jniEnv->NewString(reinterpret_cast<const jchar*>(
      JS_GetStringChars(const_cast<JSString*>(str))), len);
  return javaStr;
}

/*
 * Returns a human-readable Java string describing the type of a
 * JavaScript object.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _getTypeString
 * Signature: (I)Ljava/lang/String;
 */
extern "C" JNIEXPORT jstring JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getTypeString
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._getTypeString", jsRootedValue);
  jsval val = jsRootedValue->getValue();
  JSContext* cx = JsRootedValue::currentContext();
  JsValueType valueType = GetValueType(val);
  const char* typeString = 0;
  char buf[256];
  if(valueType == JSVAL_TYPE_OBJECT) {
    JSObject* jsObject = JSVAL_TO_OBJECT(val);
    JSClass* objClass = JS_GET_CLASS(cx, jsObject);
    if (JS_InstanceOf(cx, jsObject,
        &gwt_nativewrapper_class, 0)) {
      typeString = "Java object";
    } else {
      snprintf(buf, sizeof(buf), "class %s", objClass->name);
      typeString = buf;
    }
  } else {
    typeString = JsValueTypeStrings[valueType];
  }
  jstring returnValue = jniEnv->NewStringUTF(typeString);
  return returnValue;
}

/*
 * Unwraps a wrapped Java object from a JS object.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _getWrappedJavaObject
 * Signature: (I)Ljava/lang/Object;
 */
extern "C" JNIEXPORT jobject JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getWrappedJavaObject
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._getWrappedJavaObject", jsRootedValue);
  jsval val = jsRootedValue->getValue();
  if(!JSVAL_IS_OBJECT(val)) {
    tracer.throwHostedModeException(jniEnv, "Javascript value not an object");
    return 0;
  }
  JSObject* jsObject = JSVAL_TO_OBJECT(val);
  JSContext* cx = JsRootedValue::currentContext();
  if(!JS_InstanceOf(cx, jsObject, &gwt_nativewrapper_class, 0)) {
    tracer.throwHostedModeException(jniEnv,
      "Javascript object not a Java object");
    return 0;
  } 
  jobject javaObject
      = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, jsObject));
  return javaObject;
} 

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isBoolean()
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isBoolean
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isBoolean", jsRootedValue);
  return jsRootedValue->isBoolean();
}

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isInt()
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isInt
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isBoolean", jsRootedValue);
  return jsRootedValue->isInt();
}

/*
 * Checks if a JS object is a JavaScript object.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isJavaScriptObject
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isJavaScriptObject
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isJavaScriptObject", jsRootedValue);
  jsval val = jsRootedValue->getValue();
  bool returnValue = false;
  if(JSVAL_IS_OBJECT(val)) {
    JSObject* jsObject = JSVAL_TO_OBJECT(val);
    returnValue = !JS_InstanceOf(JsRootedValue::currentContext(), jsObject,
        &gwt_nativewrapper_class, 0);
    tracer.log("jsobject=%08x, isJSObject=%s", unsigned(jsObject),
        returnValue ? "true" : "false");
  } else {
    tracer.log("not an object");
  }
  return returnValue;
} 

/*
 * Checks if a JS object is a JavaScript String object.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isJavaScriptString
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isJavaScriptString
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isJavaScriptString", jsRootedValue);
  bool returnValue = jsRootedValue->isJavaScriptStringObject();
  tracer.log("value=%s", returnValue ? "true" : "false");
  return returnValue;
} 

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isNull()
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isNull
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isNull", jsRootedValue);
  return jsRootedValue->isNull();
}

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isNumber()
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isNumber
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isNumber", jsRootedValue);
  return jsRootedValue->isNumber();
}

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isString()
 * Signature: (I)Z
 * 
 * Handles the case of JavaScript String objects as well
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isString
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isString", jsRootedValue);
  return jsRootedValue->isString();
}

/*
 * Checks if a JS object is undefined (void)
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isUndefined
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isUndefined
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isUndefined", jsRootedValue);
  return jsRootedValue->isUndefined();
} 

/*
 * Checks if a JS object is a wrapped Java object.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isWrappedJavaObject
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isWrappedJavaObject
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isWrappedJavaObject", jsRootedValue);
  jsval val = jsRootedValue->getValue();
  bool returnValue = false;
  if(JSVAL_IS_OBJECT(val)) {
    JSObject* jsObject = JSVAL_TO_OBJECT(val);
    returnValue = JS_InstanceOf(JsRootedValue::currentContext(), jsObject,
        &gwt_nativewrapper_class, 0);
    tracer.log("jsobject=%08x, wrappedJava=%s", unsigned(jsObject),
        returnValue ? "true" : "false");
  } else {
    tracer.log("not an object");
  }
  return returnValue;
} 

/*
 * Set the JavaScript value to be a boolean of the supplied value.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setBoolean()
 * Signature: (IZ)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setBoolean
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jboolean val)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._setBoolean", jsRootedValue);
  jsRootedValue->setBoolean(val == JNI_TRUE);
  return;
}

/*
 * Set the JavaScript value to be a double of the supplied value.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setDouble()
 * Signature: (ID)V
 */
extern "C" JNIEXPORT void
JNICALL Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setDouble
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jdouble val)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._setDouble", jsRootedValue);
  if(!jsRootedValue->setDouble(val)) {
    tracer.throwHostedModeException(jniEnv, "Unable to allocate JS double");
    return;
  }
}

/*
 * Set the Javascript value to be an integer.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setInt()
 * Signature: (II)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setInt
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jint val)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._setInt", jsRootedValue);
  tracer.log("val=%d", val);
  jsRootedValue->setInt(val);
}

/*
 * Set the Javascript value to be another JsRootedValue's value.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setJsRootedValue()
 * Signature: (II)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setJsRootedValue
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jint jsOtherRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  JsRootedValue* jsOtherRootedValue = reinterpret_cast<JsRootedValue*>
      (jsOtherRootedValueInt);
  Tracer tracer("JsValueMoz._setJsRootedValue", jsRootedValue);
  jsRootedValue->setValue(jsOtherRootedValue->getValue());
}

/*
 * Set the JavaScript value to be null.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setNull()
 * Signature: (I)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setNull
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._setNull", jsRootedValue);
  jsRootedValue->setNull();
}

/*
 * Set the JavaScript value to be a string of the supplied value.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setString()
 * Signature: (ILjava/lang/String;)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setString
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jstring val)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._setString", jsRootedValue);
  JStringWrap strVal(jniEnv, val);
  const jchar* stringUTF16 = strVal.jstr();
  if(!stringUTF16) {
    tracer.throwHostedModeException(jniEnv, "Unable to retrieve Java string");
    return;
  }
  tracer.log("string=%s", strVal.str());
  if(!jsRootedValue->setString(reinterpret_cast<const wchar_t*>(stringUTF16),
      strVal.length())) {
    tracer.throwHostedModeException(jniEnv, "Unable to allocate JS string");
    return;
  }
}

/*
 * Set the JavaScript value to be undefined (void).
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setUndefined()
 * Signature: (I)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setUndefined
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._setUndefined", jsRootedValue);
  jsRootedValue->setUndefined();
}

/*
 * Wraps a Java object in a JS object.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setWrappedJavaObject
 * Signature: (ILjava/lang/Object)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setWrappedJavaObject
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jobject obj)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._setWrappedJavaObject", jsRootedValue);
  JSContext* cx = JsRootedValue::currentContext();
  JSObject* scriptWindow = JS_GetGlobalObject(cx);
  JSObject* newObj = JS_NewObject(cx, &gwt_nativewrapper_class, 0,
      scriptWindow);
  if (!newObj) {
    tracer.throwHostedModeException(jniEnv,
        "Unable to allocate JS object to wrap Java object");
    return;
  }
  // Save in output value so it won't get GCed.
  jsRootedValue->setObject(newObj); 
  tracer.log("jsobject=%08x", unsigned(newObj));
  
  // TODO(jat): how does this globalref get freed?
  jobject dispObjRef = jniEnv->NewGlobalRef(obj);
  if (!dispObjRef || jniEnv->ExceptionCheck()) {
    tracer.throwHostedModeException(jniEnv,
        "Unable to allocate global reference for JS wrapper");
    return;
  } 
  if (!JS_SetPrivate(cx, newObj, dispObjRef)) {
    jniEnv->DeleteGlobalRef(dispObjRef);
    tracer.throwHostedModeException(jniEnv,
        "Unable to allocate global reference for JS wrapper");
    return;
  } 
  // forcibly setup a "toString" method to override the default
  jclass dispClass = jniEnv->GetObjectClass(obj);
  if (jniEnv->ExceptionCheck()) {
    tracer.throwHostedModeException(jniEnv, "Can't get object class");
    return;
  } 
  jmethodID getFieldMeth = jniEnv->GetMethodID(dispClass, "getField",
      "(Ljava/lang/String;I)V");
  if (!getFieldMeth || jniEnv->ExceptionCheck()) {
    tracer.throwHostedModeException(jniEnv, "Can't get getField method");
    return;
  } 
  jstring ident = jniEnv->NewStringUTF("@java.lang.Object::toString()");
  if (!ident || jniEnv->ExceptionCheck()) {
    tracer.throwHostedModeException(jniEnv,
        "Can't create Java string for toString method name");
    return;
  }
  // allocate a new root to hold the result of the getField call
  JsRootedValue* toStringFunc = new JsRootedValue(); 
  jniEnv->CallVoidMethod(obj, getFieldMeth, ident,
      NS_REINTERPRET_CAST(jint, toStringFunc));
  if (toStringFunc->isUndefined() || jniEnv->ExceptionCheck()) {
    tracer.throwHostedModeException(jniEnv, "getField(toString) failed");
    return;
  } 
  if (!JS_DefineProperty(cx, newObj, "toString", toStringFunc->getValue(),
      JS_PropertyStub, JS_PropertyStub, JSPROP_READONLY | JSPROP_PERMANENT)) {
    tracer.throwHostedModeException(jniEnv, "Can't define JS toString method");
    return;
  }
} 

/*
 * Wraps a Java function in a JS object.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setWrappedFunction
 * Signature: (ILjava/lang/String;Lcom/google/gwt/dev/shell/moz/DispatchMethod;)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setWrappedFunction
    (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jstring methodName,
     jobject dispatchMethod)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._setWrappedFunction", jsRootedValue);
  JSContext* cx = JsRootedValue::currentContext();
  JSObject* scriptWindow = JS_GetGlobalObject(cx);
  JStringWrap nameStr(jniEnv, methodName);
  if (!nameStr.str()) {
    tracer.throwHostedModeException(jniEnv,
       "null method name passed to setWrappedFunction");
    return;
  }
  tracer.log("JsRootedValue=%08x, method=%s, obj=%08x", jsRootedValueInt,
      nameStr.str(), unsigned(dispatchMethod));
  JSFunction* function = JS_NewFunction(cx, invokeJavaMethod, 0,
      JSFUN_LAMBDA, 0, nameStr.str());
  if (!function) {
    tracer.throwHostedModeException(jniEnv, "JS_NewFunction failed");
    return;
  }
  JSObject* funObj = JS_GetFunctionObject(function);
  if (!funObj) {
    tracer.throwHostedModeException(jniEnv, "JS_GetFunctionObject failed");
    return;
  }
  // Save in output value so it won't get GCed.
  jsRootedValue->setObject(funObj); 

  // Create a cleanup object to hold and clean up dispMeth
  JSObject* cleanupObj = JS_NewObject(cx, &gwt_functionwrapper_class, 0,
      scriptWindow);
  if (!cleanupObj) {
    tracer.throwHostedModeException(jniEnv, "JS_NewObject failed");
    return;
  }
  tracer.log("funObj=%08x, cleanupObj=%08x", unsigned(funObj),
      unsigned(cleanupObj));
  // Store the cleanup object in funObj's reserved slot; now GC protected.
  if(!JS_SetReservedSlot(cx, funObj, 0, OBJECT_TO_JSVAL(cleanupObj))) {
    tracer.throwHostedModeException(jniEnv, "JS_SetReservedSlot failed");
    return;
  }
  jobject dispMethRef = jniEnv->NewGlobalRef(dispatchMethod);
  if (!dispMethRef || jniEnv->ExceptionCheck()) {
    tracer.throwHostedModeException(jniEnv,
        "NewGlobalRef(dispatchMethod) failed");
    return;
  }
  // Store our global ref in the wrapper object
  if (!JS_SetPrivate(cx, cleanupObj, dispMethRef)) {
    jniEnv->DeleteGlobalRef(dispMethRef);
    tracer.throwHostedModeException(jniEnv, "JS_SetPrivate(cleanupObj) failed");
    return;
  }
}      

/*
 * Returns a JavaScript value as a string.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _toString
 * Signature: (I)Ljava/lang/String;
 */
extern "C" JNIEXPORT jstring JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1toString
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._toString", jsRootedValue);
  jsval val = jsRootedValue->getValue();
  JSContext* cx = JsRootedValue::currentContext();

  // if it is a JavaScript object that has a toString member function
  // call that, otherwise call JS_ValueToString
  if(JSVAL_IS_OBJECT(val)) {
    JSObject* jsObject = JSVAL_TO_OBJECT(val);
    jsval fval;
    jsval rval;
    if (!JS_InstanceOf(cx, jsObject, &gwt_nativewrapper_class, 0)
        && JS_GetProperty(cx, jsObject, "toString", &fval)
        && JS_ValueToFunction(cx, fval)
        && JS_CallFunctionValue(cx, jsObject, fval, 0, 0, &rval)) {
      // all the steps succeeded, so use the result of toString() instead
      // of the value for JS_ValueToString below
      val = rval;
    }
  }
  JSString* str = JS_ValueToString(cx, val);
  if (!str) {
    return 0;
  }
  int len = JS_GetStringLength(str);
  jstring javaStr =jniEnv->NewString(reinterpret_cast<const jchar*>(
      JS_GetStringChars(str)), len);
  return javaStr;
} 
