📄 testapi.c
字号:
{ UNUSED_PARAM(context); if (TestInitializeFinalize) { ASSERT((void*)1 == JSObjectGetPrivate(object)); JSObjectSetPrivate(object, (void*)2); }}static unsigned Base_didFinalize;static void Base_finalize(JSObjectRef object){ UNUSED_PARAM(object); if (TestInitializeFinalize) { ASSERT((void*)4 == JSObjectGetPrivate(object)); Base_didFinalize = true; }}static JSClassRef Base_class(JSContextRef context){ UNUSED_PARAM(context); static JSClassRef jsClass; if (!jsClass) { JSClassDefinition definition = kJSClassDefinitionEmpty; definition.staticValues = Base_staticValues; definition.staticFunctions = Base_staticFunctions; definition.initialize = Base_initialize; definition.finalize = Base_finalize; jsClass = JSClassCreate(&definition); } return jsClass;}static JSValueRef Derived_get(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception){ UNUSED_PARAM(object); UNUSED_PARAM(propertyName); UNUSED_PARAM(exception); return JSValueMakeNumber(ctx, 2); // distinguish base get form derived get}static bool Derived_set(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception){ UNUSED_PARAM(ctx); UNUSED_PARAM(object); UNUSED_PARAM(propertyName); UNUSED_PARAM(value); *exception = JSValueMakeNumber(ctx, 2); // distinguish base set from derived set return true;}static JSValueRef Derived_callAsFunction(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ UNUSED_PARAM(function); UNUSED_PARAM(thisObject); UNUSED_PARAM(argumentCount); UNUSED_PARAM(arguments); UNUSED_PARAM(exception); return JSValueMakeNumber(ctx, 2); // distinguish base call from derived call}static JSStaticFunction Derived_staticFunctions[] = { { "protoOnly", Derived_callAsFunction, kJSPropertyAttributeNone }, { "protoDup", NULL, kJSPropertyAttributeNone }, { "baseProtoDup", Derived_callAsFunction, kJSPropertyAttributeNone }, { 0, 0, 0 }};static JSStaticValue Derived_staticValues[] = { { "derivedOnly", Derived_get, Derived_set, kJSPropertyAttributeNone }, { "protoDup", Derived_get, Derived_set, kJSPropertyAttributeNone }, { "baseDup", Derived_get, Derived_set, kJSPropertyAttributeNone }, { 0, 0, 0, 0 }};static void Derived_initialize(JSContextRef context, JSObjectRef object){ UNUSED_PARAM(context); if (TestInitializeFinalize) { ASSERT((void*)2 == JSObjectGetPrivate(object)); JSObjectSetPrivate(object, (void*)3); }}static void Derived_finalize(JSObjectRef object){ if (TestInitializeFinalize) { ASSERT((void*)3 == JSObjectGetPrivate(object)); JSObjectSetPrivate(object, (void*)4); }}static JSClassRef Derived_class(JSContextRef context){ static JSClassRef jsClass; if (!jsClass) { JSClassDefinition definition = kJSClassDefinitionEmpty; definition.parentClass = Base_class(context); definition.staticValues = Derived_staticValues; definition.staticFunctions = Derived_staticFunctions; definition.initialize = Derived_initialize; definition.finalize = Derived_finalize; jsClass = JSClassCreate(&definition); } return jsClass;}static JSValueRef print_callAsFunction(JSContextRef context, JSObjectRef functionObject, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ UNUSED_PARAM(functionObject); UNUSED_PARAM(thisObject); UNUSED_PARAM(exception); if (argumentCount > 0) { JSStringRef string = JSValueToStringCopy(context, arguments[0], NULL); size_t sizeUTF8 = JSStringGetMaximumUTF8CStringSize(string); char* stringUTF8 = (char*)malloc(sizeUTF8); JSStringGetUTF8CString(string, stringUTF8, sizeUTF8); printf("%s\n", stringUTF8); free(stringUTF8); JSStringRelease(string); } return JSValueMakeUndefined(context);}static JSObjectRef myConstructor_callAsConstructor(JSContextRef context, JSObjectRef constructorObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ UNUSED_PARAM(constructorObject); UNUSED_PARAM(exception); JSObjectRef result = JSObjectMake(context, NULL, NULL); if (argumentCount > 0) { JSStringRef value = JSStringCreateWithUTF8CString("value"); JSObjectSetProperty(context, result, value, arguments[0], kJSPropertyAttributeNone, NULL); JSStringRelease(value); } return result;}static void globalObject_initialize(JSContextRef context, JSObjectRef object){ UNUSED_PARAM(object); // Ensure that an execution context is passed in ASSERT(context); // Ensure that the global object is set to the object that we were passed JSObjectRef globalObject = JSContextGetGlobalObject(context); ASSERT(globalObject); ASSERT(object == globalObject); // Ensure that the standard global properties have been set on the global object JSStringRef array = JSStringCreateWithUTF8CString("Array"); JSObjectRef arrayConstructor = JSValueToObject(context, JSObjectGetProperty(context, globalObject, array, NULL), NULL); JSStringRelease(array); UNUSED_PARAM(arrayConstructor); ASSERT(arrayConstructor);}static JSValueRef globalObject_get(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception){ UNUSED_PARAM(object); UNUSED_PARAM(propertyName); UNUSED_PARAM(exception); return JSValueMakeNumber(ctx, 3);}static bool globalObject_set(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception){ UNUSED_PARAM(object); UNUSED_PARAM(propertyName); UNUSED_PARAM(value); *exception = JSValueMakeNumber(ctx, 3); return true;}static JSValueRef globalObject_call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ UNUSED_PARAM(function); UNUSED_PARAM(thisObject); UNUSED_PARAM(argumentCount); UNUSED_PARAM(arguments); UNUSED_PARAM(exception); return JSValueMakeNumber(ctx, 3);}static JSStaticValue globalObject_staticValues[] = { { "globalStaticValue", globalObject_get, globalObject_set, kJSPropertyAttributeNone }, { 0, 0, 0, 0 }};static JSStaticFunction globalObject_staticFunctions[] = { { "globalStaticFunction", globalObject_call, kJSPropertyAttributeNone }, { 0, 0, 0 }};static char* createStringWithContentsOfFile(const char* fileName);static void testInitializeFinalize(){ JSObjectRef o = JSObjectMake(context, Derived_class(context), (void*)1); UNUSED_PARAM(o); ASSERT(JSObjectGetPrivate(o) == (void*)3);}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); JSReportExtraMemoryCost(context, 0); JSReportExtraMemoryCost(context, 1); JSReportExtraMemoryCost(context, 1024); 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));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -