📄 testapi.c
字号:
/* * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "JavaScriptCore.h"#include "JSBasePrivate.h"#include <math.h>#include <wtf/Assertions.h>#include <wtf/UnusedParam.h>#if COMPILER(MSVC)#include <wtf/MathExtras.h>static double nan(const char*){ return std::numeric_limits<double>::quiet_NaN();}#endifstatic JSGlobalContextRef context = 0;static void assertEqualsAsBoolean(JSValueRef value, bool expectedValue){ if (JSValueToBoolean(context, value) != expectedValue) fprintf(stderr, "assertEqualsAsBoolean failed: %p, %d\n", value, expectedValue);}static void assertEqualsAsNumber(JSValueRef value, double expectedValue){ double number = JSValueToNumber(context, value, 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 if (number != expectedValue && !(isnan((float)number) && isnan((float)expectedValue))) fprintf(stderr, "assertEqualsAsNumber failed: %p, %lf\n", value, expectedValue);}static void assertEqualsAsUTF8String(JSValueRef value, const char* expectedValue){ JSStringRef valueAsString = JSValueToStringCopy(context, value, NULL); size_t jsSize = JSStringGetMaximumUTF8CStringSize(valueAsString); char* jsBuffer = (char*)malloc(jsSize); JSStringGetUTF8CString(valueAsString, jsBuffer, jsSize); unsigned i; for (i = 0; jsBuffer[i]; i++) if (jsBuffer[i] != expectedValue[i]) fprintf(stderr, "assertEqualsAsUTF8String failed at character %d: %c(%d) != %c(%d)\n", i, jsBuffer[i], jsBuffer[i], expectedValue[i], expectedValue[i]); if (jsSize < strlen(jsBuffer) + 1) fprintf(stderr, "assertEqualsAsUTF8String failed: jsSize was too small\n"); free(jsBuffer); JSStringRelease(valueAsString);}static void assertEqualsAsCharactersPtr(JSValueRef value, const char* expectedValue){ JSStringRef valueAsString = JSValueToStringCopy(context, value, NULL); size_t jsLength = JSStringGetLength(valueAsString); const JSChar* jsBuffer = JSStringGetCharactersPtr(valueAsString); CFStringRef expectedValueAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, expectedValue, kCFStringEncodingUTF8); CFIndex cfLength = CFStringGetLength(expectedValueAsCFString); UniChar* cfBuffer = (UniChar*)malloc(cfLength * sizeof(UniChar)); CFStringGetCharacters(expectedValueAsCFString, CFRangeMake(0, cfLength), cfBuffer); CFRelease(expectedValueAsCFString); if (memcmp(jsBuffer, cfBuffer, cfLength * sizeof(UniChar)) != 0) fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsBuffer != cfBuffer\n"); if (jsLength != (size_t)cfLength) fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsLength(%ld) != cfLength(%ld)\n", jsLength, cfLength); free(cfBuffer); JSStringRelease(valueAsString);}static JSValueRef jsGlobalValue; // non-stack value for testing JSValueProtect()/* MyObject pseudo-class */static bool MyObject_hasProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName){ UNUSED_PARAM(context); UNUSED_PARAM(object); if (JSStringIsEqualToUTF8CString(propertyName, "alwaysOne") || JSStringIsEqualToUTF8CString(propertyName, "cantFind") || JSStringIsEqualToUTF8CString(propertyName, "myPropertyName") || JSStringIsEqualToUTF8CString(propertyName, "hasPropertyLie") || JSStringIsEqualToUTF8CString(propertyName, "0")) { return true; } return false;}static JSValueRef MyObject_getProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception){ UNUSED_PARAM(context); UNUSED_PARAM(object); if (JSStringIsEqualToUTF8CString(propertyName, "alwaysOne")) { return JSValueMakeNumber(context, 1); } if (JSStringIsEqualToUTF8CString(propertyName, "myPropertyName")) { return JSValueMakeNumber(context, 1); } if (JSStringIsEqualToUTF8CString(propertyName, "cantFind")) { return JSValueMakeUndefined(context); } if (JSStringIsEqualToUTF8CString(propertyName, "0")) { *exception = JSValueMakeNumber(context, 1); return JSValueMakeNumber(context, 1); } return NULL;}static bool MyObject_setProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception){ UNUSED_PARAM(context); UNUSED_PARAM(object); UNUSED_PARAM(value); UNUSED_PARAM(exception); if (JSStringIsEqualToUTF8CString(propertyName, "cantSet")) return true; // pretend we set the property in order to swallow it return false;}static bool MyObject_deleteProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception){ UNUSED_PARAM(context); UNUSED_PARAM(object); if (JSStringIsEqualToUTF8CString(propertyName, "cantDelete")) return true; if (JSStringIsEqualToUTF8CString(propertyName, "throwOnDelete")) { *exception = JSValueMakeNumber(context, 2); return false; } return false;}static void MyObject_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames){ UNUSED_PARAM(context); UNUSED_PARAM(object); JSStringRef propertyName; propertyName = JSStringCreateWithUTF8CString("alwaysOne"); JSPropertyNameAccumulatorAddName(propertyNames, propertyName); JSStringRelease(propertyName); propertyName = JSStringCreateWithUTF8CString("myPropertyName"); JSPropertyNameAccumulatorAddName(propertyNames, propertyName); JSStringRelease(propertyName);}static JSValueRef MyObject_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ UNUSED_PARAM(context); UNUSED_PARAM(object); UNUSED_PARAM(thisObject); UNUSED_PARAM(exception); if (argumentCount > 0 && JSValueIsStrictEqual(context, arguments[0], JSValueMakeNumber(context, 0))) return JSValueMakeNumber(context, 1); return JSValueMakeUndefined(context);}static JSObjectRef MyObject_callAsConstructor(JSContextRef context, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ UNUSED_PARAM(context); UNUSED_PARAM(object); if (argumentCount > 0 && JSValueIsStrictEqual(context, arguments[0], JSValueMakeNumber(context, 0))) return JSValueToObject(context, JSValueMakeNumber(context, 1), exception); return JSValueToObject(context, JSValueMakeNumber(context, 0), exception);}static bool MyObject_hasInstance(JSContextRef context, JSObjectRef constructor, JSValueRef possibleValue, JSValueRef* exception){ UNUSED_PARAM(context); UNUSED_PARAM(constructor); JSStringRef numberString = JSStringCreateWithUTF8CString("Number"); JSObjectRef numberConstructor = JSValueToObject(context, JSObjectGetProperty(context, JSContextGetGlobalObject(context), numberString, exception), exception); JSStringRelease(numberString); return JSValueIsInstanceOfConstructor(context, possibleValue, numberConstructor, exception);}static JSValueRef MyObject_convertToType(JSContextRef context, JSObjectRef object, JSType type, JSValueRef* exception){ UNUSED_PARAM(object); UNUSED_PARAM(exception); switch (type) { case kJSTypeNumber: return JSValueMakeNumber(context, 1); case kJSTypeString: { JSStringRef string = JSStringCreateWithUTF8CString("MyObjectAsString"); JSValueRef result = JSValueMakeString(context, string); JSStringRelease(string); return result; } default: break; } // string conversion -- forward to default object class return NULL;}static JSStaticValue evilStaticValues[] = { { "nullGetSet", 0, 0, kJSPropertyAttributeNone }, { 0, 0, 0, 0 }};static JSStaticFunction evilStaticFunctions[] = { { "nullCall", 0, kJSPropertyAttributeNone }, { 0, 0, 0 }};JSClassDefinition MyObject_definition = { 0, kJSClassAttributeNone, "MyObject", NULL, evilStaticValues, evilStaticFunctions, NULL, NULL, MyObject_hasProperty, MyObject_getProperty, MyObject_setProperty, MyObject_deleteProperty, MyObject_getPropertyNames, MyObject_callAsFunction, MyObject_callAsConstructor, MyObject_hasInstance, MyObject_convertToType,};static JSClassRef MyObject_class(JSContextRef context){ UNUSED_PARAM(context); static JSClassRef jsClass; if (!jsClass) jsClass = JSClassCreate(&MyObject_definition); return jsClass;}static JSValueRef Base_get(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception){ UNUSED_PARAM(object); UNUSED_PARAM(propertyName); UNUSED_PARAM(exception); return JSValueMakeNumber(ctx, 1); // distinguish base get form derived get}static bool Base_set(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception){ UNUSED_PARAM(object); UNUSED_PARAM(propertyName); UNUSED_PARAM(value); *exception = JSValueMakeNumber(ctx, 1); // distinguish base set from derived set return true;}static JSValueRef Base_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, 1); // distinguish base call from derived call}static JSStaticFunction Base_staticFunctions[] = { { "baseProtoDup", NULL, kJSPropertyAttributeNone }, { "baseProto", Base_callAsFunction, kJSPropertyAttributeNone }, { 0, 0, 0 }};static JSStaticValue Base_staticValues[] = { { "baseDup", Base_get, Base_set, kJSPropertyAttributeNone }, { "baseOnly", Base_get, Base_set, kJSPropertyAttributeNone }, { 0, 0, 0, 0 }};static bool TestInitializeFinalize;static void Base_initialize(JSContextRef context, JSObjectRef object)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -