]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - API/tests/testapi.c
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / API / tests / testapi.c
index 91978bbfd50f32aa635e34ebf1fe947a8c263de8..fc4914b7ab69527095ef0e658a4b342f590495d1 100644 (file)
@@ -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
  *    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 <wtf/Platform.h>
+
 #include "JavaScriptCore.h"
 #include "JSBasePrivate.h"
 #include "JSContextRefPrivate.h"
 #include "JSObjectRefPrivate.h"
+#include "JSScriptRefPrivate.h"
+#include "JSStringRefPrivate.h"
 #include <math.h>
 #define ASSERT_DISABLED 0
 #include <wtf/Assertions.h>
-#include <wtf/UnusedParam.h>
 
 #if OS(WINDOWS)
 #include <windows.h>
 #endif
 
-#if COMPILER(MSVC)
-
-#include <wtf/MathExtras.h>
+#include "CompareAndSwapTest.h"
+#include "CustomGlobalObjectClassTest.h"
+#include "GlobalContextWithFinalizerTest.h"
 
-static double nan(const char*)
-{
-    return std::numeric_limits<double>::quiet_NaN();
-}
+#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;
-static int failed;
+int failed;
 static void assertEqualsAsBoolean(JSValueRef value, bool expectedValue)
 {
     if (JSValueToBoolean(context, value) != expectedValue) {
@@ -77,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;
         }
     }
@@ -116,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;
     }
 
@@ -481,6 +494,11 @@ static bool PropertyCatchalls_setProperty(JSContextRef context, JSObjectRef obje
         return true;
     }
 
+    if (JSStringIsEqualToUTF8CString(propertyName, "make_throw") || JSStringIsEqualToUTF8CString(propertyName, "0")) {
+        *exception = JSValueMakeNumber(context, 5);
+        return true;
+    }
+
     return false;
 }
 
@@ -561,7 +579,6 @@ static JSValueRef EvilExceptionObject_convertToType(JSContextRef context, JSObje
         break;
     default:
         return JSValueMakeNull(context);
-        break;
     }
     
     JSValueRef func = JSObjectGetProperty(context, object, funcName, exception);
@@ -883,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");
@@ -945,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 }
 };
@@ -969,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)
@@ -1022,6 +1038,75 @@ static bool checkForCycleInPrototypeChain()
     return result;
 }
 
+static JSValueRef valueToObjectExceptionCallAsFunction(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);
+    JSValueRef jsUndefined = JSValueMakeUndefined(JSContextGetGlobalContext(ctx));
+    JSValueToObject(JSContextGetGlobalContext(ctx), jsUndefined, exception);
+    
+    return JSValueMakeUndefined(ctx);
+}
+static bool valueToObjectExceptionTest()
+{
+    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);
+
+    JSStringRef test = JSStringCreateWithUTF8CString("valueToObject();");
+    JSEvaluateScript(testContext, test, NULL, NULL, 1, NULL);
+    
+    JSStringRelease(test);
+    JSClassRelease(globalObjectClass);
+    JSGlobalContextRelease(testContext);
+    
+    return true;
+}
+
+static bool globalContextNameTest()
+{
+    bool result = true;
+    JSGlobalContextRef context = JSGlobalContextCreate(0);
+
+    JSStringRef str = JSGlobalContextCopyName(context);
+    result &= assertTrue(!str, "Default context name is NULL");
+
+    JSStringRef name1 = JSStringCreateWithUTF8CString("name1");
+    JSStringRef name2 = JSStringCreateWithUTF8CString("name2");
+
+    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;
+}
+
 static void checkConstnessInJSObjectNames()
 {
     JSStaticFunction fun;
@@ -1030,15 +1115,31 @@ static void checkConstnessInJSObjectNames()
     val.name = "something";
 }
 
+
 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 <http://webkit.org/b/55222>.
     ::SetErrorMode(0);
 #endif
 
+    testCompareAndSwap();
+
+#if JSC_OBJC_API_ENABLED
+    testObjectiveCAPI();
+#endif
+
     const char *scriptPath = "testapi.js";
     if (argc > 1) {
         scriptPath = argv[1];
@@ -1061,6 +1162,8 @@ int main(int argc, char* argv[])
     JSClassRef globalObjectClass = JSClassCreate(&globalObjectClassDefinition);
     context = JSGlobalContextCreateInGroup(NULL, globalObjectClass);
 
+    JSContextGroupRef contextGroup = JSContextGetGroup(context);
+    
     JSGlobalContextRetain(context);
     JSGlobalContextRelease(context);
     ASSERT(JSContextGetGlobalContext(context) == context);
@@ -1082,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);
@@ -1117,6 +1227,12 @@ int main(int argc, char* argv[])
     free(buffer);
     JSValueRef jsCFEmptyStringWithCharacters = JSValueMakeString(context, jsCFEmptyIStringWithCharacters);
 
+    JSChar constantString[] = { 'H', 'e', 'l', 'l', 'o', };
+    JSStringRef constantStringRef = JSStringCreateWithCharactersNoCopy(constantString, sizeof(constantString) / sizeof(constantString[0]));
+    ASSERT(JSStringGetCharactersPtr(constantStringRef) == constantString);
+    JSStringRelease(constantStringRef);
+
+    ASSERT(JSValueGetType(context, NULL) == kJSTypeNull);
     ASSERT(JSValueGetType(context, jsUndefined) == kJSTypeUndefined);
     ASSERT(JSValueGetType(context, jsNull) == kJSTypeNull);
     ASSERT(JSValueGetType(context, jsTrue) == kJSTypeBoolean);
@@ -1131,6 +1247,51 @@ int main(int argc, char* argv[])
     ASSERT(JSValueGetType(context, jsCFEmptyString) == kJSTypeString);
     ASSERT(JSValueGetType(context, jsCFEmptyStringWithCharacters) == kJSTypeString);
 
+    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));
+    ASSERT(JSValueIsNull(context, NULL));
+    ASSERT(!JSObjectCallAsFunction(context, NULL, NULL, 0, NULL, NULL));
+    ASSERT(!JSObjectCallAsConstructor(context, NULL, 0, NULL, NULL));
+    ASSERT(!JSObjectIsConstructor(context, NULL));
+    ASSERT(!JSObjectIsFunction(context, NULL));
+
+    JSStringRef nullString = JSStringCreateWithUTF8CString(0);
+    const JSChar* characters = JSStringGetCharactersPtr(nullString);
+    if (characters) {
+        printf("FAIL: Didn't return null when accessing character pointer of a null String.\n");
+        failed = 1;
+    } 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");
+        failed = 1;
+    } else
+        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);
@@ -1208,6 +1369,15 @@ int main(int argc, char* argv[])
     } else
         printf("PASS: Retrieved private property.\n");
 
+    JSStringRef nullJSON = JSStringCreateWithUTF8CString(0);
+    JSValueRef nullJSONObject = JSValueMakeFromJSONString(context, nullJSON);
+    if (nullJSONObject) {
+        printf("FAIL: Did not parse null String as JSON correctly\n");
+        failed = 1;
+    } else
+        printf("PASS: Parsed null String as JSON correctly.\n");
+    JSStringRelease(nullJSON);
+
     JSStringRef validJSON = JSStringCreateWithUTF8CString("{\"aProperty\":true}");
     JSValueRef jsonObject = JSValueMakeFromJSONString(context, validJSON);
     JSStringRelease(validJSON);
@@ -1241,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) {
@@ -1374,9 +1546,12 @@ int main(int argc, char* argv[])
     JSValueUnprotect(context, jsNumberValue);
 
     JSStringRef goodSyntax = JSStringCreateWithUTF8CString("x = 1;");
-    JSStringRef badSyntax = JSStringCreateWithUTF8CString("x := 1;");
+    const char* badSyntaxConstant = "x := 1;";
+    JSStringRef badSyntax = JSStringCreateWithUTF8CString(badSyntaxConstant);
     ASSERT(JSCheckScriptSyntax(context, goodSyntax, NULL, 0, NULL));
     ASSERT(!JSCheckScriptSyntax(context, badSyntax, NULL, 0, NULL));
+    ASSERT(!JSScriptCreateFromString(contextGroup, 0, 0, badSyntax, 0, 0));
+    ASSERT(!JSScriptCreateReferencingImmortalASCIIText(contextGroup, 0, 0, badSyntaxConstant, strlen(badSyntaxConstant), 0, 0));
 
     JSValueRef result;
     JSValueRef v;
@@ -1422,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);
 
@@ -1456,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");
@@ -1565,13 +1760,21 @@ int main(int argc, char* argv[])
     v = JSObjectCallAsFunction(context, function, o, 0, NULL, NULL);
     ASSERT(JSValueIsEqual(context, v, o, NULL));
 
-    JSStringRef script = JSStringCreateWithUTF8CString("this;");
+    const char* thisScript = "this;";
+    JSStringRef script = JSStringCreateWithUTF8CString(thisScript);
     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);
 
+    JSScriptRef scriptObject = JSScriptCreateReferencingImmortalASCIIText(contextGroup, 0, 0, thisScript, strlen(thisScript), 0, 0);
+    v = JSScriptEvaluate(context, scriptObject, NULL, NULL);
+    ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
+    v = JSScriptEvaluate(context, scriptObject, o, NULL);
+    ASSERT(JSValueIsEqual(context, v, o, NULL));
+    JSScriptRelease(scriptObject);
+
     script = JSStringCreateWithUTF8CString("eval(this);");
     v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
     ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
@@ -1579,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. <https://bugs.webkit.org/show_bug.cgi?id=25785>
     nullDefinition = kJSClassDefinitionEmpty;
@@ -1591,8 +1816,24 @@ int main(int argc, char* argv[])
         printf("FAIL: Test script could not be loaded.\n");
         failed = 1;
     } else {
-        script = JSStringCreateWithUTF8CString(scriptUTF8);
-        result = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
+        JSStringRef url = JSStringCreateWithUTF8CString(scriptPath);
+        JSStringRef script = JSStringCreateWithUTF8CString(scriptUTF8);
+        JSStringRef errorMessage = 0;
+        int errorLine = 0;
+        JSScriptRef scriptObject = JSScriptCreateFromString(contextGroup, url, 1, script, &errorMessage, &errorLine);
+        ASSERT((!scriptObject) != (!errorMessage));
+        if (!scriptObject) {
+            printf("FAIL: Test script did not parse\n\t%s:%d\n\t", scriptPath, errorLine);
+            CFStringRef errorCF = JSStringCopyCFString(kCFAllocatorDefault, errorMessage);
+            CFShow(errorCF);
+            CFRelease(errorCF);
+            JSStringRelease(errorMessage);
+            failed = 1;
+        }
+
+        JSStringRelease(script);
+        exception = NULL;
+        result = scriptObject ? JSScriptEvaluate(context, scriptObject, 0, &exception) : 0;
         if (result && JSValueIsUndefined(context, result))
             printf("PASS: Test script executed successfully.\n");
         else {
@@ -1604,10 +1845,37 @@ int main(int argc, char* argv[])
             JSStringRelease(exceptionIString);
             failed = 1;
         }
-        JSStringRelease(script);
+        JSScriptRelease(scriptObject);
         free(scriptUTF8);
     }
 
+    // Check Promise is not exposed.
+    {
+        JSObjectRef globalObject = JSContextGetGlobalObject(context);
+        {
+            JSStringRef promiseProperty = JSStringCreateWithUTF8CString("Promise");
+            ASSERT(!JSObjectHasProperty(context, globalObject, promiseProperty));
+            JSStringRelease(promiseProperty);
+        }
+        {
+            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");
+    }
+
+#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;
     v = NULL;
@@ -1649,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");
@@ -1670,6 +1947,7 @@ static char* createStringWithContentsOfFile(const char* fileName)
     FILE* f = fopen(fileName, "r");
     if (!f) {
         fprintf(stderr, "Could not open file: %s\n", fileName);
+        free(buffer);
         return 0;
     }
     
@@ -1688,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<char**>(argv));
+}
+#endif