X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/12899fa232562c774004a3a9d7d3149944dec712..ed1e77d3adeb83d26fd1dfb16dd84cabdcefd250:/API/tests/testapi.c diff --git a/API/tests/testapi.c b/API/tests/testapi.c index 83c605c..fc4914b 100644 --- a/API/tests/testapi.c +++ b/API/tests/testapi.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2006, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,19 +10,21 @@ * 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 + * THIS SOFTWARE IS PROVIDED BY APPLE 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 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include + #include "JavaScriptCore.h" #include "JSBasePrivate.h" #include "JSContextRefPrivate.h" @@ -33,34 +35,23 @@ #define ASSERT_DISABLED 0 #include -#if PLATFORM(MAC) || PLATFORM(IOS) -#include -#include -#include -#endif - #if OS(WINDOWS) #include #endif -#if COMPILER(MSVC) - -#include - -static double nan(const char*) -{ - return std::numeric_limits::quiet_NaN(); -} - -using std::isinf; -using std::isnan; +#include "CompareAndSwapTest.h" +#include "CustomGlobalObjectClassTest.h" +#include "GlobalContextWithFinalizerTest.h" +#if OS(DARWIN) +#include "ExecutionTimeLimitTest.h" #endif #if JSC_OBJC_API_ENABLED void testObjectiveCAPI(void); #endif +bool assertTrue(bool value, const char* message); extern void JSSynchronousGarbageCollectForDebugging(JSContextRef); static JSGlobalContextRef context; @@ -93,11 +84,13 @@ static void assertEqualsAsUTF8String(JSValueRef value, const char* expectedValue 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]); + fprintf(stderr, "value: %s\n", jsBuffer); + fprintf(stderr, "expectedValue: %s\n", expectedValue); failed = 1; } } @@ -132,7 +125,11 @@ static void assertEqualsAsCharactersPtr(JSValueRef value, const char* expectedVa } if (jsLength != (size_t)cfLength) { - fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsLength(%ld) != cfLength(%ld)\n", jsLength, cfLength); +#if OS(WINDOWS) + fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsLength(%Iu) != cfLength(%Iu)\n", jsLength, (size_t)cfLength); +#else + fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsLength(%zu) != cfLength(%zu)\n", jsLength, (size_t)cfLength); +#endif failed = 1; } @@ -582,7 +579,6 @@ static JSValueRef EvilExceptionObject_convertToType(JSContextRef context, JSObje break; default: return JSValueMakeNull(context); - break; } JSValueRef func = JSObjectGetProperty(context, object, funcName, exception); @@ -904,10 +900,8 @@ static void globalObject_initialize(JSContextRef context, JSObjectRef 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"); @@ -966,6 +960,7 @@ static JSStaticValue globalObject_staticValues[] = { static JSStaticFunction globalObject_staticFunctions[] = { { "globalStaticFunction", globalObject_call, kJSPropertyAttributeNone }, + { "globalStaticFunction2", globalObject_call, kJSPropertyAttributeNone }, { "gc", functionGC, kJSPropertyAttributeNone }, { 0, 0, 0 } }; @@ -990,7 +985,7 @@ static void makeGlobalNumberValue(JSContextRef context) { v = NULL; } -static bool assertTrue(bool value, const char* message) +bool assertTrue(bool value, const char* message) { if (!value) { if (message) @@ -1043,85 +1038,104 @@ static bool checkForCycleInPrototypeChain() return result; } -static void checkConstnessInJSObjectNames() +static JSValueRef valueToObjectExceptionCallAsFunction(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { - JSStaticFunction fun; - fun.name = "something"; - JSStaticValue val; - val.name = "something"; + UNUSED_PARAM(function); + UNUSED_PARAM(thisObject); + UNUSED_PARAM(argumentCount); + UNUSED_PARAM(arguments); + JSValueRef jsUndefined = JSValueMakeUndefined(JSContextGetGlobalContext(ctx)); + JSValueToObject(JSContextGetGlobalContext(ctx), jsUndefined, exception); + + return JSValueMakeUndefined(ctx); } - -#if PLATFORM(MAC) || PLATFORM(IOS) -static double currentCPUTime() +static bool valueToObjectExceptionTest() { - mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT; - thread_basic_info_data_t info; + JSGlobalContextRef testContext; + JSClassDefinition globalObjectClassDefinition = kJSClassDefinitionEmpty; + globalObjectClassDefinition.initialize = globalObject_initialize; + globalObjectClassDefinition.staticValues = globalObject_staticValues; + globalObjectClassDefinition.staticFunctions = globalObject_staticFunctions; + globalObjectClassDefinition.attributes = kJSClassAttributeNoAutomaticPrototype; + JSClassRef globalObjectClass = JSClassCreate(&globalObjectClassDefinition); + testContext = JSGlobalContextCreateInGroup(NULL, globalObjectClass); + JSObjectRef globalObject = JSContextGetGlobalObject(testContext); + + JSStringRef valueToObject = JSStringCreateWithUTF8CString("valueToObject"); + JSObjectRef valueToObjectFunction = JSObjectMakeFunctionWithCallback(testContext, valueToObject, valueToObjectExceptionCallAsFunction); + JSObjectSetProperty(testContext, globalObject, valueToObject, valueToObjectFunction, kJSPropertyAttributeNone, NULL); + JSStringRelease(valueToObject); - /* Get thread information */ - mach_port_t threadPort = mach_thread_self(); - thread_info(threadPort, THREAD_BASIC_INFO, (thread_info_t)(&info), &infoCount); - mach_port_deallocate(mach_task_self(), threadPort); + JSStringRef test = JSStringCreateWithUTF8CString("valueToObject();"); + JSEvaluateScript(testContext, test, NULL, NULL, 1, NULL); - double time = info.user_time.seconds + info.user_time.microseconds / 1000000.; - time += info.system_time.seconds + info.system_time.microseconds / 1000000.; + JSStringRelease(test); + JSClassRelease(globalObjectClass); + JSGlobalContextRelease(testContext); - return time; + return true; } -static JSValueRef currentCPUTime_callAsFunction(JSContextRef ctx, JSObjectRef functionObject, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +static bool globalContextNameTest() { - UNUSED_PARAM(functionObject); - UNUSED_PARAM(thisObject); - UNUSED_PARAM(argumentCount); - UNUSED_PARAM(arguments); - UNUSED_PARAM(exception); + bool result = true; + JSGlobalContextRef context = JSGlobalContextCreate(0); - ASSERT(JSContextGetGlobalContext(ctx) == context); - return JSValueMakeNumber(ctx, currentCPUTime()); -} + JSStringRef str = JSGlobalContextCopyName(context); + result &= assertTrue(!str, "Default context name is NULL"); -bool shouldTerminateCallbackWasCalled = false; -static bool shouldTerminateCallback(JSContextRef ctx, void* context) -{ - UNUSED_PARAM(ctx); - UNUSED_PARAM(context); - shouldTerminateCallbackWasCalled = true; - return true; -} + JSStringRef name1 = JSStringCreateWithUTF8CString("name1"); + JSStringRef name2 = JSStringCreateWithUTF8CString("name2"); -bool cancelTerminateCallbackWasCalled = false; -static bool cancelTerminateCallback(JSContextRef ctx, void* context) -{ - UNUSED_PARAM(ctx); - UNUSED_PARAM(context); - cancelTerminateCallbackWasCalled = true; - return false; + JSGlobalContextSetName(context, name1); + JSStringRef fetchName1 = JSGlobalContextCopyName(context); + JSGlobalContextSetName(context, name2); + JSStringRef fetchName2 = JSGlobalContextCopyName(context); + JSGlobalContextSetName(context, NULL); + JSStringRef fetchName3 = JSGlobalContextCopyName(context); + + result &= assertTrue(JSStringIsEqual(name1, fetchName1), "Unexpected Context name"); + result &= assertTrue(JSStringIsEqual(name2, fetchName2), "Unexpected Context name"); + result &= assertTrue(!JSStringIsEqual(fetchName1, fetchName2), "Unexpected Context name"); + result &= assertTrue(!fetchName3, "Unexpected Context name"); + + JSStringRelease(name1); + JSStringRelease(name2); + JSStringRelease(fetchName1); + JSStringRelease(fetchName2); + + return result; } -int extendTerminateCallbackCalled = 0; -static bool extendTerminateCallback(JSContextRef ctx, void* context) +static void checkConstnessInJSObjectNames() { - UNUSED_PARAM(context); - extendTerminateCallbackCalled++; - if (extendTerminateCallbackCalled == 1) { - JSContextGroupRef contextGroup = JSContextGetGroup(ctx); - JSContextGroupSetExecutionTimeLimit(contextGroup, .200f, extendTerminateCallback, 0); - return false; - } - return true; + JSStaticFunction fun; + fun.name = "something"; + JSStaticValue val; + val.name = "something"; } -#endif /* PLATFORM(MAC) || PLATFORM(IOS) */ int main(int argc, char* argv[]) { #if OS(WINDOWS) +#if defined(_M_X64) || defined(__x86_64__) + // The VS2013 runtime has a bug where it mis-detects AVX-capable processors + // if the feature has been disabled in firmware. This causes us to crash + // in some of the math functions. For now, we disable those optimizations + // because Microsoft is not going to fix the problem in VS2013. + // FIXME: http://webkit.org/b/141449: Remove this workaround when we switch to VS2015+. + _set_FMA3_enable(0); +#endif + // Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for // testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the // error mode here to work around Cygwin's behavior. See . ::SetErrorMode(0); #endif + testCompareAndSwap(); + #if JSC_OBJC_API_ENABLED testObjectiveCAPI(); #endif @@ -1171,6 +1185,13 @@ int main(int argc, char* argv[]) JSObjectRef jsObjectNoProto = JSObjectMake(context, NULL, NULL); JSObjectSetPrototype(context, jsObjectNoProto, JSValueMakeNull(context)); + JSObjectSetPrivate(globalObject, (void*)123); + if (JSObjectGetPrivate(globalObject) != (void*)123) { + printf("FAIL: Didn't return private data when set by JSObjectSetPrivate().\n"); + failed = 1; + } else + printf("PASS: returned private data when set by JSObjectSetPrivate().\n"); + // FIXME: test funny utf8 characters JSStringRef jsEmptyIString = JSStringCreateWithUTF8CString(""); JSValueRef jsEmptyString = JSValueMakeString(context, jsEmptyIString); @@ -1228,6 +1249,8 @@ int main(int argc, char* argv[]) ASSERT(!JSValueIsBoolean(context, NULL)); ASSERT(!JSValueIsObject(context, NULL)); + ASSERT(!JSValueIsArray(context, NULL)); + ASSERT(!JSValueIsDate(context, NULL)); ASSERT(!JSValueIsString(context, NULL)); ASSERT(!JSValueIsNumber(context, NULL)); ASSERT(!JSValueIsUndefined(context, NULL)); @@ -1245,6 +1268,14 @@ int main(int argc, char* argv[]) } else printf("PASS: returned null when accessing character pointer of a null String.\n"); + JSStringRef emptyString = JSStringCreateWithCFString(CFSTR("")); + characters = JSStringGetCharactersPtr(emptyString); + if (!characters) { + printf("FAIL: Returned null when accessing character pointer of an empty String.\n"); + failed = 1; + } else + printf("PASS: returned empty when accessing character pointer of an empty String.\n"); + size_t length = JSStringGetLength(nullString); if (length) { printf("FAIL: Didn't return 0 length for null String.\n"); @@ -1253,6 +1284,14 @@ int main(int argc, char* argv[]) printf("PASS: returned 0 length for null String.\n"); JSStringRelease(nullString); + length = JSStringGetLength(emptyString); + if (length) { + printf("FAIL: Didn't return 0 length for empty String.\n"); + failed = 1; + } else + printf("PASS: returned 0 length for empty String.\n"); + JSStringRelease(emptyString); + JSObjectRef propertyCatchalls = JSObjectMake(context, PropertyCatchalls_class(context), NULL); JSStringRef propertyCatchallsString = JSStringCreateWithUTF8CString("PropertyCatchalls"); JSObjectSetProperty(context, globalObject, propertyCatchallsString, propertyCatchalls, kJSPropertyAttributeNone, NULL); @@ -1372,8 +1411,10 @@ int main(int argc, char* argv[]) } else printf("PASS: Correctly serialised with indent of 4.\n"); JSStringRelease(str); - JSStringRef src = JSStringCreateWithUTF8CString("({get a(){ throw '';}})"); - JSValueRef unstringifiableObj = JSEvaluateScript(context, src, NULL, NULL, 1, NULL); + + str = JSStringCreateWithUTF8CString("({get a(){ throw '';}})"); + JSValueRef unstringifiableObj = JSEvaluateScript(context, str, NULL, NULL, 1, NULL); + JSStringRelease(str); str = JSValueCreateJSONString(context, unstringifiableObj, 4, 0); if (str) { @@ -1556,7 +1597,27 @@ int main(int argc, char* argv[]) 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); + assertEqualsAsNumber(v, 2); + JSStringRelease(functionBody); + JSStringRelease(line); + + exception = NULL; + functionBody = JSStringCreateWithUTF8CString("rreturn Array;"); + line = JSStringCreateWithUTF8CString("line"); + ASSERT(!JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, -42, &exception)); + ASSERT(JSValueIsObject(context, exception)); + v = JSObjectGetProperty(context, JSValueToObject(context, exception, NULL), line, NULL); + assertEqualsAsNumber(v, 2); + JSStringRelease(functionBody); + JSStringRelease(line); + + exception = NULL; + functionBody = JSStringCreateWithUTF8CString("// Line one.\nrreturn Array;"); + 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, 3); JSStringRelease(functionBody); JSStringRelease(line); @@ -1590,7 +1651,7 @@ int main(int argc, char* argv[]) JSStringRelease(functionBody); string = JSValueToStringCopy(context, function, NULL); - assertEqualsAsUTF8String(JSValueMakeString(context, string), "function foo(foo) { return foo;\n}"); + assertEqualsAsUTF8String(JSValueMakeString(context, string), "function foo(foo) {\nreturn foo;\n}"); JSStringRelease(string); JSStringRef print = JSStringCreateWithUTF8CString("print"); @@ -1721,6 +1782,28 @@ int main(int argc, char* argv[]) ASSERT(JSValueIsEqual(context, v, o, NULL)); JSStringRelease(script); + script = JSStringCreateWithUTF8CString("[ ]"); + v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL); + ASSERT(JSValueIsArray(context, v)); + JSStringRelease(script); + + script = JSStringCreateWithUTF8CString("new Date"); + v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL); + ASSERT(JSValueIsDate(context, v)); + JSStringRelease(script); + + exception = NULL; + script = JSStringCreateWithUTF8CString("rreturn Array;"); + JSStringRef sourceURL = JSStringCreateWithUTF8CString("file:///foo/bar.js"); + JSStringRef sourceURLKey = JSStringCreateWithUTF8CString("sourceURL"); + JSEvaluateScript(context, script, NULL, sourceURL, 1, &exception); + ASSERT(exception); + v = JSObjectGetProperty(context, JSValueToObject(context, exception, NULL), sourceURLKey, NULL); + assertEqualsAsUTF8String(v, "file:///foo/bar.js"); + JSStringRelease(script); + JSStringRelease(sourceURL); + JSStringRelease(sourceURLKey); + // Verify that creating a constructor for a class with no static functions does not trigger // an assert inside putDirect or lead to a crash during GC. nullDefinition = kJSClassDefinitionEmpty; @@ -1749,6 +1832,7 @@ int main(int argc, char* argv[]) } JSStringRelease(script); + exception = NULL; result = scriptObject ? JSScriptEvaluate(context, scriptObject, 0, &exception) : 0; if (result && JSValueIsUndefined(context, result)) printf("PASS: Test script executed successfully.\n"); @@ -1765,158 +1849,32 @@ int main(int argc, char* argv[]) free(scriptUTF8); } -#if PLATFORM(MAC) || PLATFORM(IOS) - JSStringRef currentCPUTimeStr = JSStringCreateWithUTF8CString("currentCPUTime"); - JSObjectRef currentCPUTimeFunction = JSObjectMakeFunctionWithCallback(context, currentCPUTimeStr, currentCPUTime_callAsFunction); - JSObjectSetProperty(context, globalObject, currentCPUTimeStr, currentCPUTimeFunction, kJSPropertyAttributeNone, NULL); - JSStringRelease(currentCPUTimeStr); - - /* Test script timeout: */ - JSContextGroupSetExecutionTimeLimit(contextGroup, .10f, shouldTerminateCallback, 0); - { - const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } "; - JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript); - double startTime; - double endTime; - exception = NULL; - shouldTerminateCallbackWasCalled = false; - startTime = currentCPUTime(); - v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception); - endTime = currentCPUTime(); - - if (((endTime - startTime) < .150f) && shouldTerminateCallbackWasCalled) - printf("PASS: script timed out as expected.\n"); - else { - if (!((endTime - startTime) < .150f)) - printf("FAIL: script did not timed out as expected.\n"); - if (!shouldTerminateCallbackWasCalled) - printf("FAIL: script timeout callback was not called.\n"); - failed = true; - } - - if (!exception) { - printf("FAIL: TerminatedExecutionException was not thrown.\n"); - failed = true; - } - } - - /* Test the script timeout's TerminatedExecutionException should NOT be catchable: */ - JSContextGroupSetExecutionTimeLimit(contextGroup, 0.10f, shouldTerminateCallback, 0); + // Check Promise is not exposed. { - const char* loopForeverScript = "var startTime = currentCPUTime(); try { while (true) { if (currentCPUTime() - startTime > .150) break; } } catch(e) { }"; - JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript); - double startTime; - double endTime; - exception = NULL; - shouldTerminateCallbackWasCalled = false; - startTime = currentCPUTime(); - v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception); - endTime = currentCPUTime(); - - if (((endTime - startTime) >= .150f) || !shouldTerminateCallbackWasCalled) { - if (!((endTime - startTime) < .150f)) - printf("FAIL: script did not timed out as expected.\n"); - if (!shouldTerminateCallbackWasCalled) - printf("FAIL: script timeout callback was not called.\n"); - failed = true; - } - - if (exception) - printf("PASS: TerminatedExecutionException was not catchable as expected.\n"); - else { - printf("FAIL: TerminatedExecutionException was caught.\n"); - failed = true; - } - } - - /* Test script timeout with no callback: */ - JSContextGroupSetExecutionTimeLimit(contextGroup, .10f, 0, 0); - { - const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } "; - JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript); - double startTime; - double endTime; - exception = NULL; - startTime = currentCPUTime(); - v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception); - endTime = currentCPUTime(); - - if (((endTime - startTime) < .150f) && shouldTerminateCallbackWasCalled) - printf("PASS: script timed out as expected when no callback is specified.\n"); - else { - if (!((endTime - startTime) < .150f)) - printf("FAIL: script did not timed out as expected when no callback is specified.\n"); - failed = true; - } - - if (!exception) { - printf("FAIL: TerminatedExecutionException was not thrown.\n"); - failed = true; - } - } - - /* Test script timeout cancellation: */ - JSContextGroupSetExecutionTimeLimit(contextGroup, 0.10f, cancelTerminateCallback, 0); - { - const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } "; - JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript); - double startTime; - double endTime; - exception = NULL; - startTime = currentCPUTime(); - v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception); - endTime = currentCPUTime(); - - if (((endTime - startTime) >= .150f) && cancelTerminateCallbackWasCalled && !exception) - printf("PASS: script timeout was cancelled as expected.\n"); - else { - if (((endTime - startTime) < .150) || exception) - printf("FAIL: script timeout was not cancelled.\n"); - if (!cancelTerminateCallbackWasCalled) - printf("FAIL: script timeout callback was not called.\n"); - failed = true; + JSObjectRef globalObject = JSContextGetGlobalObject(context); + { + JSStringRef promiseProperty = JSStringCreateWithUTF8CString("Promise"); + ASSERT(!JSObjectHasProperty(context, globalObject, promiseProperty)); + JSStringRelease(promiseProperty); } - - if (exception) { - printf("FAIL: Unexpected TerminatedExecutionException thrown.\n"); - failed = true; + { + JSStringRef script = JSStringCreateWithUTF8CString("typeof Promise"); + JSStringRef undefined = JSStringCreateWithUTF8CString("undefined"); + JSValueRef value = JSEvaluateScript(context, script, NULL, NULL, 1, NULL); + ASSERT(JSValueIsString(context, value)); + JSStringRef valueAsString = JSValueToStringCopy(context, value, NULL); + ASSERT(JSStringIsEqual(valueAsString, undefined)); + JSStringRelease(valueAsString); + JSStringRelease(undefined); + JSStringRelease(script); } + printf("PASS: Promise is not exposed under JSContext API.\n"); } - /* Test script timeout extension: */ - JSContextGroupSetExecutionTimeLimit(contextGroup, 0.100f, extendTerminateCallback, 0); - { - const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .500) break; } "; - JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript); - double startTime; - double endTime; - double deltaTime; - exception = NULL; - startTime = currentCPUTime(); - v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception); - endTime = currentCPUTime(); - deltaTime = endTime - startTime; - - if ((deltaTime >= .300f) && (deltaTime < .500f) && (extendTerminateCallbackCalled == 2) && exception) - printf("PASS: script timeout was extended as expected.\n"); - else { - if (deltaTime < .200f) - printf("FAIL: script timeout was not extended as expected.\n"); - else if (deltaTime >= .500f) - printf("FAIL: script did not timeout.\n"); - - if (extendTerminateCallbackCalled < 1) - printf("FAIL: script timeout callback was not called.\n"); - if (extendTerminateCallbackCalled < 2) - printf("FAIL: script timeout callback was not called after timeout extension.\n"); - - if (!exception) - printf("FAIL: TerminatedExecutionException was not thrown during timeout extension test.\n"); - - failed = true; - } - } -#endif /* PLATFORM(MAC) || PLATFORM(IOS) */ +#if OS(DARWIN) + failed = testExecutionTimeLimit() || failed; +#endif /* OS(DARWIN) */ + failed = testGlobalContextWithFinalizer() || failed; // Clear out local variables pointing at JSObjectRefs to allow their values to be collected function = NULL; @@ -1959,6 +1917,15 @@ int main(int argc, char* argv[]) printf("FAIL: A cycle in a prototype chain can be created.\n"); failed = true; } + if (valueToObjectExceptionTest()) + printf("PASS: throwException did not crash when handling an error with appendMessageToError set and no codeBlock available.\n"); + + if (globalContextNameTest()) + printf("PASS: global context name behaves as expected.\n"); + + customGlobalObjectClassTest(); + globalObjectSetPrototypeTest(); + globalObjectPrivatePropertyTest(); if (failed) { printf("FAIL: Some tests failed.\n"); @@ -1999,3 +1966,10 @@ static char* createStringWithContentsOfFile(const char* fileName) return buffer; } + +#if OS(WINDOWS) +extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(int argc, const char* argv[]) +{ + return main(argc, const_cast(argv)); +} +#endif