JNIEXPORT void JNICALL Java_com_appcelerator_hyperloop_HyperloopJNI_HyperloopCallActivityOnCreate (JNIEnv *env, jobject thiz, jlong jsContextRef, jobject activity, jobject savedInstanceState) { JSContextRef context = (JSContextRef)jsContextRef; JSObjectRef globalObject = JSContextGetGlobalObject(context); JSStringRef onCreate = JSStringCreateWithUTF8CString("onCreate"); JSObjectRef onCreateFunc = JSValueToObject(context, JSObjectGetProperty(context, globalObject, onCreate, NULL), NULL); JSStringRelease(onCreate); // save current Activity JSObjectRef activityObj = MakeObjectForJava_android_app_Activity(context, activity); // save parameter JSValueRef args[1]; args[0] = MakeObjectForJava_android_os_Bundle(context, savedInstanceState); JSValueRef exception = JSValueMakeNull(context); // Call onCreate function if (JSObjectIsFunction(context, onCreateFunc)) { JSObjectCallAsFunction(context, onCreateFunc, activityObj, 1, args, &exception); } if (!JSValueIsNull(context, exception)) { JSStringRef string = JSValueToStringCopy(context, exception, NULL); CCHAR_FROM_JSSTRINGREF(string, cstring); LOGD("Java_com_appcelerator_hyperloop_HyperloopJNI_HyperloopCallActivityOnCreate '%s'", cstring); free(cstring); JSStringRelease(string); } }
JNIEXPORT jboolean JNICALL Java_com_appcelerator_hyperloop_ViewOnTouchListener_NativeOnTouch (JNIEnv *env, jobject thiz, jlong jsContextRef, jlong thisObjectRef, jlong onTouchFuncRef, jobject view, jobject event) { JSContextRef ctx = (JSContextRef)jsContextRef; JSObjectRef onTouchFunc = (JSObjectRef)onTouchFuncRef; JSObjectRef thisObject = (JSObjectRef)thisObjectRef; JSValueRef argv[2]; argv[0] = MakeObjectForJava_android_view_View(ctx, view); argv[1] = MakeObjectForJava_android_view_MotionEvent(ctx, event); if (JSObjectIsFunction(ctx, onTouchFunc)) { JSValueRef exception = JSValueMakeNull(ctx); JSValueRef result = JSObjectCallAsFunction(ctx, onTouchFunc, thisObject, 2, argv, &exception); if (!JSValueIsNull(ctx, exception)) { JSStringRef string = JSValueToStringCopy(ctx, exception, NULL); CCHAR_FROM_JSSTRINGREF(string, cstring); LOGD("Java_com_appcelerator_hyperloop_ViewOnTouchListener_NativeOnTouch '%s'", cstring); free(cstring); JSStringRelease(string); } return JSValueToBoolean(ctx, result) ? JNI_TRUE : JNI_FALSE; } return JNI_FALSE; }
Type GetType(JSValueRef value) { if (JSValueIsNull(g_ctx, value)) return VTYPE_NULL; if (JSValueIsBoolean(g_ctx, value)) return VTYPE_BOOL; if (JSValueIsNumber(g_ctx, value)) return VTYPE_DOUBLE; if (JSValueIsString(g_ctx, value)) return VTYPE_STRING; if (JSValueIsObject(g_ctx, value)) { JSObjectRef obj = JSValueToObject(g_ctx, value, NULL); if (JSObjectIsFunction(g_ctx, obj)) return VTYPE_FUNCTION; if (IsArray(obj)) return VTYPE_LIST; return VTYPE_DICTIONARY; } return VTYPE_INVALID; }
gboolean filter_function_child(JSContextRef ctx, JSValueRef jsvalue, int i) { JSObjectRef p =JSValueToObject(ctx, JSObjectGetPropertyAtIndex(ctx, (JSObjectRef)jsvalue, i, NULL), NULL); if (p == NULL) { return FALSE; } return JSObjectIsFunction(ctx, p); }
static JSValueRef seed_gobject_signal_connect_on_property (JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef * exception) { gulong id = 0; JSObjectRef this_obj; signal_privates *privates; privates = (signal_privates *) JSObjectGetPrivate (thisObject); if (!privates) g_error ("Signal constructed with invalid parameters" "in namespace import \n"); this_obj = (JSObjectRef) seed_value_from_object (ctx, privates->object, exception); if ((argumentCount > 2) || (argumentCount == 0)) { seed_make_exception (ctx, exception, "ArgumentError", "Signal connection expected" " 1, or 2 arguments. Got " "%zd", argumentCount); return JSValueMakeNull (ctx); } if (JSValueIsNull (ctx, arguments[0]) || !JSValueIsObject (ctx, arguments[0]) || !JSObjectIsFunction (ctx, (JSObjectRef) arguments[0])) { seed_make_exception (ctx, exception, "ArgumentError", "Signal connection requires a function" " as first argument"); return JSValueMakeNull (ctx); } if (argumentCount == 1) { id = seed_gobject_signal_connect (ctx, privates->signal_name, privates->object, (JSObjectRef) arguments[0], this_obj, NULL); } else if (argumentCount == 2) { id = seed_gobject_signal_connect (ctx, privates->signal_name, privates->object, (JSObjectRef) arguments[0], this_obj, (JSObjectRef) arguments[1]); } return seed_value_from_ulong (ctx, id, exception); }
void JSArray::push(const JSValue& val) { JSValueRef prop = JSObjectGetProperty(ctx_, instance_, JSString("push"), nullptr); if (JSValueIsObject(ctx_, prop)) { JSObjectRef func = JSValueToObject(ctx_, prop, nullptr); if (JSObjectIsFunction(ctx_, func)) { JSValueRef arg = val; JSObjectCallAsFunction(ctx_, func, instance_, 1, &arg, nullptr); } } }
/** * invoke a function callback */ EXPORTAPI JSValueRef HyperloopInvokeFunctionCallback (JSContextRef ctx, void * callbackPointer, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) { JSValueRef callback = *(JSValueRef*)callbackPointer; if (!JSValueIsObject(ctx, callback) || !JSObjectIsFunction(ctx, JSValueToObject(ctx,callback,exception))) { *exception = HyperloopMakeException(ctx,"Function callback is not a JS function object"); return JSValueMakeUndefined(ctx); } JSObjectRef callbackObj = JSValueToObject(ctx,callback,exception); return JSObjectCallAsFunction(HyperloopGlobalContext(), callbackObj, NULL, argumentCount, arguments, exception); }
bool web_view_callback (struct js_callback_data *data) { unsigned short i; JSValueRef js_args[data->args_len]; for (i = 0; i < data->args_len; i++) { switch (data->args[i].type) { case kJSTypeBoolean: js_args[i] = JSValueMakeBoolean(data->widget->js_context, data->args[i].value.boolean); break; case kJSTypeNull: js_args[i] = JSValueMakeNull(data->widget->js_context); break; case kJSTypeNumber: js_args[i] = JSValueMakeNumber(data->widget->js_context, data->args[i].value.number); break; case kJSTypeObject: js_args[i] = data->args[i].value.object; break; case kJSTypeString: { JSStringRef str = JSStringCreateWithUTF8CString(data->args[i].value.string); js_args[i] = JSValueMakeString(data->widget->js_context, str); JSStringRelease(str); break; } case kJSTypeUndefined: js_args[i] = JSValueMakeUndefined(data->widget->js_context); break; } } if (!data->widget->js_context || !data->widget->js_object) { LOG_ERR("missing JS context or object!"); return false; } JSStringRef str_ondatachanged = JSStringCreateWithUTF8CString("onDataChanged"); JSValueRef func = JSObjectGetProperty(data->widget->js_context, data->widget->js_object, str_ondatachanged, NULL); JSObjectRef function = JSValueToObject(data->widget->js_context, func, NULL); JSStringRelease(str_ondatachanged); /* let the thread know we're done with the data so it can cleanup */ pthread_cond_signal(&update_cond); if (!JSObjectIsFunction(data->widget->js_context, function)) { LOG_DEBUG("onDataChanged callback for 'widget_%s' with type '%s' is not a function or is not set", data->widget->name, data->widget->type); return false; /* only run once */ } JSObjectCallAsFunction(data->widget->js_context, function, NULL, data->args_len, js_args, NULL); return false; /* only run once */ }
static JSValueRef seed_gobject_signal_connect_by_name (JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef * exception) { GType obj_type; JSObjectRef user_data = NULL; gchar *signal_name; GObject *obj; gulong id; if (argumentCount < 2 || argumentCount > 3) { seed_make_exception (ctx, exception, "ArgumentError", "Signal connection expected" " 2 or 3 arguments. Got " "%zd", argumentCount); return JSValueMakeNull (ctx); } if (JSValueIsNull (ctx, arguments[1]) || !JSValueIsObject (ctx, arguments[1]) || !JSObjectIsFunction (ctx, (JSObjectRef) arguments[1])) { seed_make_exception (ctx, exception, "ArgumentError", "Signal connection by name " "requires a function" " as second argument"); return JSValueMakeNull (ctx); } if (argumentCount == 3) { user_data = (JSObjectRef) arguments[2]; } signal_name = seed_value_to_string (ctx, arguments[0], exception); obj = (GObject *) JSObjectGetPrivate (thisObject); obj_type = G_OBJECT_TYPE (obj); id = seed_gobject_signal_connect (ctx, signal_name, obj, (JSObjectRef) arguments[1], NULL, user_data); g_free (signal_name); return seed_value_from_ulong (ctx, id, exception); }
int JSArray::indexOf(const JSValue& val, int start) const { JSValueRef prop = JSObjectGetProperty(ctx_, instance_, JSString("indexOf"), nullptr); if (JSValueIsObject(ctx_, prop)) { JSObjectRef func = JSValueToObject(ctx_, prop, nullptr); if (JSObjectIsFunction(ctx_, func)) { JSValueRef args[2] = { val, JSValueMakeNumber(ctx_, start) }; JSValueRef result = JSObjectCallAsFunction(ctx_, func, instance_, 2, args, nullptr); if (JSValueIsNumber(ctx_, result)) { return static_cast<int>(JSValueToNumber(ctx_, result, nullptr)); } } } return -1; }
static void callOnMessage(JSObjectRef object, WKStringRef contents, WKBundlePageRef page) { static JSStringRef onmessageName = JSStringCreateWithUTF8CString("onmessage"); if (!object) return; WKBundleFrameRef frame = WKBundlePageGetMainFrame(page); JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame); JSValueRef onmessageValue = JSObjectGetProperty(context, object, onmessageName, 0); if (!JSValueIsObject(context, onmessageValue)) return; JSObjectRef onmessageFunction = JSValueToObject(context, onmessageValue, 0); if (!JSObjectIsFunction(context, onmessageFunction)) return; JSObjectRef wrappedMessage = createWrappedMessage(context, contents); JSObjectCallAsFunction(context, onmessageFunction, 0, 1, &wrappedMessage, 0); }
void QtBuiltinBundlePage::didReceiveMessageToNavigatorQtObject(WKStringRef contents) { static JSStringRef onmessageName = JSStringCreateWithUTF8CString("onmessage"); if (!m_navigatorQtObject) return; WKBundleFrameRef frame = WKBundlePageGetMainFrame(m_page); JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame); JSValueRef onmessageValue = JSObjectGetProperty(context, m_navigatorQtObject, onmessageName, 0); if (!JSValueIsObject(context, onmessageValue)) return; JSObjectRef onmessageFunction = JSValueToObject(context, onmessageValue, 0); if (!JSObjectIsFunction(context, onmessageFunction)) return; JSObjectRef wrappedMessage = createWrappedMessage(context, contents); JSObjectCallAsFunction(context, onmessageFunction, 0, 1, &wrappedMessage, 0); }
bool jsc::Value::isFunction() const {return JSValueIsObject(context, value) && JSObjectIsFunction(context, const_cast<JSObjectRef>(value));}
NATIVE(JSObject,jboolean,isFunction) (PARAMS, jlong ctx, jlong object) { return JSObjectIsFunction((JSContextRef) ctx, (JSObjectRef) object); }
bool VJSValue::IsFunction() const { JSObjectRef obj = ( (fValue != NULL) && JSValueIsObject( fContext, fValue) ) ? JSValueToObject( fContext, fValue, NULL) : NULL; return (obj != NULL) ? JSObjectIsFunction( fContext, obj) : false; }
bool script_state_save_single(int script_idx,bool checkpoint,char *err_str) { int n,count,prop_name_len,prop_value_len; char prop_name[256]; char *prop_value; script_type *script; JSPropertyNameArrayRef js_names; JSStringRef js_prop_name,js_prop_json; JSValueRef js_prop_value; if (script_idx==-1) return(TRUE); // send save state event scripts_post_event(script_idx,-1,sd_event_state,(checkpoint?sd_event_state_save_checkpoint:sd_event_state_save),0,err_str); // get the script script=js.script_list.scripts[script_idx]; // run through the properities js_names=JSObjectCopyPropertyNames(script->cx,script->global_obj); count=JSPropertyNameArrayGetCount(js_names); for (n=0;n!=count;n++) { // get the property name and value js_prop_name=JSPropertyNameArrayGetNameAtIndex(js_names,n); js_prop_value=JSObjectGetProperty(script->cx,script->global_obj,js_prop_name,NULL); // skip all properties that are functions if (js_prop_value!=NULL) { if (JSValueIsObject(script->cx,js_prop_value)) { if (JSObjectIsFunction(script->cx,(JSObjectRef)js_prop_value)) continue; } } // skip all API objects or DIM3 defines JSStringGetUTF8CString(js_prop_name,prop_name,256); prop_name[255]=0x0; if (script_is_prop_global_object(prop_name)) continue; if (script_is_prop_define(prop_name)) continue; // process the property with JSON js_prop_json=JSValueCreateJSONString(script->cx,js_prop_value,0,NULL); if (js_prop_json==NULL) continue; prop_value_len=JSStringGetMaximumUTF8CStringSize(js_prop_json); prop_value=(char*)malloc(prop_value_len); if (prop_value==NULL) { strcpy(err_str,"Out of Memory"); JSStringRelease(js_prop_json); return(FALSE); } prop_value_len=JSStringGetUTF8CString(js_prop_json,prop_value,prop_value_len); JSStringRelease(js_prop_json); // save property, we have to write a length // with each of these because they can be of any size prop_name_len=strlen(prop_name)+1; game_file_add_chunk(&prop_name_len,1,sizeof(int)); game_file_add_chunk(prop_name,1,prop_name_len); game_file_add_chunk(&prop_value_len,1,sizeof(int)); game_file_add_chunk(prop_value,1,prop_value_len); // free the property value JSON string free(prop_value); } JSPropertyNameArrayRelease(js_names); // end each block with a 0 prop name length prop_name_len=0; game_file_add_chunk(&prop_name_len,1,sizeof(int)); return(TRUE); }
int main(int argc, char* argv[]) { const char *scriptPath = "testapi.js"; if (argc > 1) { scriptPath = argv[1]; } // Test garbage collection with a fresh context context = JSGlobalContextCreateInGroup(NULL, NULL); TestInitializeFinalize = true; testInitializeFinalize(); JSGlobalContextRelease(context); TestInitializeFinalize = false; ASSERT(Base_didFinalize); JSClassDefinition globalObjectClassDefinition = kJSClassDefinitionEmpty; globalObjectClassDefinition.initialize = globalObject_initialize; globalObjectClassDefinition.staticValues = globalObject_staticValues; globalObjectClassDefinition.staticFunctions = globalObject_staticFunctions; globalObjectClassDefinition.attributes = kJSClassAttributeNoAutomaticPrototype; JSClassRef globalObjectClass = JSClassCreate(&globalObjectClassDefinition); context = JSGlobalContextCreateInGroup(NULL, globalObjectClass); JSGlobalContextRetain(context); JSGlobalContextRelease(context); JSObjectRef globalObject = JSContextGetGlobalObject(context); ASSERT(JSValueIsObject(context, globalObject)); JSValueRef jsUndefined = JSValueMakeUndefined(context); JSValueRef jsNull = JSValueMakeNull(context); JSValueRef jsTrue = JSValueMakeBoolean(context, true); JSValueRef jsFalse = JSValueMakeBoolean(context, false); JSValueRef jsZero = JSValueMakeNumber(context, 0); JSValueRef jsOne = JSValueMakeNumber(context, 1); JSValueRef jsOneThird = JSValueMakeNumber(context, 1.0 / 3.0); JSObjectRef jsObjectNoProto = JSObjectMake(context, NULL, NULL); JSObjectSetPrototype(context, jsObjectNoProto, JSValueMakeNull(context)); // FIXME: test funny utf8 characters JSStringRef jsEmptyIString = JSStringCreateWithUTF8CString(""); JSValueRef jsEmptyString = JSValueMakeString(context, jsEmptyIString); JSStringRef jsOneIString = JSStringCreateWithUTF8CString("1"); JSValueRef jsOneString = JSValueMakeString(context, jsOneIString); UniChar singleUniChar = 65; // Capital A CFMutableStringRef cfString = CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorDefault, &singleUniChar, 1, 1, kCFAllocatorNull); JSStringRef jsCFIString = JSStringCreateWithCFString(cfString); JSValueRef jsCFString = JSValueMakeString(context, jsCFIString); CFStringRef cfEmptyString = CFStringCreateWithCString(kCFAllocatorDefault, "", kCFStringEncodingUTF8); JSStringRef jsCFEmptyIString = JSStringCreateWithCFString(cfEmptyString); JSValueRef jsCFEmptyString = JSValueMakeString(context, jsCFEmptyIString); CFIndex cfStringLength = CFStringGetLength(cfString); UniChar* buffer = (UniChar*)malloc(cfStringLength * sizeof(UniChar)); CFStringGetCharacters(cfString, CFRangeMake(0, cfStringLength), buffer); JSStringRef jsCFIStringWithCharacters = JSStringCreateWithCharacters((JSChar*)buffer, cfStringLength); JSValueRef jsCFStringWithCharacters = JSValueMakeString(context, jsCFIStringWithCharacters); JSStringRef jsCFEmptyIStringWithCharacters = JSStringCreateWithCharacters((JSChar*)buffer, CFStringGetLength(cfEmptyString)); free(buffer); JSValueRef jsCFEmptyStringWithCharacters = JSValueMakeString(context, jsCFEmptyIStringWithCharacters); ASSERT(JSValueGetType(context, jsUndefined) == kJSTypeUndefined); ASSERT(JSValueGetType(context, jsNull) == kJSTypeNull); ASSERT(JSValueGetType(context, jsTrue) == kJSTypeBoolean); ASSERT(JSValueGetType(context, jsFalse) == kJSTypeBoolean); ASSERT(JSValueGetType(context, jsZero) == kJSTypeNumber); ASSERT(JSValueGetType(context, jsOne) == kJSTypeNumber); ASSERT(JSValueGetType(context, jsOneThird) == kJSTypeNumber); ASSERT(JSValueGetType(context, jsEmptyString) == kJSTypeString); ASSERT(JSValueGetType(context, jsOneString) == kJSTypeString); ASSERT(JSValueGetType(context, jsCFString) == kJSTypeString); ASSERT(JSValueGetType(context, jsCFStringWithCharacters) == kJSTypeString); ASSERT(JSValueGetType(context, jsCFEmptyString) == kJSTypeString); ASSERT(JSValueGetType(context, jsCFEmptyStringWithCharacters) == kJSTypeString); JSObjectRef myObject = JSObjectMake(context, MyObject_class(context), NULL); JSStringRef myObjectIString = JSStringCreateWithUTF8CString("MyObject"); JSObjectSetProperty(context, globalObject, myObjectIString, myObject, kJSPropertyAttributeNone, NULL); JSStringRelease(myObjectIString); JSValueRef exception; // Conversions that throw exceptions exception = NULL; ASSERT(NULL == JSValueToObject(context, jsNull, &exception)); ASSERT(exception); exception = NULL; // FIXME <rdar://4668451> - On i386 the isnan(double) macro tries to map to the isnan(float) function, // causing a build break with -Wshorten-64-to-32 enabled. The issue is known by the appropriate team. // After that's resolved, we can remove these casts ASSERT(isnan((float)JSValueToNumber(context, jsObjectNoProto, &exception))); ASSERT(exception); exception = NULL; ASSERT(!JSValueToStringCopy(context, jsObjectNoProto, &exception)); ASSERT(exception); ASSERT(JSValueToBoolean(context, myObject)); exception = NULL; ASSERT(!JSValueIsEqual(context, jsObjectNoProto, JSValueMakeNumber(context, 1), &exception)); ASSERT(exception); exception = NULL; JSObjectGetPropertyAtIndex(context, myObject, 0, &exception); ASSERT(1 == JSValueToNumber(context, exception, NULL)); assertEqualsAsBoolean(jsUndefined, false); assertEqualsAsBoolean(jsNull, false); assertEqualsAsBoolean(jsTrue, true); assertEqualsAsBoolean(jsFalse, false); assertEqualsAsBoolean(jsZero, false); assertEqualsAsBoolean(jsOne, true); assertEqualsAsBoolean(jsOneThird, true); assertEqualsAsBoolean(jsEmptyString, false); assertEqualsAsBoolean(jsOneString, true); assertEqualsAsBoolean(jsCFString, true); assertEqualsAsBoolean(jsCFStringWithCharacters, true); assertEqualsAsBoolean(jsCFEmptyString, false); assertEqualsAsBoolean(jsCFEmptyStringWithCharacters, false); assertEqualsAsNumber(jsUndefined, nan("")); assertEqualsAsNumber(jsNull, 0); assertEqualsAsNumber(jsTrue, 1); assertEqualsAsNumber(jsFalse, 0); assertEqualsAsNumber(jsZero, 0); assertEqualsAsNumber(jsOne, 1); assertEqualsAsNumber(jsOneThird, 1.0 / 3.0); assertEqualsAsNumber(jsEmptyString, 0); assertEqualsAsNumber(jsOneString, 1); assertEqualsAsNumber(jsCFString, nan("")); assertEqualsAsNumber(jsCFStringWithCharacters, nan("")); assertEqualsAsNumber(jsCFEmptyString, 0); assertEqualsAsNumber(jsCFEmptyStringWithCharacters, 0); ASSERT(sizeof(JSChar) == sizeof(UniChar)); assertEqualsAsCharactersPtr(jsUndefined, "undefined"); assertEqualsAsCharactersPtr(jsNull, "null"); assertEqualsAsCharactersPtr(jsTrue, "true"); assertEqualsAsCharactersPtr(jsFalse, "false"); assertEqualsAsCharactersPtr(jsZero, "0"); assertEqualsAsCharactersPtr(jsOne, "1"); assertEqualsAsCharactersPtr(jsOneThird, "0.3333333333333333"); assertEqualsAsCharactersPtr(jsEmptyString, ""); assertEqualsAsCharactersPtr(jsOneString, "1"); assertEqualsAsCharactersPtr(jsCFString, "A"); assertEqualsAsCharactersPtr(jsCFStringWithCharacters, "A"); assertEqualsAsCharactersPtr(jsCFEmptyString, ""); assertEqualsAsCharactersPtr(jsCFEmptyStringWithCharacters, ""); assertEqualsAsUTF8String(jsUndefined, "undefined"); assertEqualsAsUTF8String(jsNull, "null"); assertEqualsAsUTF8String(jsTrue, "true"); assertEqualsAsUTF8String(jsFalse, "false"); assertEqualsAsUTF8String(jsZero, "0"); assertEqualsAsUTF8String(jsOne, "1"); assertEqualsAsUTF8String(jsOneThird, "0.3333333333333333"); assertEqualsAsUTF8String(jsEmptyString, ""); assertEqualsAsUTF8String(jsOneString, "1"); assertEqualsAsUTF8String(jsCFString, "A"); assertEqualsAsUTF8String(jsCFStringWithCharacters, "A"); assertEqualsAsUTF8String(jsCFEmptyString, ""); assertEqualsAsUTF8String(jsCFEmptyStringWithCharacters, ""); ASSERT(JSValueIsStrictEqual(context, jsTrue, jsTrue)); ASSERT(!JSValueIsStrictEqual(context, jsOne, jsOneString)); ASSERT(JSValueIsEqual(context, jsOne, jsOneString, NULL)); ASSERT(!JSValueIsEqual(context, jsTrue, jsFalse, NULL)); CFStringRef cfJSString = JSStringCopyCFString(kCFAllocatorDefault, jsCFIString); CFStringRef cfJSEmptyString = JSStringCopyCFString(kCFAllocatorDefault, jsCFEmptyIString); ASSERT(CFEqual(cfJSString, cfString)); ASSERT(CFEqual(cfJSEmptyString, cfEmptyString)); CFRelease(cfJSString); CFRelease(cfJSEmptyString); CFRelease(cfString); CFRelease(cfEmptyString); jsGlobalValue = JSObjectMake(context, NULL, NULL); JSValueProtect(context, jsGlobalValue); JSGarbageCollect(context); ASSERT(JSValueIsObject(context, jsGlobalValue)); JSValueUnprotect(context, jsGlobalValue); JSStringRef goodSyntax = JSStringCreateWithUTF8CString("x = 1;"); JSStringRef badSyntax = JSStringCreateWithUTF8CString("x := 1;"); ASSERT(JSCheckScriptSyntax(context, goodSyntax, NULL, 0, NULL)); ASSERT(!JSCheckScriptSyntax(context, badSyntax, NULL, 0, NULL)); JSValueRef result; JSValueRef v; JSObjectRef o; JSStringRef string; result = JSEvaluateScript(context, goodSyntax, NULL, NULL, 1, NULL); ASSERT(result); ASSERT(JSValueIsEqual(context, result, jsOne, NULL)); exception = NULL; result = JSEvaluateScript(context, badSyntax, NULL, NULL, 1, &exception); ASSERT(!result); ASSERT(JSValueIsObject(context, exception)); JSStringRef array = JSStringCreateWithUTF8CString("Array"); JSObjectRef arrayConstructor = JSValueToObject(context, JSObjectGetProperty(context, globalObject, array, NULL), NULL); JSStringRelease(array); result = JSObjectCallAsConstructor(context, arrayConstructor, 0, NULL, NULL); ASSERT(result); ASSERT(JSValueIsObject(context, result)); ASSERT(JSValueIsInstanceOfConstructor(context, result, arrayConstructor, NULL)); ASSERT(!JSValueIsInstanceOfConstructor(context, JSValueMakeNull(context), arrayConstructor, NULL)); o = JSValueToObject(context, result, NULL); exception = NULL; ASSERT(JSValueIsUndefined(context, JSObjectGetPropertyAtIndex(context, o, 0, &exception))); ASSERT(!exception); JSObjectSetPropertyAtIndex(context, o, 0, JSValueMakeNumber(context, 1), &exception); ASSERT(!exception); exception = NULL; ASSERT(1 == JSValueToNumber(context, JSObjectGetPropertyAtIndex(context, o, 0, &exception), &exception)); ASSERT(!exception); JSStringRef functionBody; JSObjectRef function; exception = NULL; functionBody = JSStringCreateWithUTF8CString("rreturn Array;"); JSStringRef line = JSStringCreateWithUTF8CString("line"); ASSERT(!JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, &exception)); ASSERT(JSValueIsObject(context, exception)); v = JSObjectGetProperty(context, JSValueToObject(context, exception, NULL), line, NULL); assertEqualsAsNumber(v, 1); JSStringRelease(functionBody); JSStringRelease(line); exception = NULL; functionBody = JSStringCreateWithUTF8CString("return Array;"); function = JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, &exception); JSStringRelease(functionBody); ASSERT(!exception); ASSERT(JSObjectIsFunction(context, function)); v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL); ASSERT(v); ASSERT(JSValueIsEqual(context, v, arrayConstructor, NULL)); exception = NULL; function = JSObjectMakeFunction(context, NULL, 0, NULL, jsEmptyIString, NULL, 0, &exception); ASSERT(!exception); v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, &exception); ASSERT(v && !exception); ASSERT(JSValueIsUndefined(context, v)); exception = NULL; v = NULL; JSStringRef foo = JSStringCreateWithUTF8CString("foo"); JSStringRef argumentNames[] = { foo }; functionBody = JSStringCreateWithUTF8CString("return foo;"); function = JSObjectMakeFunction(context, foo, 1, argumentNames, functionBody, NULL, 1, &exception); ASSERT(function && !exception); JSValueRef arguments[] = { JSValueMakeNumber(context, 2) }; v = JSObjectCallAsFunction(context, function, NULL, 1, arguments, &exception); JSStringRelease(foo); JSStringRelease(functionBody); string = JSValueToStringCopy(context, function, NULL); assertEqualsAsUTF8String(JSValueMakeString(context, string), "function foo(foo) {return foo;}"); JSStringRelease(string); JSStringRef print = JSStringCreateWithUTF8CString("print"); JSObjectRef printFunction = JSObjectMakeFunctionWithCallback(context, print, print_callAsFunction); JSObjectSetProperty(context, globalObject, print, printFunction, kJSPropertyAttributeNone, NULL); JSStringRelease(print); ASSERT(!JSObjectSetPrivate(printFunction, (void*)1)); ASSERT(!JSObjectGetPrivate(printFunction)); JSStringRef myConstructorIString = JSStringCreateWithUTF8CString("MyConstructor"); JSObjectRef myConstructor = JSObjectMakeConstructor(context, NULL, myConstructor_callAsConstructor); JSObjectSetProperty(context, globalObject, myConstructorIString, myConstructor, kJSPropertyAttributeNone, NULL); JSStringRelease(myConstructorIString); ASSERT(!JSObjectSetPrivate(myConstructor, (void*)1)); ASSERT(!JSObjectGetPrivate(myConstructor)); string = JSStringCreateWithUTF8CString("Derived"); JSObjectRef derivedConstructor = JSObjectMakeConstructor(context, Derived_class(context), NULL); JSObjectSetProperty(context, globalObject, string, derivedConstructor, kJSPropertyAttributeNone, NULL); JSStringRelease(string); o = JSObjectMake(context, NULL, NULL); JSObjectSetProperty(context, o, jsOneIString, JSValueMakeNumber(context, 1), kJSPropertyAttributeNone, NULL); JSObjectSetProperty(context, o, jsCFIString, JSValueMakeNumber(context, 1), kJSPropertyAttributeDontEnum, NULL); JSPropertyNameArrayRef nameArray = JSObjectCopyPropertyNames(context, o); size_t expectedCount = JSPropertyNameArrayGetCount(nameArray); size_t count; for (count = 0; count < expectedCount; ++count) JSPropertyNameArrayGetNameAtIndex(nameArray, count); JSPropertyNameArrayRelease(nameArray); ASSERT(count == 1); // jsCFString should not be enumerated JSClassDefinition nullDefinition = kJSClassDefinitionEmpty; nullDefinition.attributes = kJSClassAttributeNoAutomaticPrototype; JSClassRef nullClass = JSClassCreate(&nullDefinition); JSClassRelease(nullClass); nullDefinition = kJSClassDefinitionEmpty; nullClass = JSClassCreate(&nullDefinition); JSClassRelease(nullClass); functionBody = JSStringCreateWithUTF8CString("return this;"); function = JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, NULL); JSStringRelease(functionBody); v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL); ASSERT(JSValueIsEqual(context, v, globalObject, NULL)); v = JSObjectCallAsFunction(context, function, o, 0, NULL, NULL); ASSERT(JSValueIsEqual(context, v, o, NULL)); functionBody = JSStringCreateWithUTF8CString("return eval(\"this\");"); function = JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, NULL); JSStringRelease(functionBody); v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL); ASSERT(JSValueIsEqual(context, v, globalObject, NULL)); v = JSObjectCallAsFunction(context, function, o, 0, NULL, NULL); ASSERT(JSValueIsEqual(context, v, o, NULL)); JSStringRef script = JSStringCreateWithUTF8CString("this;"); v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL); ASSERT(JSValueIsEqual(context, v, globalObject, NULL)); v = JSEvaluateScript(context, script, o, NULL, 1, NULL); ASSERT(JSValueIsEqual(context, v, o, NULL)); JSStringRelease(script); script = JSStringCreateWithUTF8CString("eval(this);"); v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL); ASSERT(JSValueIsEqual(context, v, globalObject, NULL)); v = JSEvaluateScript(context, script, o, NULL, 1, NULL); ASSERT(JSValueIsEqual(context, v, o, NULL)); JSStringRelease(script); char* scriptUTF8 = createStringWithContentsOfFile(scriptPath); if (!scriptUTF8) printf("FAIL: Test script could not be loaded.\n"); else { script = JSStringCreateWithUTF8CString(scriptUTF8); result = JSEvaluateScript(context, script, NULL, NULL, 1, &exception); if (JSValueIsUndefined(context, result)) printf("PASS: Test script executed successfully.\n"); else { printf("FAIL: Test script returned unexpected value:\n"); JSStringRef exceptionIString = JSValueToStringCopy(context, exception, NULL); CFStringRef exceptionCF = JSStringCopyCFString(kCFAllocatorDefault, exceptionIString); CFShow(exceptionCF); CFRelease(exceptionCF); JSStringRelease(exceptionIString); } JSStringRelease(script); free(scriptUTF8); } // Clear out local variables pointing at JSObjectRefs to allow their values to be collected function = NULL; v = NULL; o = NULL; globalObject = NULL; JSStringRelease(jsEmptyIString); JSStringRelease(jsOneIString); JSStringRelease(jsCFIString); JSStringRelease(jsCFEmptyIString); JSStringRelease(jsCFIStringWithCharacters); JSStringRelease(jsCFEmptyIStringWithCharacters); JSStringRelease(goodSyntax); JSStringRelease(badSyntax); JSGlobalContextRelease(context); JSClassRelease(globalObjectClass); printf("PASS: Program exited normally.\n"); return 0; }
bool JSValue::IsFunction() const { if (!IsObject()) return false; JSObjectRef obj = JSValueToObject(ctx_, instance(), nullptr); return JSObjectIsFunction(ctx_, obj); }
bool JSFunction::IsValid() const { return !!instance_ && JSObjectIsFunction(ctx_, instance_); }