| /*  | 
 |  * 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 "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; | 
 |  | 
 | /* | 
 |  * Print a JSValue in human-readable form. | 
 |  *  | 
 |  * val JSValue* to print | 
 |  * prefix a string to print before the value | 
 |  */ | 
 | void PrintJSValue(JSValue* val, char* prefix) { | 
 |   static const char* typeStrings[]={ | 
 |     "unspecified", | 
 |     "number", | 
 |     "boolean", | 
 |     "undefined", | 
 |     "null", | 
 |     "string", | 
 |     "object", | 
 |     "getter/setter", | 
 |   }; | 
 |   char buf[256]; | 
 |   snprintf(buf, sizeof(buf), "%s{%08x}:", prefix, unsigned(val)); | 
 |   TRACE(buf); | 
 |   JSType type = val->type(); | 
 |   const char* typeString=typeStrings[type]; | 
 |   char* p = buf; | 
 |   p += snprintf(p, sizeof(buf)-(p-buf), " %s: ", typeString); | 
 |   //p += snprintf(p, sizeof(buf)-(p-buf), "%s{%08x} %s: ", prefix,  | 
 |   //    unsigned(val), 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", (int)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); | 
 | } | 
 |  | 
 | /* | 
 |  * Called for each gcProtect, only if TRACING is enabled. | 
 |  *  | 
 |  * val JSValue* to be protected | 
 |  */ | 
 | void gcProtectHook(JSValue* val) { | 
 |   PrintJSValue(val, "gcProtect: val="); | 
 | } | 
 |  | 
 | /* | 
 |  * Called for each gcUnprotect, only if TRACING is enabled. | 
 |  *  | 
 |  * val JSValue* to be protected | 
 |  * trace string containing trace information for the creation site, or null | 
 |  *     if not available | 
 |  */ | 
 | void gcUnprotectHook(JSValue* val, const char* trace) { | 
 |   if (trace) { | 
 |     TRACE("gcUnprotect - value created at:"); | 
 |     TRACE(trace); | 
 |   } | 
 |   PrintJSValue(val, "gcUnprotect: val="); | 
 | } | 
 |  | 
 | /* | 
 |  * 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 reinterpret_cast<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 reinterpret_cast<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"); | 
 | #ifdef ENABLE_TRACING | 
 |   char buf[256]; | 
 |   snprintf(buf, sizeof(buf), " val=%s", jval ? "true" : "false"); | 
 |   TRACE(buf); | 
 | #endif | 
 |  | 
 |   JSValue *jsval = (jval == JNI_FALSE) ? jsBoolean(false) : jsBoolean(true); | 
 |  | 
 |   /* | 
 |    * Since we know this is a boolean primitive, the protect is a no-op, but | 
 |    * it is useful to have it for the trace log. | 
 |    */ | 
 |   gwtGCProtect(jsval); | 
 |    | 
 |   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); | 
 |   gwtGCProtect(jsval); | 
 |   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())); | 
 |  | 
 |   gwtGCProtect(jsval); | 
 |   if (!jsval) { | 
 |     return JNI_FALSE; | 
 |   } | 
 |  | 
 |   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(), static_cast<int>(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) | 
 | { | 
 |   gwtGCProtect(reinterpret_cast<JSValue*>(jsval)); | 
 | } | 
 |  | 
 | /* | 
 |  * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf | 
 |  * Method:    _gcUnlock | 
 |  * Signature: (ILjava/lang/String;)V | 
 |  */ | 
 | JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1gcUnlock | 
 |     (JNIEnv* jniEnv, jclass, jint jsval, jstring creationDesc) | 
 | { | 
 |   JStringWrap creationStr(jniEnv, creationDesc); | 
 |   gwtGCUnprotect(reinterpret_cast<JSValue*>(jsval), | 
 |       creationDesc ? creationStr.str() : 0); | 
 | } | 
 |  | 
 | /* | 
 |  * 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), "scriptObject=%08x, method=%s, argc=%d", | 
 |       static_cast<unsigned>(jsScriptObject), jmethod.str(), | 
 |       static_cast<unsigned>(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]=", i); | 
 |     TRACE(buf); | 
 |     PrintJSValue((JSValue*)argi, buf); | 
 | #endif | 
 |     if (argi) { | 
 |       args.append((JSValue*)argi); | 
 |     } else { | 
 |       args.append(jsNull()); | 
 |     } | 
 |   } | 
 |  | 
 |   JSValue* result = func->call(execState, thisObj, args); | 
 |   gwtGCProtect(result); | 
 |   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 reinterpret_cast<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 reinterpret_cast<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; | 
 |   // check for JavaScript String objects | 
 |   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 reinterpret_cast<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; | 
 |   } | 
 |  | 
 |   reinterpret_cast<ExecState*>(execState)->setException( | 
 |       reinterpret_cast<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 = reinterpret_cast<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); | 
 |  | 
 |   gwtGCProtect(wrapper); | 
 |  | 
 |   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); | 
 |  | 
 |   gwtGCProtect(wrapper); | 
 |   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 |