/* 
 * Copyright 2006 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 "gwt-ll.h"
#include "DispWrapper.h"
#include "FuncWrapper.h"

JNIEnv* gEnv;
jclass gClass;
jclass gDispObjCls;
jclass gDispMethCls;
jmethodID gGetFieldMeth;
jmethodID gSetFieldMeth;
jmethodID gInvokeMeth;
jmethodID gToStringMeth;

using namespace KJS;

static void PrintJSValue(JSValue* val, char* prefix="") {
  static const char* typeStrings[]={
    "unspecified",
    "number",
    "boolean",
    "undefined",
    "null",
    "string",
    "object",
    "getter/setter",
  };
  JSType type = val->type();
  const char* typeString=typeStrings[type];
  char buf[256];
	char* p = buf;
	p += snprintf(p, sizeof(buf)-(p-buf), "%s%s: ", prefix, typeString);
	if (val->isNumber()) {
		p += snprintf(p, sizeof(buf)-(p-buf), "%lf", val->getNumber());
	} else if(val->isString()) {
		CString str(val->getString().UTF8String());
		p += snprintf(p, sizeof(buf)-(p-buf), "%.*s", str.size(), str.c_str());
	} else if(val->isObject()) {
		const JSObject* obj = val->getObject();
		const ClassInfo* cinfo = obj->classInfo();
		const char* cname = cinfo ? cinfo->className : "js object";
		p += snprintf(p, sizeof(buf)-(p-buf), "%s @ %08x", cname, unsigned(obj));
	} else if(val->isBoolean()) {
		p += snprintf(p, sizeof(buf)-(p-buf), "%s", val->getBoolean() ? "true" : "false");
	}
	TRACE(buf);
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    isNull
 * Signature: (I)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isNull
  (JNIEnv *env, jclass, jint jsval) {
    TRACE("ENTER LowLevelSaf__isNull");

  JSValue* val = (JSValue*)jsval;
  if (!val)
    return JNI_FALSE;

    TRACE("SUCCESS LowLevelSaf__isNull");
  return val->isNull();
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    isUndefined
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isUndefined
  (JNIEnv *env, jclass, jint jsval) {
    TRACE("ENTER LowLevelSaf__isUndefined");
  JSValue* val = (JSValue*)jsval;
  if (!val)
    return JNI_FALSE;

    TRACE("SUCCESS LowLevelSaf__isUndefined");
  return val->isUndefined();
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    jsNull
 * Signature: ()I
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_gwt_dev_shell_mac_LowLevelSaf_jsNull
  (JNIEnv *, jclass) {
  return (jint)jsNull();
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    getTypeString
 * Signature: (I)Ljava/lang/String;
 */
extern "C" JNIEXPORT jstring JNICALL
Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getTypeString
   (JNIEnv *env, jclass, jint jsval) {
  static const char* typeStrings[]={
    "unspecified",
    "number",
    "boolean",
    "undefined",
    "null",
    "string",
    "object",
    "getter/setter",
  };
  JSValue* val = (JSValue*)jsval;
  if (!val)
    return 0;
  JSType type = val->type();
  const char* typeString=typeStrings[type];
  if (type == ObjectType) {
	  if (val->isObject(&DispWrapper::info)) {
 	  	typeString = "Java object";
 	  } else {
 	  	typeString = "JS object";
	  }
  }
  return env->NewStringUTF(typeString);
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    jsUndefined
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_jsUndefined
  (JNIEnv *env, jclass) {
    return (jint)jsUndefined();
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _coerceToBoolean
 * Signature: (II[Z)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1coerceToBoolean
  (JNIEnv * env, jclass, jint execState, jint jsval, jbooleanArray rval) {
    TRACE("ENTER LowLevelSaf__1coerceToBoolean");

  if (!execState || !jsval)
    return JNI_FALSE;

  jboolean result = ((JSValue*)jsval)->toBoolean((ExecState*)execState);
  env->SetBooleanArrayRegion(rval, 0, 1, &result);
  if (env->ExceptionCheck())
      return JNI_FALSE;

    TRACE("SUCCESS LowLevelSaf__1coerceToBoolean");
  return JNI_TRUE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _coerceToDouble
 * Signature: (II[D)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1coerceToDouble
  (JNIEnv *env, jclass, jint execState, jint jsval, jdoubleArray rval) {
    TRACE("ENTER LowLevelSaf__1coerceToDouble");

  if (!execState || !jsval)
    return JNI_FALSE;

  jdouble result = ((JSValue*)jsval)->toNumber((ExecState*)execState);
  env->SetDoubleArrayRegion(rval, 0, 1, &result);
  if (env->ExceptionCheck())
      return JNI_FALSE;

    TRACE("SUCCESS LowLevelSaf__1coerceToDouble");
  return JNI_TRUE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _coerceToString
 * Signature: (II[Ljava/lang/String;)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1coerceToString
  (JNIEnv *env, jclass, jint execState, jint jsval, jobjectArray rval) {
    TRACE("ENTER LowLevelSaf__1coerceToString");

  JSValue *val = (JSValue*)jsval;
  if (!execState || !val)
    return JNI_FALSE;

  /* 
   * Convert all objects to their string representation, EXCEPT
   * null and undefined which will be returned as a true NULL.
   */
  jstring result = NULL;
  if (!val->isNull() && !val->isUndefined()) {
    UString str = val->toString((ExecState*)execState);
    result = env->NewString((const jchar*)str.data(), str.size());
    if (env->ExceptionCheck())
      return JNI_FALSE;
  }

  env->SetObjectArrayElement(rval,0,result);
  if (env->ExceptionCheck())
    return JNI_FALSE;

  TRACE("SUCCESS LowLevelSaf__1coerceToString");
  return JNI_TRUE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _convertBoolean
 * Signature: (IZ[I)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1convertBoolean
  (JNIEnv *env, jclass, jboolean jval, jintArray rval) {
    TRACE("ENTER LowLevelSaf__1convertBoolean");
  char buf[256];
  snprintf(buf, sizeof(buf), " val=%s", jval ? "true" : "false");
  TRACE(buf);

  JSValue *jsval = (jval == JNI_FALSE) ? jsBoolean(false) : jsBoolean(true);
  if (!jsval)
    return JNI_FALSE;

  env->SetIntArrayRegion(rval,0,1,(const jint*)&jsval);
  if (env->ExceptionCheck())
    return JNI_FALSE;
  
    TRACE("SUCCESS LowLevelSaf__1convertBoolean");
  return JNI_TRUE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _convertDouble
 * Signature: (ID[I)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1convertDouble
  (JNIEnv *env, jclass, jdouble jval, jintArray rval) {
    TRACE("ENTER LowLevelSaf__1convertDouble");
#ifdef ENABLE_TRACING
  char buf[256];
  snprintf(buf, sizeof(buf), " val=%lf", jval);
  TRACE(buf);
#endif

  JSValue *jsval = jsNumber(jval);
  if (!jsval)
    return JNI_FALSE;

  env->SetIntArrayRegion(rval,0,1,(const jint*)&jsval);
  if (env->ExceptionCheck())
    return JNI_FALSE;

    TRACE("SUCCESS LowLevelSaf__1convertDouble");
  return JNI_TRUE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _convertString
 * Signature: (ILjava/lang/String;[I)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1convertString
  (JNIEnv *env, jclass, jstring jval, jintArray rval) {
    TRACE("ENTER LowLevelSaf__1convertString");

  JStringWrap jstr(env, jval);
  if (!jstr.jstr())
    return JNI_FALSE;
#ifdef ENABLE_TRACING
  char buf[256];
  snprintf(buf, sizeof(buf), " val=%s", jstr.str());
  TRACE(buf);
#endif
  
  JSValue *jsval = jsString(UString((const UChar*)jstr.jstr(), jstr.length()));
  /*
   * TODO / LEAK / HACK: We will be persisting these objects on the java side,
   * so in order to keep the JS GC from collecting our objects when they are
   * away, we need to add them to the protect list. This should be refactored
   * out in favor of better memory mgmt scheme.
   */
  gcProtectNullTolerant(jsval);
  if (!jsval)
    return JNI_FALSE;

#ifdef ENABLE_TRACING
  snprintf(buf, sizeof(buf), " return={%08x} ", unsigned(jsval));
  PrintJSValue(jsval, buf);
#endif
  
  env->SetIntArrayRegion(rval,0,1,(const jint*)&jsval);
  if (env->ExceptionCheck())
    return JNI_FALSE;

  TRACE("SUCCESS LowLevelSaf__1convertString");
  return JNI_TRUE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _executeScript
 * Signature: (ILjava/lang/String;)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1executeScript
  (JNIEnv* env, jclass, jint execState, jstring code) {
    TRACE("ENTER LowLevelSaf__1executeScript"); 
  if (!execState || !code)
    return JNI_FALSE;

  JStringWrap jcode(env, code);
  if (!jcode.jstr())
    return JNI_FALSE;
#ifdef ENABLE_TRACING
  char buf[1024];
  snprintf(buf, sizeof(buf), " code=%s", jcode.str());
  TRACE(buf);
#endif
    
  Interpreter* interp = ((ExecState*)execState)->dynamicInterpreter();
  if (!interp)
    return JNI_FALSE;

  interp->evaluate(UString(), 0, (const UChar*)jcode.jstr(), jcode.length());
    TRACE("SUCCESS LowLevelSaf__1executeScript");
  return JNI_TRUE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _executeScriptWithInfo
 * Signature: (ILjava/lang/String;Ljava/lang/String;I)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1executeScriptWithInfo
  (JNIEnv* env, jclass, jint execState, jstring code, jstring file, jint line) {
    TRACE("ENTER LowLevelSaf__1executeScriptWithInfo");
  if (!execState || !code || !file)
    return JNI_FALSE;

  JStringWrap jcode(env, code);
  if (!jcode.jstr())
    return JNI_FALSE;

  JStringWrap jfile(env, file);
  if (!jcode.jstr())
    return JNI_FALSE;

#ifdef ENABLE_TRACING
  char buf[1024];
  snprintf(buf, sizeof(buf), " code=%s, file=%s, line=%d", jcode.str(), jfile.str(), line);
  TRACE(buf);
#endif
  
  Interpreter* interp = ((ExecState*)execState)->dynamicInterpreter();
  if (!interp)
    return JNI_FALSE;

  interp->evaluate(UString((const UChar*)jfile.jstr(), jfile.length()), line, (const UChar*)jcode.jstr(), jcode.length());
    TRACE("SUCCESS LowLevelSaf__1executeScriptWithInfo");
  return JNI_TRUE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _gcLock
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1gcLock
  (JNIEnv *, jclass, jint jsval) {
  gcProtectNullTolerant((JSValue*)jsval);
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _gcUnlock
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1gcUnlock
  (JNIEnv *, jclass, jint jsval) {
  gcUnprotectNullTolerant((JSValue*)jsval);
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _getGlobalExecState
 * Signature: (I[I)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1getGlobalExecState
  (JNIEnv *env, jclass, jint scriptObject, jintArray rval) {
    TRACE("ENTER LowLevelSaf__1getGlobalExecState");

  if (!scriptObject || !((JSValue*)scriptObject)->isObject())
    return JNI_FALSE;

  Interpreter* interp = Interpreter::interpreterWithGlobalObject((JSObject*)scriptObject);
  if (!interp)
    return JNI_FALSE;

  ExecState* execState = interp->globalExec();
    env->SetIntArrayRegion(rval, 0, 1, (jint*)&execState);
    if (env->ExceptionCheck())
        return JNI_FALSE;
    TRACE("SUCCESS LowLevelSaf__1getGlobalExecState");
  return JNI_TRUE;

}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _initNative
 * Signature: (Ljava/lang/Class;Ljava/lang/Class;)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1initNative
  (JNIEnv* env, jclass llClass, jclass dispObjCls, jclass dispMethCls) {
  Interpreter::setShouldPrintExceptions(true);
  gEnv = env;
  gClass =  static_cast<jclass>(env->NewGlobalRef(llClass));
  gDispObjCls = static_cast<jclass>(env->NewGlobalRef(dispObjCls));
  gDispMethCls = static_cast<jclass>(env->NewGlobalRef(dispMethCls));
  if (!gClass || !gDispObjCls || !gDispMethCls || env->ExceptionCheck()) {
    return false;
  }

  gGetFieldMeth = env->GetMethodID(gDispObjCls, "getField", "(Ljava/lang/String;)I");
  gSetFieldMeth = env->GetMethodID(gDispObjCls, "setField", "(Ljava/lang/String;I)V");
  gInvokeMeth = env->GetMethodID(gDispMethCls, "invoke", "(II[I)I");
  gToStringMeth = env->GetMethodID(gDispObjCls, "toString", "()Ljava/lang/String;");
  if (!gGetFieldMeth || !gSetFieldMeth || !gInvokeMeth || !gToStringMeth || env->ExceptionCheck()) {
    return false;
  }

#ifdef FILETRACE
    gout = fopen("/tmp/gwt-ll.log", "w");
    filetrace("LOG STARTED");
#endif // FILETRACE

#ifdef JAVATRACE
    gTraceMethod = env->GetStaticMethodID(gClass, "trace", "(Ljava/lang/String;)V");
    if (!gTraceMethod || env->ExceptionCheck())
        return false;
#endif // JAVATRACE

  return true;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _invoke
 * Signature: (IILjava/lang/String;II[I[I)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1invoke
  (JNIEnv* env, jclass, jint jsexecState, jint jsScriptObject, jstring method, jint jsthis, jint argc, jintArray argv, jintArray rval) {
    TRACE("ENTER LowLevelSaf__1invoke");

  if (!jsexecState || !jsScriptObject || !method || !rval)
    return JNI_FALSE;
  JStringWrap jmethod(env, method);
#ifdef ENABLE_TRACING
  char buf[256];
  snprintf(buf, sizeof(buf), "sciptObject=%08x, method=%s, argc=%d",
      jsScriptObject, jmethod.str(), argc);
  TRACE(buf);
  PrintJSValue((JSValue*)jsthis, " jsthis=");
#endif
  ExecState* execState = (ExecState*)jsexecState;

  JSObject* scriptObj = (JSObject*)jsScriptObject;
  if (!scriptObj->isObject())
    return JNI_FALSE;

  if (!jmethod.jstr())
    return JNI_FALSE;

  JSObject* thisObj = (JSObject*)jsthis;
  if (!thisObj || thisObj->isNull() || thisObj->isUndefined()) {
    thisObj = scriptObj;
  }
  if (!thisObj->isObject())
    return JNI_FALSE;

  JSValue* maybeFunc = scriptObj->get(execState, Identifier((const UChar*)jmethod.jstr(), jmethod.length()));
  if (!maybeFunc || !maybeFunc->isObject())
    return JNI_FALSE;
  
  JSObject* func = (JSObject*)maybeFunc;
  if (!func->implementsCall())
    return JNI_FALSE;

  List args;
  for (int i = 0; i < argc; ++i) {
    jint argi;
    env->GetIntArrayRegion(argv, i, 1, &argi);
    if (env->ExceptionCheck())
      return JNI_FALSE;
#ifdef ENABLE_TRACING
    snprintf(buf, sizeof(buf), " arg[%d]={%08x} ", i, argi);
    TRACE(buf);
    PrintJSValue((JSValue*)argi, buf);
#endif
    if (argi) {
      args.append((JSValue*)argi);
    } else {
      args.append(jsNull());
    }
  }

  JSValue* result = func->call(execState, thisObj, args);
  gcProtectNullTolerant(result);
#ifdef ENABLE_TRACING
  PrintJSValue(result, " return=");
#endif
  env->SetIntArrayRegion(rval, 0, 1, (jint*)&result);
  if (env->ExceptionCheck())
    return JNI_FALSE;

  TRACE("SUCCESS LowLevelSaf__1invoke");
  return JNI_TRUE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    isBoolean
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isBoolean
  (JNIEnv *, jclass, jint jsval) {
  if (!jsval)
    return JNI_FALSE;
    return ((JSValue*)jsval)->isBoolean() ? JNI_TRUE : JNI_FALSE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    isNumber
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isNumber
  (JNIEnv *, jclass, jint jsval) {
  if (!jsval)
    return JNI_FALSE;
  return ((JSValue*)jsval)->isNumber() ? JNI_TRUE : JNI_FALSE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _isString
 * Signature: (I)Z
 * 
 * Must return true for JavaScript String objects as well as string primitives.
 */
JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1isString
  (JNIEnv *, jclass, jint jsval) {
  if (!jsval)
    return JNI_FALSE;
  JSValue* jsValue = reinterpret_cast<JSValue*>(jsval);
  if(jsValue->isString()) return JNI_TRUE;
	if(jsValue->isObject()) {
		const JSObject* obj = jsValue->getObject();
		const ClassInfo* cinfo = obj->classInfo();
		if (cinfo && !strcmp(cinfo->className, "String")) {
			return JNI_TRUE;
		}
	}
	return JNI_FALSE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _isObject
 * Signature: (I)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1isObject
  (JNIEnv *, jclass, jint jsval) {
  if (!jsval)
    return JNI_FALSE;
  return ((JSValue*)jsval)->isObject() ? JNI_TRUE : JNI_FALSE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _isWrappedDispatch
 * Signature: (I[Z)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1isWrappedDispatch
  (JNIEnv* env, jclass, jint jsval, jbooleanArray rval) {
    TRACE("ENTER LowLevelSaf__1isWrappedDispatch");
  if (!jsval)
    return JNI_FALSE;

  JSValue* val = (JSValue*)jsval;
  jboolean result = val->isObject(&DispWrapper::info) ? JNI_TRUE : JNI_FALSE;

    env->SetBooleanArrayRegion(rval, 0, 1, &result);
    if (env->ExceptionCheck())
        return JNI_FALSE;

    TRACE("SUCCESS LowLevelSaf__1isWrappedDispatch");
    return JNI_TRUE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _jsLock
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1jsLock
  (JNIEnv *, jclass) {
  JSLock::lock();
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _jsUnlock
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1jsUnlock
  (JNIEnv *, jclass) {
  JSLock::unlock();
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _raiseJavaScriptException
 * Signature: (II)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1raiseJavaScriptException
  (JNIEnv *env, jclass, jint execState, jint jsval) {
    TRACE("ENTER LowLevelSaf__1raiseJavaScriptException");

  if (!execState || !jsval)
    return JNI_FALSE;

  ((ExecState*)execState)->setException((JSValue*)jsval);
    TRACE("SUCCESS LowLevelSaf__1raiseJavaScriptException");
  return JNI_TRUE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _unwrapDispatch
 * Signature: (I[Lcom/google/gwt/dev/shell/mac/LowLevelSaf/DispatchObject;)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1unwrapDispatch
  (JNIEnv* env, jclass, jint jsval, jobjectArray rval) {
    TRACE("ENTER LowLevelSaf__1unwrapDispatch");
  if (!jsval)
    return JNI_FALSE;

  JSValue* val = (JSValue*)jsval;
  if (!val->isObject(&DispWrapper::info))
    return JNI_FALSE;

  DispWrapper* wrapper = static_cast<DispWrapper*>(val);
    env->SetObjectArrayElement(rval, 0, wrapper->getDispObj());
    if (env->ExceptionCheck())
        return JNI_FALSE;

    TRACE("SUCCESS LowLevelSaf__1unwrapDispatch");
    return JNI_TRUE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _wrapDispatch
 * Signature: (Lcom/google/gwt/dev/shell/mac/LowLevelSaf/DispatchObject;[I)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1wrapDispatch
  (JNIEnv* env, jclass, jobject dispObj, jintArray rval) {
    TRACE("ENTER LowLevelSaf__1wrapDispatch");

    jobject dispObjRef = env->NewGlobalRef(dispObj);
    if (!dispObjRef || env->ExceptionCheck())
        return JNI_FALSE;
  
  DispWrapper* wrapper = new DispWrapper(dispObjRef);
  /*
   * TODO / LEAK / HACK: We will be persisting these objects on the java side,
   * so in order to keep the JS GC from collecting our objects when they are
   * away, we need to add them to the protect list. This should be refactored
   * out in favor of better memory mgmt scheme.
   */
  gcProtectNullTolerant(wrapper);
#ifdef ENABLE_TRACING
  char buf[256];
  snprintf(buf, sizeof(buf), " return={%08x} ", unsigned(wrapper));
  PrintJSValue((JSValue*)wrapper, buf);
#endif

    env->SetIntArrayRegion(rval, 0, 1, (jint*)&wrapper);
    if (env->ExceptionCheck())
        return JNI_FALSE;

    TRACE("SUCCESS LowLevelSaf__1wrapDispatch");
    return JNI_TRUE;
}

/*
 * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
 * Method:    _wrapFunction
 * Signature: (Ljava/lang/String;Lcom/google/gwt/dev/shell/mac/LowLevelSaf/DispatchMethod;[I)Z
 */
JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1wrapFunction
  (JNIEnv* env, jclass, jstring name, jobject dispMeth, jintArray rval) {
    TRACE("ENTER LowLevelSaf__1wrapFunction");

    jobject dispMethRef = env->NewGlobalRef(dispMeth);
    if (!dispMethRef || env->ExceptionCheck())
        return JNI_FALSE;
  
  JStringWrap jname(env, name);
  if (!jname.jstr())
    return JNI_FALSE;
  
  FuncWrapper* wrapper = new FuncWrapper(UString((const UChar*)jname.jstr(), jname.length()), dispMethRef);
  /*
   * TODO / LEAK / HACK: We will be persisting these objects on the java side,
   * so in order to keep the JS GC from collecting our objects when they are
   * away, we need to add them to the protect list. This should be refactored
   * out in favor of better memory mgmt scheme.
   */
  gcProtectNullTolerant(wrapper);
#ifdef ENABLE_TRACING
  char buf[256];
  snprintf(buf, sizeof(buf), " return={%08x} ", unsigned(wrapper));
  PrintJSValue((JSValue*)wrapper, buf);
#endif
    env->SetIntArrayRegion(rval, 0, 1, (jint*)&wrapper);
    if (env->ExceptionCheck())
        return JNI_FALSE;

    TRACE("SUCCESS LowLevelSaf__1wrapFunction");
    return JNI_TRUE;
}

#ifdef FILETRACE
FILE* gout = 0;
void filetrace(const char* s)
{
    fprintf(gout, s);
    fprintf(gout, "\n");
    fflush(gout);
}
#endif // FILETRACE

#ifdef JAVATRACE
jmethodID gTraceMethod = 0;
void javatrace(const char* s)
{
    if (!gEnv->ExceptionCheck())
    {
        jstring out = gEnv->NewStringUTF(s);
        if (!gEnv->ExceptionCheck())
            gEnv->CallStaticVoidMethod(gClass, gTraceMethod, out);
        else
            gEnv->ExceptionClear();
    }
}
#endif // JAVATRACE

