| /* |
| * Copyright 2008 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 <iostream> |
| #include <JavaScriptCore/JavaScriptCore.h> |
| #include "gwt-webkit.h" |
| #include "JStringWrap.h" |
| #include "java-dispatch.h" |
| #include "trace.h" |
| |
| |
| // http://unixjunkie.blogspot.com/2006/07/access-argc-and-argv-from-anywhere.html |
| extern "C" int *_NSGetArgc(void); |
| extern "C" char ***_NSGetArgv(void); |
| |
| /* |
| * |
| */ |
| JSContextRef ToJSContextRef(jint context) { |
| return reinterpret_cast<JSContextRef>(context); |
| } |
| |
| /* |
| * |
| */ |
| JSValueRef ToJSValueRef(jint value) { |
| return reinterpret_cast<JSValueRef>(value); |
| } |
| |
| /* |
| * |
| */ |
| JSObjectRef ToJSObjectRef(JSContextRef jsContext, jint object, |
| JSValueRef* jsException) { |
| JSValueRef jsValue = reinterpret_cast<JSValueRef>(object); |
| if (!jsValue || !JSValueIsObject(jsContext, jsValue)) { |
| return NULL; |
| } |
| return JSValueToObject(jsContext, jsValue, jsException); |
| } |
| |
| /* |
| * |
| */ |
| JSObjectRef ToJSObjectRef(JSContextRef jsContext, JSValueRef jsValue, |
| JSValueRef* jsException) { |
| if (!jsValue || !JSValueIsObject(jsContext, jsValue)) { |
| return NULL; |
| } |
| return JSValueToObject(jsContext, jsValue, jsException); |
| } |
| |
| /* |
| * |
| */ |
| JSObjectRef GetStringConstructor(JSContextRef jsContext, |
| JSValueRef* jsException) { |
| // This could only be cached relative to jsContext. |
| JSStringRef script = JSStringCreateWithUTF8CString("(String)"); |
| JSValueRef ctorVal = JSEvaluateScript(jsContext, script, NULL, NULL, 0, jsException); |
| JSStringRelease(script); |
| return ToJSObjectRef(jsContext, ctorVal, jsException); |
| } |
| |
| /* |
| * |
| */ |
| bool IsObjectOfStringConstructor(JSContextRef jsContext, JSValueRef jsValue, |
| JSValueRef* jsException) { |
| JSObjectRef jsObject = ToJSObjectRef(jsContext, jsValue, jsException); |
| if (!jsObject) { |
| return false; |
| } |
| JSObjectRef stringCtor = GetStringConstructor(jsContext, jsException); |
| if (!stringCtor) { |
| return false; |
| } |
| return JSValueIsInstanceOfConstructor(jsContext, jsObject, stringCtor, |
| jsException); |
| } |
| |
| #if 0 // For debugging purposes only. |
| void PrintJSString(JSStringRef jsString) |
| { |
| size_t length = JSStringGetMaximumUTF8CStringSize(jsString); |
| char* buffer = new char[length]; |
| JSStringGetUTF8CString(jsString, buffer, length); |
| std::cerr << "JSString: " << buffer << std::endl; |
| delete[] buffer; |
| } |
| |
| void PrintJSValue(JSContextRef jsContext, JSValueRef jsValue) |
| { |
| JSValueRef jsException = NULL; |
| JSStringRef jsResult = JSValueToStringCopy(jsContext, jsValue, |
| &jsException); |
| if (!jsException && jsValue) { |
| PrintJSString(jsResult); |
| } else { |
| std::cerr << "Could not convert the value to string." << std::endl; |
| } |
| } |
| #endif |
| |
| /* |
| * |
| */ |
| JSStringRef ToJSStringRef(JNIEnv* env, jstring jstr) { |
| if (!jstr) { |
| return NULL; |
| } |
| |
| JStringWrap jstrw(env, jstr); |
| if (!jstrw.jstr()) { |
| return NULL; |
| } |
| |
| return JSStringCreateWithCharacters(static_cast<const JSChar*>(jstrw.jstr()), |
| static_cast<size_t>(jstrw.length())); |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsNull |
| (JNIEnv *env, jclass klass, jint context, jint value) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| JSValueRef jsValue = ToJSValueRef(value); |
| if (!jsContext || !jsValue) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| TR_LEAVE(); |
| return static_cast<jboolean>(JSValueIsNull(jsContext, jsValue)); |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsUndefined |
| (JNIEnv *env, jclass klass, jint context, jint value) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| JSValueRef jsValue = ToJSValueRef(value); |
| if (!jsContext || !jsValue) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| TR_LEAVE(); |
| return static_cast<jboolean>(JSValueIsUndefined(jsContext, jsValue)); |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getJsUndefined |
| (JNIEnv *env, jclass klass, jint context) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| if (!jsContext) { |
| return static_cast<jint>(NULL); |
| } |
| |
| JSValueRef jsUndefined = JSValueMakeUndefined(jsContext); |
| JSValueProtectChecked(jsContext, jsUndefined); |
| TR_LEAVE(); |
| return reinterpret_cast<jint>(jsUndefined); |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getJsNull |
| (JNIEnv *env, jclass klass, jint context) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| if (!jsContext) { |
| return static_cast<jint>(NULL); |
| } |
| JSValueRef jsNull = JSValueMakeNull(jsContext); |
| JSValueProtectChecked(jsContext, jsNull); |
| TR_LEAVE(); |
| return reinterpret_cast<jint>(jsNull); |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsBoolean |
| (JNIEnv *env, jclass klass, jint context, jint value) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| JSValueRef jsValue = ToJSValueRef(value); |
| if (!jsContext || !jsValue) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| TR_LEAVE(); |
| return static_cast<jboolean>(JSValueIsBoolean(jsContext, jsValue)); |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsNumber |
| (JNIEnv *env, jclass klass, jint context, jint value) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| JSValueRef jsValue = ToJSValueRef(value); |
| if (!jsContext || !jsValue) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| TR_LEAVE(); |
| return static_cast<jboolean>(JSValueIsNumber(jsContext, jsValue)); |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toJsBooleanImpl |
| (JNIEnv *env, jclass klass, jint context, jboolean jValue, jintArray rval) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| if (!jsContext) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSValueRef jsValue = JSValueMakeBoolean(jsContext, static_cast<bool>(jValue)); |
| |
| env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<const jint*>(&jsValue)); |
| if (env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| JSValueProtectChecked(jsContext, jsValue); |
| |
| TR_LEAVE(); |
| return JNI_TRUE; |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_gcUnprotect |
| (JNIEnv *env, jclass klass, jint context, jint value) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| JSValueRef jsValue = ToJSValueRef(value); |
| if (!jsContext || !jsValue) { |
| return; |
| } |
| JSValueUnprotectChecked(jsContext, jsValue); |
| TR_LEAVE(); |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toJsNumberImpl |
| (JNIEnv *env, jclass klass, jint context, jdouble jValue, jintArray rval) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| if (!jsContext) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSValueRef jsValue = JSValueMakeNumber(jsContext, static_cast<jdouble>(jValue)); |
| |
| env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<const jint*>(&jsValue)); |
| if (env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSValueProtectChecked(jsContext, jsValue); |
| |
| TR_LEAVE(); |
| return JNI_TRUE; |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_executeScriptWithInfoImpl |
| (JNIEnv *env, jclass klass, jint context, jstring jScript, jstring jUrl, |
| jint jLine, jintArray rval) { |
| TR_ENTER(); |
| JSValueRef jsException = NULL; |
| |
| JSContextRef jsContext = ToJSContextRef(context); |
| if (!jsContext) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSStringRef jsScript = ToJSStringRef(env, jScript); |
| if (!jsScript) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSStringRef jsUrl = ToJSStringRef(env, jUrl); |
| |
| // Evaluate will set this to global object. |
| JSValueRef jsResult = JSEvaluateScript(jsContext, jsScript, NULL, jsUrl, |
| static_cast<int>(jLine), &jsException); |
| if (jsException) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSStringRelease(jsScript); |
| if (jsUrl) { |
| JSStringRelease(jsUrl); |
| } |
| |
| env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<const jint*>(&jsResult)); |
| if (env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSValueProtectChecked(jsContext, jsResult); |
| |
| TR_LEAVE(); |
| return JNI_TRUE; |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toJsStringImpl |
| (JNIEnv *env, jclass klass, jint context, jstring jValue, jintArray rval) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| if (!jsContext) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSStringRef jsString = ToJSStringRef(env, jValue); |
| if (!jsString) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSValueRef jsValue = JSValueMakeString(jsContext, jsString); |
| JSStringRelease(jsString); |
| |
| env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<const jint*>(&jsValue)); |
| if (env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSValueProtectChecked(jsContext, jsValue); |
| |
| TR_LEAVE(); |
| return JNI_TRUE; |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsStringImpl |
| (JNIEnv *env, jclass klass, jint context, jint value, jbooleanArray rval) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| JSValueRef jsValue = ToJSValueRef(value); |
| if (!jsContext || !jsValue) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| bool isString = JSValueIsString(jsContext, jsValue); |
| if (!isString) { |
| JSValueRef jsException = NULL; |
| isString = IsObjectOfStringConstructor(jsContext, jsValue, &jsException); |
| if (jsException) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| } |
| |
| jboolean jIsString = static_cast<jboolean>(isString); |
| env->SetBooleanArrayRegion(rval, 0, 1, &jIsString); |
| if (env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| TR_LEAVE(); |
| return JNI_TRUE; |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_invokeImpl |
| (JNIEnv *env, jclass klass, jint context, jint scriptValue, |
| jstring jMethodName, jint thisVal, jintArray jArgs, jint jArgsLength, |
| jintArray rval) { |
| TR_ENTER(); |
| |
| JSContextRef jsContext = ToJSContextRef(context); |
| if (!jsContext) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSObjectRef jsScriptObj = ToJSObjectRef(jsContext, scriptValue, NULL); |
| if (!jsScriptObj) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSValueRef jsThisVal = ToJSValueRef(thisVal); |
| JSObjectRef jsThisObj = NULL; |
| // If thisVal is null, jsNull, or jsUndefined use the script object |
| // as this. |
| if (!jsThisVal || JSValueIsNull(jsContext, jsThisVal) |
| || JSValueIsUndefined(jsContext, jsThisVal)) { |
| jsThisObj = jsScriptObj; |
| } else { |
| // If we are given a value, ensure that it is an object. |
| jsThisObj = ToJSObjectRef(jsContext, jsThisVal, NULL); |
| if (!jsThisObj) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| } |
| |
| JSStringRef jsMethodName = ToJSStringRef(env, jMethodName); |
| if (!jsMethodName) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSObjectRef jsMethod = ToJSObjectRef(jsContext, JSObjectGetProperty(jsContext, |
| jsScriptObj, jsMethodName, NULL), NULL); |
| if (!jsMethod || !JSObjectIsFunction(jsContext, jsMethod)) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSStringRelease(jsMethodName); |
| |
| // NOTE (knorton): Fix for 64-bit. |
| JSValueRef* jsArgs = new JSValueRef[static_cast<size_t>(jArgsLength)]; |
| env->GetIntArrayRegion(jArgs, 0, jArgsLength, |
| reinterpret_cast<jint*>(jsArgs)); |
| if (env->ExceptionCheck()) { |
| TR_FAIL(); |
| delete[] jsArgs; |
| return JNI_FALSE; |
| } |
| |
| JSValueRef jsException = NULL; |
| JSValueRef jsResult = JSObjectCallAsFunction(jsContext, jsMethod, jsThisObj, |
| static_cast<size_t>(jArgsLength), jsArgs, &jsException); |
| if (jsException) { |
| TR_FAIL(); |
| delete[] jsArgs; |
| return JNI_FALSE; |
| } |
| delete[] jsArgs; |
| |
| env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<const jint*>(&jsResult)); |
| if (env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSValueProtectChecked(jsContext, jsResult); |
| |
| TR_LEAVE(); |
| return JNI_TRUE; |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsObject |
| (JNIEnv *env, jclass klass, jint context, jint value) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| JSValueRef jsValue = ToJSValueRef(value); |
| if (!jsContext || !jsValue) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| TR_LEAVE(); |
| return static_cast<jboolean>(JSValueIsObject(jsContext, jsValue)); |
| } |
| |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toBooleanImpl |
| (JNIEnv *env, jclass klass, jint context, jint value, jbooleanArray rval) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| JSValueRef jsValue = ToJSValueRef(value); |
| if (!jsContext || !jsValue) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| jboolean jResult = static_cast<jboolean>(JSValueToBoolean(jsContext, jsValue)); |
| env->SetBooleanArrayRegion(rval, 0, 1, &jResult); |
| if (env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| TR_LEAVE(); |
| return JNI_TRUE; |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toDoubleImpl |
| (JNIEnv *env, jclass klass, jint context, jint value, jdoubleArray rval) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| JSValueRef jsValue = ToJSValueRef(value); |
| if (!jsContext || !jsValue) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSValueRef jsException = NULL; |
| double result = JSValueToNumber(jsContext, jsValue, &jsException); |
| if (jsException) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| env->SetDoubleArrayRegion(rval, 0, 1, static_cast<jdouble*>(&result)); |
| if (env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| TR_LEAVE(); |
| return JNI_TRUE; |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toStringImpl |
| (JNIEnv *env, jclass klass, jint context, jint value, jobjectArray rval) { |
| TR_ENTER(); |
| JSValueRef jsException = NULL; |
| JSContextRef jsContext = ToJSContextRef(context); |
| JSValueRef jsValue = ToJSValueRef(value); |
| if (!jsContext || !jsValue) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| jstring jResult = NULL; |
| // Convert all objects to their string representation, EXCEPT |
| // null and undefined which will be returned as a true NULL. |
| if (!JSValueIsNull(jsContext, jsValue) && |
| !JSValueIsUndefined(jsContext, jsValue)) { |
| JSStringRef jsResult = JSValueToStringCopy(jsContext, jsValue, &jsException); |
| if (jsException) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| jResult = env->NewString( |
| static_cast<const jchar*>(JSStringGetCharactersPtr(jsResult)), |
| static_cast<jsize>(JSStringGetLength(jsResult))); |
| if (env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSStringRelease(jsResult); |
| } |
| |
| env->SetObjectArrayElement(rval, 0, jResult); |
| if (env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| TR_LEAVE(); |
| return JNI_TRUE; |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_wrapDispatchObjectImpl |
| (JNIEnv *env, jclass klass, jint context, jobject dispatch, jintArray rval) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| if (!jsContext) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSObjectRef jsDispatch = gwt::DispatchObjectCreate(jsContext, dispatch); |
| if (!jsDispatch || env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<jint*>(&jsDispatch)); |
| if (env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSValueProtectChecked(jsContext, jsDispatch); |
| |
| TR_LEAVE(); |
| return JNI_TRUE; |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_unwrapDispatchObjectImpl |
| (JNIEnv *env, jclass klass, jint context, jint value, jobjectArray rval) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| JSValueRef jsValue = ToJSValueRef(value); |
| if (!jsContext || !jsValue) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| if (!JSValueIsObjectOfClass(jsContext, jsValue, gwt::GetDispatchObjectClass())) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSObjectRef jsObject = ToJSObjectRef(jsContext, jsValue, NULL); |
| if (!jsObject) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| env->SetObjectArrayElement(rval, 0, reinterpret_cast<jobject>(JSObjectGetPrivate(jsObject))); |
| if (env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| TR_LEAVE(); |
| return JNI_TRUE; |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_initImpl |
| (JNIEnv *env, jclass klass, jclass dispatchObjectClass, |
| jclass dispatchMethodClass, jclass lowLevelSafClass) { |
| TR_ENTER(); |
| TR_LEAVE(); |
| return static_cast<jboolean>(gwt::Initialize(env, dispatchObjectClass, dispatchMethodClass, lowLevelSafClass)); |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_wrapDispatchMethodImpl |
| (JNIEnv *env, jclass klass, jint context, jstring name, jobject jDispatch, |
| jintArray rval) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| if (!jsContext) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JStringWrap nameWrap(env, name); |
| std::string nameStr(nameWrap.str()); |
| JSObjectRef jsDispatch = gwt::DispatchMethodCreate(jsContext, nameStr, |
| jDispatch); |
| if (!jsDispatch || env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<jint*>(&jsDispatch)); |
| if (env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSValueProtectChecked(jsContext, jsDispatch); |
| |
| TR_LEAVE(); |
| return JNI_TRUE; |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jstring JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getTypeString |
| (JNIEnv *env, jclass klass, jint context, jint value) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| JSValueRef jsValue = ToJSValueRef(value); |
| if (!jsContext || !jsValue) { |
| return NULL; |
| } |
| |
| switch (JSValueGetType(jsContext, jsValue)) { |
| case kJSTypeUndefined: |
| return env->NewStringUTF("undefined"); |
| case kJSTypeNull: |
| return env->NewStringUTF("null"); |
| case kJSTypeBoolean: |
| return env->NewStringUTF("boolean"); |
| case kJSTypeNumber: |
| return env->NewStringUTF("number"); |
| case kJSTypeString: |
| return env->NewStringUTF("string"); |
| case kJSTypeObject: |
| return (JSValueIsObjectOfClass(jsContext, jsValue, gwt::GetDispatchObjectClass())) |
| ? env->NewStringUTF("Java object") : env->NewStringUTF("JavaScript object"); |
| default: |
| return env->NewStringUTF("unknown"); |
| } |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isDispatchObjectImpl |
| (JNIEnv *env, jclass klass, jint context, jint value, jbooleanArray rval) { |
| TR_ENTER(); |
| JSContextRef jsContext = ToJSContextRef(context); |
| JSValueRef jsValue = ToJSValueRef(value); |
| if (!jsContext || !jsValue) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| jboolean jIsDispatchObject = static_cast<jboolean>(JSValueIsObjectOfClass( |
| jsContext, jsValue, gwt::GetDispatchObjectClass())); |
| env->SetBooleanArrayRegion(rval, 0, 1, &jIsDispatchObject); |
| if (env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| TR_LEAVE(); |
| return JNI_TRUE; |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getArgc |
| (JNIEnv *env, jclass klass) { |
| return *_NSGetArgc(); |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jstring JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getArgv |
| (JNIEnv *env, jclass klass, jint index) { |
| int argc = *_NSGetArgc(); |
| if (index < 0 || index >= argc) { |
| return 0; |
| } |
| char **argv = *_NSGetArgv(); |
| return env->NewStringUTF(argv[index]); |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getGlobalJsObjectImpl |
| (JNIEnv *env, jclass klass, jint context, jintArray rval) { |
| TR_ENTER(); |
| |
| JSContextRef jsContext = ToJSContextRef(context); |
| if (!jsContext) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSObjectRef jsGlobalObject = JSContextGetGlobalObject(jsContext); |
| env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<jint*>(&jsGlobalObject)); |
| if (env->ExceptionCheck()) { |
| TR_FAIL(); |
| return JNI_FALSE; |
| } |
| |
| JSValueProtectChecked(jsContext, jsGlobalObject); |
| |
| TR_LEAVE(); |
| return JNI_TRUE; |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_gcProtect |
| (JNIEnv *env, jclass klass, jint context, jint value) { |
| TR_ENTER(); |
| |
| JSContextRef jsContext = ToJSContextRef(context); |
| JSValueRef jsValue = ToJSValueRef(value); |
| if (!jsContext || !jsValue) { |
| return; |
| } |
| |
| JSValueProtectChecked(jsContext, jsValue); |
| TR_LEAVE(); |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_retainJsGlobalContext |
| (JNIEnv *env, jclass klass, jint context) { |
| TR_ENTER(); |
| JSGlobalContextRef jsContext = reinterpret_cast<JSGlobalContextRef>(context); |
| if (!jsContext) { |
| TR_FAIL(); |
| return; |
| } |
| JSGlobalContextRetain(jsContext); |
| TR_LEAVE(); |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_releaseJsGlobalContext |
| (JNIEnv *env, jclass klass, jint context) { |
| TR_ENTER(); |
| JSGlobalContextRef jsContext = reinterpret_cast<JSGlobalContextRef>(context); |
| if (!jsContext) { |
| TR_FAIL(); |
| return; |
| } |
| JSGlobalContextRelease(jsContext); |
| TR_LEAVE(); |
| } |
| |
| /* |
| * |
| */ |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isGcProtected |
| (JNIEnv *env, jclass klass, jint value) { |
| JSValueRef jsValue = ToJSValueRef(value); |
| TR_ENTER(); |
| TR_LEAVE(); |
| return static_cast<jboolean>(JSValueIsProtected(jsValue)); |
| } |
| |
| JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsValueProtectionCheckingEnabledImpl |
| (JNIEnv *env, jclass klass) { |
| TR_ENTER(); |
| TR_LEAVE(); |
| return static_cast<jboolean>(JSValueProtectCheckingIsEnabled()); |
| } |